jiejieTop / mqttclient

A high-performance, high-stability, cross-platform MQTT client, developed based on the socket API, can be used on embedded devices (FreeRTOS / LiteOS / RT-Thread / TencentOS tiny), Linux, Windows, Mac, with a very concise The API interface realizes the quality of service of QOS2 with very few resources, and seamlessly connects the mbedtls encryption library.
Apache License 2.0
694 stars 255 forks source link

在Linux应用程序上使用release有很大概率出现core dump #60

Open Yangyuanxin opened 2 years ago

Yangyuanxin commented 2 years ago

杰神,请看这是由内存检测工具打出来的log: 执行以下命令: valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./my_app 在做这件事情之前,我已经修复了内部线程退出时由linux pthread模块引发的内存泄漏问题,文件:linux\platform_thread.c的platform_thread_destroy函数:

void platform_thread_destroy(platform_thread_t* thread)
{
    if (NULL != thread)
    {
        pthread_detach(thread->thread);
        //内存释放
        platform_memory_free(thread);
        thread = NULL;
    }
}

mqtt_release.c文件:int mqtt_release(mqtt_client_t* c)函数:

    /* wait for the clean session to complete */
    while ((CLIENT_STATE_INVALID != mqtt_get_client_state(c))) {
        // platform_timer_usleep(1000);            // 1ms avoid compiler optimization.
        if (platform_timer_is_expired(&timer)) {
            MQTT_LOG_E("%s:%d %s()... mqtt release failed...", __FILE__, __LINE__, __FUNCTION__);
            //RETURN_ERROR(MQTT_FAILED_ERROR)
            //退出后才会清除没有释放的内存,销毁互斥锁
            break;
        }    
    }

然后,我的应用逻辑如下: 初始化->连接->主题订阅->进入循环->发布两次消息->退出循环->断开连接->执行mqtt_release。

正常情况下是这样的,运行不会产生错误,也没有任何内存泄漏,程序样例正常进行

mqttclient.c:946 mqtt_yield_thread()..., mqtt clean session....
mqttclient.c:1241 mqtt_release()... mqtt release failed...
MqttTest-308::MqttUnInit success!
LogDestroy Success : 0
==46068== 
==46068== HEAP SUMMARY:
==46068==     in use at exit: 0 bytes in 0 blocks
==46068==   total heap usage: 26 allocs, 26 frees, 42,573 bytes allocated
==46068== 
==46068== All heap blocks were freed -- no leaks are possible
==46068== 
==46068== For counts of detected and suppressed errors, rerun with: -v
==46068== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

当多次执行该程序后出现Core dump的日志如下:

