akheron / jansson

C library for encoding, decoding and manipulating JSON data
http://www.digip.org/jansson/
Other
3.06k stars 815 forks source link

Segmentation fault: malloc.c: No such file or directory. #451

Closed JesseGuoX closed 5 years ago

JesseGuoX commented 5 years ago

cause Segmentation fault when call funtion like json_array() or json_object ()

gdb message below:

Thread 3 "transceiver" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x759b4460 (LWP 10226)]
_int_malloc (av=av@entry=0x76c687c8 <main_arena>, bytes=bytes@entry=24) at malloc.c:3486
3486    malloc.c: No such file or directory.
(gdb) bt
#0  _int_malloc (av=av@entry=0x76c687c8 <main_arena>, bytes=bytes@entry=24) at malloc.c:3486
#1  0x76bcf3f8 in __GI___libc_malloc (bytes=24) at malloc.c:2888
#2  0x76e43960 in json_array () from /usr/lib/libjansson.so.4
#3  0x0001584a in report_factors (factors=factors@entry=0x57f20 <continuous_reporters+76024>, factor_num=1, current=current@entry=1545717344, interval=18) at transceiver.c:608
#4  0x00015b3e in transceiver_report (current_time=1545717344) at transceiver.c:405
#5  0x0001602e in transceiver_report_thread (param=<optimized out>) at transceiver.c:307
#6  0x76efc5ce in start_thread (arg=0x759b3fa0) at pthread_create.c:314
#7  0x76c106bc in ?? () at ../ports/sysdeps/unix/sysv/linux/arm/nptl/../clone.S:92 from /lib/libc.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

code:

int report_factors(factor_S * factors, int factor_num, time_t current, int interval)
{
    json_t * report_msg_j = NULL;
    json_t * value = NULL;
    char * report_msg = NULL;
    json_t * report_array_j  = NULL;
    json_error_t jerror;
    int i = 0;
    report_array_j = json_array();
    for(i = 0; i < factor_num; i++){

        if(factors[i].id ==  0){
            continue;
        }
        if((factors[i].dtime < (current - interval)) || (factors[i].dtime > current)){
            continue;
        }
        switch(factors[i].data_type){
            case type_bit   :
            case type_byte  :  value = json_integer(factors[i].value.u8); break;
            case type_u16   :  value = json_integer(factors[i].value.u16); break; 
            case type_16    :  value = json_integer(factors[i].value.i16); break; 
            case type_u32   :  value = json_integer(factors[i].value.u32); break; 
            case type_32    :  value = json_integer(factors[i].value.i32); break; 
            case type_float :  {
                            if(isnan(factors[i].value.f)){
                                continue;
                            }else if(isinf(factors[i].value.f)){
                                continue;
                            }else{
                                value = json_real(factors[i].value.f); 
                            } 
                        }break;
            case type_double:  {
                            if(isnan(factors[i].value.d)){
                                continue;
                            }else if(isinf(factors[i].value.d)){
                                continue;
                            }else{
                                value = json_real(factors[i].value.d); 
                            } 
                        }break;
            case type_string:  value = json_string(factors[i].value.s);break;
            default:    break;  
        }

        json_array_append_new(report_array_j, json_pack_ex(&jerror, 0, "{s:s, s:o, s:i}", 
                                                    "code", factors[i].code,
                                                    "value", value,
                                                    "dtime", factors[i].dtime));

    }

    if(json_array_size(report_array_j) > 0){
        report_msg_j = json_pack_ex(&jerror, 0, "{s:i, s:I, s:o}", 
                                                "rtime",  time(NULL),
                                                "QN", utility_generate_qn(),
                                                "factors",report_array_j);
        if(report_msg_j == NULL){
            log_e("json_pack_ex  error %s from %s in line:%d",  jerror.text, jerror.source, jerror.column);
        }
        report_msg = json_dumps(report_msg_j, JSON_COMPACT);
        if(strlen(report_msg) > 0){
            sync_publishMsg(&_client, _default_pubtopic, report_msg, 1);
            json_decref(report_msg_j);
            free(report_msg);
        }
    }

    json_decref(report_array_j);
    return 0;

}
coreyfarrell commented 5 years ago

This segmentation fault is occurring inside the libc malloc. I've only ever seen this happen after memory corruption. I'd suggest testing your program from valgrind to try finding the origin of this memory corruption.

JesseGuoX commented 5 years ago

