使用三方库 Jansson
造成 memory leak
,使用 valgrind
分析如下:
$ gcc -O0 -g -ggdb main.c -ljansson
$ valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./a.out
==21533== 4,752 bytes in 1 blocks are definitely lost in loss record 4 of 4
==21533== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21533== by 0x4E3F3C4: ??? (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3C9F7: json_dumps (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x40155F: ipc_db_save (main.c:153)
==21533== by 0x401C29: main (main.c:287)
==21533==
==21533== LEAK SUMMARY:
==21533== definitely lost: 18,480 bytes in 4 blocks
==21533== indirectly lost: 0 bytes in 0 blocks
==21533== possibly lost: 0 bytes in 0 blocks
==21533== still reachable: 0 bytes in 0 blocks
==21533== suppressed: 0 bytes in 0 blocks
==21533==
==21533== For counts of detected and suppressed errors, rerun with: -v
==21533== ERROR SUMMARY: 8 errors from 8 contexts (suppressed: 0 from 0)
source code
int ipc_db_save(int index, AppIPCInfoClass *ipc_info)
{
json_t *root = NULL;
json_t *new_ipc = NULL;
json_error_t error;
if (NULL == ipc_info) {
return 1;
}
if(access("ipcamera.dat", 0))
{
_new_db("ipcamera.dat");
}
root = json_load_file("ipcamera.dat", 0, &error);
printf("[%s]source %s\n", __func__, error.source);
printf("[%s]text %s\n", __func__, error.text);
if (!json_is_array(root)) {
json_decref(root);
}
if ((new_ipc = json_object()) == NULL) {
json_decref(root);
}
printf("[%s]%d: obj type = %d\n", __func__, __LINE__, json_typeof(root));
char *result = json_dumps(root, JSON_PRESERVE_ORDER);
printf("[%s]%d: result %s\n", __func__, __LINE__, result);
//free(result);
_object_integer(new_ipc, CAMERA_TYPE_KEY, ipc_info->type);
_object_string(new_ipc, CAMERA_NAME_KEY, ipc_info->name);
_object_string(new_ipc, CAMERA_IP_KEY, ipc_info->ip);
_object_integer(new_ipc, CAMERA_PORT_KEY, ipc_info->port);
_object_string(new_ipc, CAMERA_USER_KEY, ipc_info->user);
_object_integer(new_ipc, CAMERA_CHANNEL_KEY, ipc_info->channel);
_object_string(new_ipc, CAMERA_PASSWD_KEY, ipc_info->passwd);
_object_string(new_ipc, CAMERA_STREAM_KEY, ipc_info->stream);
if (index == -1) { //add mode
json_array_append(root, new_ipc);
}
else { //edit mode
json_array_set(root, index, new_ipc);
}
result = json_dumps(root, JSON_PRESERVE_ORDER);
printf("[%s]%d: result %s\n", __func__, __LINE__, result);
free(result);
json_dump_file(root, "ipcamera.dat", 0);
json_decref(new_ipc);
json_decref(root);
return 0;
}
int ipc_db_get(int index, AppIPCInfoClass *ipc_info)
{
json_t *root = NULL;
json_t *info_obj = NULL;
json_t *obj_value = NULL;
json_error_t error;
const char *obj_key = NULL;
if (ipc_info == NULL) {
return 1;
}
root = json_load_file("ipcamera.dat", 0, &error);
if (!json_is_array(root)) {
json_decref(root);
return 1;
}
info_obj = json_array_get(root, index);
if (!json_is_object(info_obj)) {
json_decref(info_obj);
json_decref(root);
return 1;
}
json_object_foreach(info_obj, obj_key, obj_value) {
_parse_info(obj_key, obj_value, ipc_info);
}
json_decref(info_obj);
json_decref(root);
return 0;
}
valgrind memcheck
$ gcc -O0 -g -ggdb main.c -ljansson
$ valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./a.out
==21533== Memcheck, a memory error detector
==21533== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==21533== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==21533== Command: ./a.out
==21533==
==21533== Invalid read of size 8
==21533== at 0x4E42009: json_delete (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x400EFA: json_decref (jansson.h:106)
==21533== by 0x40186F: ipc_db_get (main.c:213)
==21533== by 0x401C44: main (main.c:293)
==21533== Address 0x54b09b8 is 8 bytes inside a block of size 72 free'd
==21533== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21533== by 0x400EFA: json_decref (jansson.h:106)
==21533== by 0x401860: ipc_db_get (main.c:212)
==21533== by 0x401C44: main (main.c:293)
==21533== Block was alloc'd at
==21533== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21533== by 0x4E417BA: json_object (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3E8E4: ??? (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3EBB2: ??? (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3EDAD: ??? (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3F165: json_loadf (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3F1E7: json_load_file (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x40170F: ipc_db_get (main.c:195)
==21533== by 0x401C44: main (main.c:293)
==21533==
==21533== Invalid write of size 8
==21533== at 0x4E4201A: json_delete (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x400EFA: json_decref (jansson.h:106)
==21533== by 0x40186F: ipc_db_get (main.c:213)
==21533== by 0x401C44: main (main.c:293)
==21533== Address 0x54b09b8 is 8 bytes inside a block of size 72 free'd
==21533== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21533== by 0x400EFA: json_decref (jansson.h:106)
==21533== by 0x401860: ipc_db_get (main.c:212)
==21533== by 0x401C44: main (main.c:293)
==21533== Block was alloc'd at
==21533== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21533== by 0x4E417BA: json_object (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3E8E4: ??? (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3EBB2: ??? (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3EDAD: ??? (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3F165: json_loadf (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3F1E7: json_load_file (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x40170F: ipc_db_get (main.c:195)
==21533== by 0x401C44: main (main.c:293)
==21533==
==21533== Invalid read of size 8
==21533== at 0x4E42009: json_delete (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x400EFA: json_decref (jansson.h:106)
==21533== by 0x40186F: ipc_db_get (main.c:213)
==21533== by 0x401C55: main (main.c:294)
==21533== Address 0x54c4918 is 8 bytes inside a block of size 72 free'd
==21533== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21533== by 0x400EFA: json_decref (jansson.h:106)
==21533== by 0x401860: ipc_db_get (main.c:212)
==21533== by 0x401C55: main (main.c:294)
==21533== Block was alloc'd at
==21533== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21533== by 0x4E417BA: json_object (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3E8E4: ??? (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3EBB2: ??? (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3EDAD: ??? (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3F165: json_loadf (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3F1E7: json_load_file (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x40170F: ipc_db_get (main.c:195)
==21533== by 0x401C55: main (main.c:294)
==21533==
==21533== Invalid write of size 8
==21533== at 0x4E4201A: json_delete (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x400EFA: json_decref (jansson.h:106)
==21533== by 0x40186F: ipc_db_get (main.c:213)
==21533== by 0x401C55: main (main.c:294)
==21533== Address 0x54c4918 is 8 bytes inside a block of size 72 free'd
==21533== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21533== by 0x400EFA: json_decref (jansson.h:106)
==21533== by 0x401860: ipc_db_get (main.c:212)
==21533== by 0x401C55: main (main.c:294)
==21533== Block was alloc'd at
==21533== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21533== by 0x4E417BA: json_object (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3E8E4: ??? (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3EBB2: ??? (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3EDAD: ??? (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3F165: json_loadf (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3F1E7: json_load_file (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x40170F: ipc_db_get (main.c:195)
==21533== by 0x401C55: main (main.c:294)
==21533==
==21533==
==21533== HEAP SUMMARY:
==21533== in use at exit: 18,480 bytes in 4 blocks
==21533== total heap usage: 5,525 allocs, 5,521 frees, 425,812 bytes allocated
==21533==
==21533== 4,409 bytes in 1 blocks are definitely lost in loss record 1 of 4
==21533== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21533== by 0x4E3F3C4: ??? (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3C9F7: json_dumps (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x40155F: ipc_db_save (main.c:153)
==21533== by 0x401A2C: main (main.c:251)
==21533==
==21533== 4,577 bytes in 1 blocks are definitely lost in loss record 2 of 4
==21533== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21533== by 0x4E3F3C4: ??? (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3C9F7: json_dumps (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x40155F: ipc_db_save (main.c:153)
==21533== by 0x401AD5: main (main.c:263)
==21533==
==21533== 4,742 bytes in 1 blocks are definitely lost in loss record 3 of 4
==21533== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21533== by 0x4E3F3C4: ??? (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3C9F7: json_dumps (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x40155F: ipc_db_save (main.c:153)
==21533== by 0x401B74: main (main.c:275)
==21533==
==21533== 4,752 bytes in 1 blocks are definitely lost in loss record 4 of 4
==21533== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21533== by 0x4E3F3C4: ??? (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3C9F7: json_dumps (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x40155F: ipc_db_save (main.c:153)
==21533== by 0x401C29: main (main.c:287)
==21533==
==21533== LEAK SUMMARY:
==21533== definitely lost: 18,480 bytes in 4 blocks
==21533== indirectly lost: 0 bytes in 0 blocks
==21533== possibly lost: 0 bytes in 0 blocks
==21533== still reachable: 0 bytes in 0 blocks
==21533== suppressed: 0 bytes in 0 blocks
==21533==
==21533== For counts of detected and suppressed errors, rerun with: -v
==21533== ERROR SUMMARY: 8 errors from 8 contexts (suppressed: 0 from 0)
Invalid read of size 8
==21533== Invalid read of size 8
==21533== at 0x4E42009: json_delete (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x400EFA: json_decref (jansson.h:106)
==21533== by 0x40186F: ipc_db_get (main.c:213)
==21533== by 0x401C44: main (main.c:293)
==21533== Address 0x54b09b8 is 8 bytes inside a block of size 72 free'd
==21533== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21533== by 0x400EFA: json_decref (jansson.h:106)
==21533== by 0x401860: ipc_db_get (main.c:212)
==21533== by 0x401C44: main (main.c:293)
==21533== Block was alloc'd at
==21533== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21533== by 0x4E417BA: json_object (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3E8E4: ??? (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3EBB2: ??? (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3EDAD: ??? (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3F165: json_loadf (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3F1E7: json_load_file (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x40170F: ipc_db_get (main.c:195)
==21533== by 0x401C44: main (main.c:293)
重复释放,将main.c:212
注释掉
memory leak
==21533== 4,577 bytes in 1 blocks are definitely lost in loss record 2 of 4
==21533== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21533== by 0x4E3F3C4: ??? (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x4E3C9F7: json_dumps (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==21533== by 0x40155F: ipc_db_save (main.c:153)
==21533== by 0x401AD5: main (main.c:263)
main.c:153
处申请内存没有释放,添加 free
解决此问题
正常结果
$ gcc -O0 -g -ggdb main.c -ljansson
$ valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./a.out
==21929== Memcheck, a memory error detector
==21929== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==21929== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==21929== Command: ./a.out
==21929==
==21929==
==21929== HEAP SUMMARY:
==21929== in use at exit: 0 bytes in 0 blocks
==21929== total heap usage: 5,919 allocs, 5,919 frees, 443,103 bytes allocated
==21929==
==21929== All heap blocks were freed -- no leaks are possible
==21929==
==21929== For counts of detected and suppressed errors, rerun with: -v
==21929== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)