mqttclient.c:946 mqtt_yield_thread()..., mqtt clean session....
==46058== Thread 2:
==46058== Invalid read of size 8
==46058==    at 0x1237EE: mqtt_yield_thread (mqttclient.c:947)
==46058==    by 0x4E456DA: start_thread (pthread_create.c:463)
==46058==    by 0x517E61E: clone (clone.S:95)
==46058==  Address 0x5457898 is 248 bytes inside a block of size 312 free'd
==46058==    at 0x4C32D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==46058==    by 0x11AB5F: AcMqttUnInit (AcMqtt.c:51)
==46058==    by 0x11B4DC: AcMqttTest (AcMqtt.c:302)
==46058==    by 0x1103A9: main (main.c:64)
==46058==  Block was alloc'd at
==46058==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==46058==    by 0x1226BA: mqtt_lease (mqttclient.c:1214)
==46058==    by 0x11AA09: AcMqttInit (AcMqtt.c:18)
==46058==    by 0x11B1AB: AcMqttTest (AcMqtt.c:259)
==46058==    by 0x1103A9: main (main.c:64)
==46058== 
==46058== Invalid read of size 4
==46058==    at 0x1248D0: network_disconnect (network.c:47)
==46058==    by 0x1237F9: mqtt_yield_thread (mqttclient.c:947)
==46058==    by 0x4E456DA: start_thread (pthread_create.c:463)
==46058==    by 0x517E61E: clone (clone.S:95)
==46058==  Address 0x14 is not stack'd, malloc'd or (recently) free'd
==46058== 
==46058== 
==46058== Process terminating with default action of signal 11 (SIGSEGV)
==46058==  Access not within mapped region at address 0x14
==46058==    at 0x1248D0: network_disconnect (network.c:47)
==46058==    by 0x1237F9: mqtt_yield_thread (mqttclient.c:947)
==46058==    by 0x4E456DA: start_thread (pthread_create.c:463)
==46058==    by 0x517E61E: clone (clone.S:95)
==46058==  If you believe this happened as a result of a stack
==46058==  overflow in your program's main thread (unlikely but
==46058==  possible), you can try to increase the size of the
==46058==  main thread stack using the --main-stacksize= flag.
==46058==  The main thread stack size used in this run was 8388608.
==46058== 
==46058== HEAP SUMMARY:
==46058==     in use at exit: 512 bytes in 4 blocks
==46058==   total heap usage: 26 allocs, 22 frees, 42,573 bytes allocated
==46058== 
==46058== Thread 1:
==46058== 40 bytes in 1 blocks are indirectly lost in loss record 1 of 4
==46058==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==46058==    by 0x12315B: mqtt_msg_handler_create (mqttclient.c:428)
==46058==    by 0x12315B: mqtt_subscribe (mqttclient.c:1326)
==46058==    by 0x11B28C: AcMqttSubscribe (AcMqtt.c:122)
==46058==    by 0x11B28C: AcMqttTest (AcMqtt.c:277)
==46058==    by 0x1103A9: main (main.c:64)
==46058== 
==46058== 96 bytes in 1 blocks are definitely lost in loss record 2 of 4
==46058==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==46058==    by 0x182873: platform_thread_init (platform_thread.c:23)
==46058==    by 0x122DAE: mqtt_connect_with_results (mqttclient.c:1033)
==46058==    by 0x122DAE: mqtt_connect (mqttclient.c:1271)
==46058==    by 0x11AC6C: AcMqttConnect (AcMqtt.c:63)
==46058==    by 0x11B1C3: AcMqttTest (AcMqtt.c:266)
==46058==    by 0x1103A9: main (main.c:64)
==46058== 
==46058== 144 (104 direct, 40 indirect) bytes in 1 blocks are definitely lost in loss record 3 of 4
==46058==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==46058==    by 0x120ED8: mqtt_ack_handler_create (mqttclient.c:317)
==46058==    by 0x120ED8: mqtt_ack_list_record (mqttclient.c:388)
==46058==    by 0x123BB3: mqtt_unsubscribe (mqttclient.c:1371)
==46058==    by 0x11AF63: AcMqttUnsubscribe (AcMqtt.c:140)
==46058==    by 0x11B99A: AcMqttTest (AcMqtt.c:291)
==46058==    by 0x1103A9: main (main.c:64)
==46058== 
==46058== 272 bytes in 1 blocks are possibly lost in loss record 4 of 4
==46058==    at 0x4C33B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==46058==    by 0x4013646: allocate_dtv (dl-tls.c:286)
==46058==    by 0x4013646: _dl_allocate_tls (dl-tls.c:530)
==46058==    by 0x4E46227: allocate_stack (allocatestack.c:627)
==46058==    by 0x4E46227: pthread_create@@GLIBC_2.2.5 (pthread_create.c:644)
==46058==    by 0x182886: platform_thread_init (platform_thread.c:25)
==46058==    by 0x122DAE: mqtt_connect_with_results (mqttclient.c:1033)
==46058==    by 0x122DAE: mqtt_connect (mqttclient.c:1271)
==46058==    by 0x11AC6C: AcMqttConnect (AcMqtt.c:63)
==46058==    by 0x11B1C3: AcMqttTest (AcMqtt.c:266)
==46058==    by 0x1103A9: main (main.c:64)
==46058== 
==46058== LEAK SUMMARY:
==46058==    definitely lost: 200 bytes in 2 blocks
==46058==    indirectly lost: 40 bytes in 1 blocks
==46058==      possibly lost: 272 bytes in 1 blocks
==46058==    still reachable: 0 bytes in 0 blocks
==46058==         suppressed: 0 bytes in 0 blocks
==46058== 
==46058== For counts of detected and suppressed errors, rerun with: -v
==46058== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)

杰神有空可以看看是由哪个模块引起的bug。