I found there was a double json_decref in my program. First I json_decref a reference from json_pack_ex and then I json_decref a json_array which borrowed by json_pack_ex. Could this cause the segmentation fault ? If it will casuse segmentation fault could it cause deadlock in program? Because when I did not fix double json_decref there was a deadlock problem too. GDB info like below, even thread 4 exit(0) function locked in __libc_do_syscall.

Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/libthread_db.so.1".
__libc_do_syscall () at ../ports/sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:43
43  ../ports/sysdeps/unix/sysv/linux/arm/libc-do-syscall.S: No such file or directory.
(gdb) bt
#0  __libc_do_syscall () at ../ports/sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:43
#1  0x76f1468c in __lll_lock_wait (futex=futex@entry=0x23921a8 <mqttasync_mutex_store>, private=0) at ../ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.c:46
#2  0x76f105ba in __GI___pthread_mutex_lock (mutex=0x23921a8 <mqttasync_mutex_store>) at pthread_mutex_lock.c:79
#3  0x000284f8 in Thread_lock_mutex (mutex=0x23921a8 <mqttasync_mutex_store>) at /home/guojq/bench/paho.mqtt.c-1.3.0/src/Thread.c:120
#4  0x00017a9e in MQTTAsync_lock_mutex (amutex=0x23921a8 <mqttasync_mutex_store>) at /home/guojq/bench/paho.mqtt.c-1.3.0/src/MQTTAsync.c:445
#5  0x0001d0de in MQTTAsync_isConnected (handle=0x373bf74) at /home/guojq/bench/paho.mqtt.c-1.3.0/src/MQTTAsync.c:3122
#6  0x00014992 in sync_isConnected (handle=<optimized out>) at sync.c:168
#7  0x00016452 in main (argc=<optimized out>, argv=<optimized out>) at transceiver.c:836
(gdb) info thread
  Id   Target Id         Frame
* 1    Thread 0x76fc4000 (LWP 13803) "transceiver" __libc_do_syscall () at ../ports/sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:43
  2    Thread 0x761c6460 (LWP 13804) "transceiver" 0x76bfddc2 in nanosleep () at ../sysdeps/unix/syscall-template.S:81
  3    Thread 0x759c6460 (LWP 13805) "transceiver" __libc_do_syscall () at ../ports/sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:43
  4    Thread 0x751c6460 (LWP 13806) "transceiver" __libc_do_syscall () at ../ports/sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:43
  5    Thread 0x749a4460 (LWP 13807) "transceiver" __libc_do_syscall () at ../ports/sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:43
  6    Thread 0x741a4460 (LWP 13808) "transceiver" __libc_do_syscall () at ../ports/sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:43
(gdb) thread 2
[Switching to thread 2 (Thread 0x761c6460 (LWP 13804))]
#0  0x76bfddc2 in nanosleep () at ../sysdeps/unix/syscall-template.S:81
81  ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) bt
#0  0x76bfddc2 in nanosleep () at ../sysdeps/unix/syscall-template.S:81
#1  0x76c1e09a in usleep (useconds=useconds@entry=1000) at ../sysdeps/unix/sysv/linux/usleep.c:32
#2  0x00017404 in _port_send_thread (arg=<optimized out>) at ../port.c:155
#3  0x76f0e5ce in start_thread (arg=0x761c5fa0) at pthread_create.c:314
#4  0x76c226bc in ?? () at ../ports/sysdeps/unix/sysv/linux/arm/nptl/../clone.S:92 from /lib/libc.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) thread 3
[Switching to thread 3 (Thread 0x759c6460 (LWP 13805))]
#0  __libc_do_syscall () at ../ports/sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:43
43  ../ports/sysdeps/unix/sysv/linux/arm/libc-do-syscall.S: No such file or directory.
(gdb) bt
#0  __libc_do_syscall () at ../ports/sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:43
#1  0x76c2bbb0 in __lll_lock_wait_private (futex=futex@entry=0x76c7a7c8 <main_arena>) at ../ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.c:31
#2  0x76be148a in __GI___libc_malloc (bytes=23, bytes@entry=0) at malloc.c:2884
#3  0x76fa55be in open_path (name=name@entry=0x76c598cc "libgcc_s.so.1", namelen=namelen@entry=14, secure=secure@entry=0, sps=<optimized out>, realname=realname@entry=0x759c4c9c,
    fbp=fbp@entry=0x759c4ca4, loader=0x76fc6ab8, whatcode=whatcode@entry=64, found_other_class=found_other_class@entry=0x759c4c9b) at dl-load.c:2038
#4  0x76fa7636 in _dl_map_object (loader=loader@entry=0x76fc6ab8, name=name@entry=0x76c598cc "libgcc_s.so.1", type=type@entry=2, trace_mode=0, mode=mode@entry=-1879048191, nsid=0)
    at dl-load.c:2290
#5  0x76faf3ee in dl_open_worker (a=0x759c510b) at dl-open.c:224
#6  0x76fac482 in _dl_catch_error (objname=0x759c510c, objname@entry=0x759c5124, errstring=0x759c5110, errstring@entry=0x759c5128, mallocedp=0x759c510b,
    mallocedp@entry=0x759c5123, operate=0x76faf36d <dl_open_worker>, args=0x759c5114, args@entry=0x759c512c) at dl-error.c:187
