直接泄漏和间接泄漏有啥区别?
Posted
技术标签:
【中文标题】直接泄漏和间接泄漏有啥区别?【英文标题】:What is the difference between a direct and indirect leak?直接泄漏和间接泄漏有什么区别? 【发布时间】:2018-03-16 08:28:06 【问题描述】:我从 LeakSanitizer 工具得到以下输出。根据该工具的理解,直接泄漏和间接泄漏有什么区别?
13: ==29107==ERROR: LeakSanitizer: detected memory leaks
13:
13: Direct leak of 288 byte(s) in 6 object(s) allocated from:
13: #0 0x7f2ce0089050 in __interceptor_malloc (/nix/store/zahs1kwq4742f6l6h7yy4mdj44zzc1kd-gcc-7-20170409-lib/lib/libasan.so+0xd9050)
13: #1 0x7f2cdfb974fe in qdr_core_subscribe ../src/router_core/route_tables.c:149
13: #2 0x7f2cdfb47ff0 in IoAdapter_init ../src/python_embedded.c:548
13: #3 0x7f2cde966ecd in type_call (/nix/store/1snk2wkpv97an87pk1842fgskl1vqhkr-python-2.7.14/lib/libpython2.7.so.1.0+0x9fecd)
13:
13: Indirect leak of 2368 byte(s) in 1 object(s) allocated from:
13: #0 0x7f2ce0089b88 in __interceptor_posix_memalign (/nix/store/zahs1kwq4742f6l6h7yy4mdj44zzc1kd-gcc-7-20170409-lib/lib/libasan.so+0xd9b88)
13: #1 0x7f2cdfbcc8ea in qd_alloc ../src/alloc_pool.c:182
13: #2 0x7f2cdfbb6c6b in qd_server_connection ../src/server.c:500
13: #3 0x7f2cdfbbe27d in on_accept ../src/server.c:531
13: #4 0x7f2cdfbbe27d in handle_listener ../src/server.c:701
13: #5 0x7f2cdfbbe27d in handle ../src/server.c:844
13: #6 0x7f2cdfbc2837 in thread_run ../src/server.c:921
13: #7 0x7f2cdf0ba233 in start_thread (/nix/store/zpg78y1mf0di6127q6r51kgx2q8cxsvv-glibc-2.25-49/lib/libpthread.so.0+0x7233)
[...]
【问题讨论】:
检查valgrind docu。 AddressSanitizer 类别如何与 Valgrind 的绝对丢失、间接丢失、可能丢失、仍然可达? 如果我对this here的理解正确,它只显示直接和间接泄漏,而不是可到达的块。 谢谢,它回答了我的问题。该文档页面似乎已过时,但在这方面它似乎仍然相关。 【参考方案1】:LSan wiki design document 声明:
另一个有用的功能是能够区分直接泄露 块(无法从任何地方访问)和间接泄露的块(可访问 来自其他泄露的区块)。
换句话说,间接泄漏是直接泄漏的结果。修复直接泄漏应该使间接泄漏本身成为固定泄漏或直接泄漏(分别取决于它们的内存管理是否正确实现)。
【讨论】:
这个答案很有帮助,但并不完全正确。见第二个答案。【参考方案2】:accepted answer 不太正确。特别是
换句话说,间接泄漏是直接泄漏的结果。
是错误的,因为它可能有 only 间接泄漏。当自引用结构被构建和泄漏时,可能会出现这种情况。
例子:
#include <malloc.h>
struct Foo
struct Foo *other;
;
void fn(int depth)
if (depth > 0)
// recursion is only necessary to avoid LSan finding "stray" pointers
// and not reporting any leaks at all.
fn(depth - 1);
else
struct Foo *f1 = malloc(sizeof(*f1));
struct Foo *f2 = malloc(sizeof(*f2));
f1->other = f2;
f2->other = f1;
int main()
fn(10);
return 0;
clang -g -fsanitize=address t.c && ./a.out
=================================================================
==845196==ERROR: LeakSanitizer: detected memory leaks
Indirect leak of 8 byte(s) in 1 object(s) allocated from:
#0 0x49832d in malloc (/tmp/a.out+0x49832d)
#1 0x4c7f8e in fn /tmp/t.c:15:22
#2 0x4c7f71 in fn /tmp/t.c:12:5
#3 0x4c7f71 in fn /tmp/t.c:12:5
#4 0x4c7f71 in fn /tmp/t.c:12:5
#5 0x4c7f71 in fn /tmp/t.c:12:5
#6 0x4c7f71 in fn /tmp/t.c:12:5
#7 0x4c7f71 in fn /tmp/t.c:12:5
#8 0x4c7f71 in fn /tmp/t.c:12:5
#9 0x4c7f71 in fn /tmp/t.c:12:5
#10 0x4c7f71 in fn /tmp/t.c:12:5
#11 0x4c7f71 in fn /tmp/t.c:12:5
#12 0x4c8028 in main /tmp/t.c:23:3
#13 0x7f147d3a7d09 in __libc_start_main csu/../csu/libc-start.c:308:16
Indirect leak of 8 byte(s) in 1 object(s) allocated from:
#0 0x49832d in malloc (/tmp/a.out+0x49832d)
#1 0x4c7f80 in fn /tmp/t.c:14:22
#2 0x4c7f71 in fn /tmp/t.c:12:5
#3 0x4c7f71 in fn /tmp/t.c:12:5
#4 0x4c7f71 in fn /tmp/t.c:12:5
#5 0x4c7f71 in fn /tmp/t.c:12:5
#6 0x4c7f71 in fn /tmp/t.c:12:5
#7 0x4c7f71 in fn /tmp/t.c:12:5
#8 0x4c7f71 in fn /tmp/t.c:12:5
#9 0x4c7f71 in fn /tmp/t.c:12:5
#10 0x4c7f71 in fn /tmp/t.c:12:5
#11 0x4c7f71 in fn /tmp/t.c:12:5
#12 0x4c8028 in main /tmp/t.c:23:3
#13 0x7f147d3a7d09 in __libc_start_main csu/../csu/libc-start.c:308:16
SUMMARY: AddressSanitizer: 16 byte(s) leaked in 2 allocation(s).
注意:没有直接泄漏,只有间接泄漏。
【讨论】:
以上是关于直接泄漏和间接泄漏有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章