程式語言 - Wayland - 如何使用Valgrind找出Memory Leak的地方



參考資訊:
https://jan.newmarch.name/Wayland/index.html
https://wayland.freedesktop.org/docs/html/apa.html
https://bugaevc.gitbooks.io/writing-wayland-clients/content/

main.c

#include <stdio.h>
#include <wayland-client.h>
   
void cb_handle(void *dat, struct wl_registry *reg, uint32_t id, const char *intf, uint32_t ver)
{
    printf("%s, intf:%s, ver:%u, id:%u\n", __func__, intf, ver, id);
}
   
void cb_remove(void *dat, struct wl_registry *reg, uint32_t id)
{
    printf("%s, %u\n", __func__, id);
}
   
int main(int argc, char **argv)
{
    struct wl_display *dis = wl_display_connect(NULL);
    struct wl_registry *reg = wl_display_get_registry(dis);
    struct wl_registry_listener cb = {
        .global = cb_handle,
        .global_remove = cb_remove
    };
   
    wl_registry_add_listener(reg, &cb, NULL);
    wl_display_dispatch(dis);
    wl_display_roundtrip(dis);
 
    wl_display_disconnect(dis);
    return 0;
}

編譯、執行

$ gcc main.c -o main -lwayland-client -ggdb
$ valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=log.txt ./main
$ cat log.txt
    ==2893== HEAP SUMMARY:
    ==2893==     in use at exit: 80 bytes in 1 blocks
    ==2893==   total heap usage: 27 allocs, 26 frees, 22,144 bytes allocated
    ==2893== 
    ==2893== Searching for pointers to 1 not-freed blocks
    ==2893== Checked 93,032 bytes
    ==2893== 
    ==2893== 80 bytes in 1 blocks are definitely lost in loss record 1 of 1
    ==2893==    at 0x486D71C: calloc (vg_replace_malloc.c:1328)
    ==2893==    by 0x4899B3F: ??? (in /usr/lib64/libwayland-client.so.0.3.0)
    ==2893==    by 0x489A1CB: wl_proxy_marshal_array_constructor_versioned (in /usr/lib64/libwayland-client.so.0.3.0)
    ==2893==    by 0x489A4B7: wl_proxy_marshal_constructor (in /usr/lib64/libwayland-client.so.0.3.0)
    ==2893==    by 0x4008E7: wl_display_get_registry (wayland-client-protocol.h:1052)
    ==2893==    by 0x4009C7: main (main.c:17)
    ==2893== 
    ==2893== LEAK SUMMARY:
    ==2893==    definitely lost: 80 bytes in 1 blocks
    ==2893==    indirectly lost: 0 bytes in 0 blocks
    ==2893==      possibly lost: 0 bytes in 0 blocks
    ==2893==    still reachable: 0 bytes in 0 blocks
    ==2893==         suppressed: 0 bytes in 0 blocks
    ==2893== 
    ==2893== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

P.S. 經由Valgrind的Log,可以發現wl_display_get_registry()配置的記憶體沒有被釋放掉,也就是沒有呼叫wl_registry_destroy()去釋放記憶體

main.c(修改後)

#include <stdio.h>
#include <wayland-client.h>
   
void cb_handle(void *dat, struct wl_registry *reg, uint32_t id, const char *intf, uint32_t ver)
{
    printf("%s, intf:%s, ver:%u, id:%u\n", __func__, intf, ver, id);
}
   
void cb_remove(void *dat, struct wl_registry *reg, uint32_t id)
{
    printf("%s, %u\n", __func__, id);
}
   
int main(int argc, char **argv)
{
    struct wl_display *dis = wl_display_connect(NULL);
    struct wl_registry *reg = wl_display_get_registry(dis);
    struct wl_registry_listener cb = {
        .global = cb_handle,
        .global_remove = cb_remove
    };
   
    wl_registry_add_listener(reg, &cb, NULL);
    wl_display_dispatch(dis);
    wl_display_roundtrip(dis);

    wl_registry_destroy(reg);
    wl_display_disconnect(dis);
    return 0;
}

編譯、執行

$ gcc main.c -o main -lwayland-client -ggdb
$ valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=log.txt ./main
$ cat log.txt
    ==3014== HEAP SUMMARY:
    ==3014==     in use at exit: 0 bytes in 0 blocks
    ==3014==   total heap usage: 27 allocs, 27 frees, 22,144 bytes allocated
    ==3014== 
    ==3014== All heap blocks were freed -- no leaks are possible
    ==3014== 
    ==3014== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)