#7  0x76faefa0 in _dl_open (file=0x76c598cc "libgcc_s.so.1", mode=-2147483647, caller_dlopen=0x76c2d669 <init+20>, nsid=<optimized out>, argc=2, argv=0x7ed31e44, env=0x7ed31e50)
    at dl-open.c:650
#8  0x76c47454 in do_dlopen (ptr=0x759c5378) at dl-libc.c:87
#9  0x76fac482 in _dl_catch_error (objname=0x759c5360, errstring=0x759c5364, mallocedp=0x759c535f, operate=0x76c47419 <do_dlopen>, args=0x759c5378) at dl-error.c:187
#10 0x76c474e6 in dlerror_run (operate=<optimized out>, args=args@entry=0x759c5378) at dl-libc.c:46
#11 0x76c47532 in __GI___libc_dlopen_mode (name=<optimized out>, mode=<optimized out>) at dl-libc.c:163
#12 0x76c2d668 in init () at ../ports/sysdeps/arm/backtrace.c:45
#13 0x76f134f0 in __GI___pthread_once (once_control=0x76c7c5fc <once>, init_routine=0x76c2d655 <init>) at ../ports/sysdeps/unix/sysv/linux/arm/nptl/pthread_once.c:76
#14 0x76c2d710 in __GI___backtrace (array=array@entry=0x759c53f0, size=size@entry=64) at ../ports/sysdeps/arm/backtrace.c:98
#15 0x76ba10a6 in backtrace_and_maps (do_abort=do_abort@entry=2, written=<optimized out>, fd=fd@entry=2) at ../sysdeps/unix/sysv/linux/libc_fatal.c:49
#16 0x76bd76b0 in __libc_message (do_abort=2, fmt=<optimized out>) at ../sysdeps/posix/libc_fatal.c:172
#17 0x76bde540 in malloc_printerr (action=3, str=0x76c5d0dc "malloc(): memory corruption", ptr=<optimized out>) at malloc.c:4991
#18 0x76bdf92e in _int_malloc (av=av@entry=0x76c7a7c8 <main_arena>, bytes=bytes@entry=40) at malloc.c:3444
#19 0x76be13f8 in __GI___libc_malloc (bytes=40) at malloc.c:2888
#20 0x76e55750 in json_object () from /usr/lib/libjansson.so.4
#21 0x76e53e14 in ?? () from /usr/lib/libjansson.so.4
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) thread 4
[Switching to thread 4 (Thread 0x751c6460 (LWP 13806))]
#0  __libc_do_syscall () at ../ports/sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:43
43  ../ports/sysdeps/unix/sysv/linux/arm/libc-do-syscall.S: No such file or directory.
(gdb) bt
#0  __libc_do_syscall () at ../ports/sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:43
#1  0x76f1468c in __lll_lock_wait (futex=futex@entry=0x76fc951c <_rtld_local+1220>, private=0) at ../ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.c:46
#2  0x76f105fa in __GI___pthread_mutex_lock (mutex=0x76fc951c <_rtld_local+1220>) at pthread_mutex_lock.c:114
#3  0x76fac8a6 in _dl_fini () at dl-fini.c:156
#4  0x76bb3934 in __run_exit_handlers (status=status@entry=0, listp=0x76c7a4c8 <__exit_funcs>, run_list_atexit=run_list_atexit@entry=true) at exit.c:82
#5  0x76bb396c in __GI_exit (status=status@entry=0) at exit.c:104
#6  0x00014ed4 in _walking_dead_thread (param=<optimized out>) at transceiver.c:791
#7  0x76f0e5ce in start_thread (arg=0x751c5fa0) at pthread_create.c:314
#8  0x76c226bc in ?? () at ../ports/sysdeps/unix/sysv/linux/arm/nptl/../clone.S:92 from /lib/libc.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) thread 5
[Switching to thread 5 (Thread 0x749a4460 (LWP 13807))]
#0  __libc_do_syscall () at ../ports/sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:43
43  ../ports/sysdeps/unix/sysv/linux/arm/libc-do-syscall.S: No such file or directory.
(gdb) bt
#0  __libc_do_syscall () at ../ports/sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:43
#1  0x76c2bbb0 in __lll_lock_wait_private (futex=futex@entry=0x76c7a7c8 <main_arena>) at ../ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.c:31
#2  0x76bdf1de in _int_free (av=0x76c7a7c8 <main_arena>, p=0x376c6a0, have_lock=0) at malloc.c:3940
#3  0x0002a6b0 in Internal_heap_unlink (file=0x32030 "/home/guojq/bench/paho.mqtt.c-1.3.0/src/MQTTProtocolClient.c", line=232, p=0x376c6f4)
    at /home/guojq/bench/paho.mqtt.c-1.3.0/src/Heap.c:247
#4  0x0002a728 in myfree (file=0x32030 "/home/guojq/bench/paho.mqtt.c-1.3.0/src/MQTTProtocolClient.c", line=232, p=0x376c6f4) at /home/guojq/bench/paho.mqtt.c-1.3.0/src/Heap.c:269
#5  0x00020856 in MQTTProtocol_storePublication (publish=0x738006fc, len=0x749a3cf0) at /home/guojq/bench/paho.mqtt.c-1.3.0/src/MQTTProtocolClient.c:232
#6  0x00020722 in MQTTProtocol_createMessage (publish=0x738006fc, mm=0x749a3de8, qos=1, retained=0) at /home/guojq/bench/paho.mqtt.c-1.3.0/src/MQTTProtocolClient.c:192
#7  0x00020652 in MQTTProtocol_startPublish (pubclient=0x373c314, publish=0x738006fc, qos=1, retained=0, mm=0x749a3de8)
    at /home/guojq/bench/paho.mqtt.c-1.3.0/src/MQTTProtocolClient.c:159
#8  0x00019b62 in MQTTAsync_processCommand () at /home/guojq/bench/paho.mqtt.c-1.3.0/src/MQTTAsync.c:1502
#9  0x0001a502 in MQTTAsync_sendThread (n=0x0) at /home/guojq/bench/paho.mqtt.c-1.3.0/src/MQTTAsync.c:1795
#10 0x76f0e5ce in start_thread (arg=0x749a3fa0) at pthread_create.c:314
#11 0x76c226bc in ?? () at ../ports/sysdeps/unix/sysv/linux/arm/nptl/../clone.S:92 from /lib/libc.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) thread 6
[Switching to thread 6 (Thread 0x741a4460 (LWP 13808))]
#0  __libc_do_syscall () at ../ports/sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:43
43  ../ports/sysdeps/unix/sysv/linux/arm/libc-do-syscall.S: No such file or directory.
(gdb) bt
#0  __libc_do_syscall () at ../ports/sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:43
#1  0x76f1468c in __lll_lock_wait (futex=futex@entry=0x23921a8 <mqttasync_mutex_store>, private=0) at ../ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.c:46
#2  0x76f105ba in __GI___pthread_mutex_lock (mutex=0x23921a8 <mqttasync_mutex_store>) at pthread_mutex_lock.c:79
#3  0x000284f8 in Thread_lock_mutex (mutex=0x23921a8 <mqttasync_mutex_store>) at /home/guojq/bench/paho.mqtt.c-1.3.0/src/Thread.c:120
#4  0x00017a9e in MQTTAsync_lock_mutex (amutex=0x23921a8 <mqttasync_mutex_store>) at /home/guojq/bench/paho.mqtt.c-1.3.0/src/MQTTAsync.c:445
#5  0x0001e218 in MQTTAsync_cycle (sock=0x741a3de4, timeout=1000, rc=0x741a3de8) at /home/guojq/bench/paho.mqtt.c-1.3.0/src/MQTTAsync.c:3681
#6  0x0001ae7c in MQTTAsync_receiveThread (n=0x373bf74) at /home/guojq/bench/paho.mqtt.c-1.3.0/src/MQTTAsync.c:2076
#7  0x76f0e5ce in start_thread (arg=0x741a3fa0) at pthread_create.c:314
#8  0x76c226bc in ?? () at ../ports/sysdeps/unix/sysv/linux/arm/nptl/../clone.S:92 from /lib/libc.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb)
coreyfarrell commented 5 years ago

Performing an extra json_decref can definitely cause a segmentation fault just the same as:

void *mem = malloc(10);
free(mem);
free(mem);

So you report_array_j = json_array(); creates an object with 1 reference. Passing that to json_pack with a lower-case o format will cause json_pack to steal the reference. So:

json_t *report_array_j = json_array();
json_t *obj = json_pack("{s: o}", "key", report_array_j);

json_decref(obj); // This will free report_array_j
if (0) {
  json_decref(report_array_j); // This would likely segfault because report_array_j was already free'd.
}

libjansson itself doesn't actually have locking, it doesn't even link to any threading library. It uses compiler atomic functionality for reference counting but that cannot cause a deadlock. So you will have to look into your own code / other libraries you are using for the source of any deadlock. I'm not even sure your backtrace shows a deadlock - it might just show that a segmentation fault happened when libc had internals locked.

JesseGuoX commented 5 years ago

@coreyfarrell Thanks a lot, I will check my code again and I will append if there is something new.

coreyfarrell commented 5 years ago

I'm going to close this for now as I haven't seen any evidence of a bug in the jansson library. Feel free to reopen if you find something.