代码之家  ›  专栏  ›  技术社区  ›  user7610

直接泄漏和间接泄漏之间有什么区别?

  •  26
  • user7610  · 技术社区  · 7 年前

    我从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)
    [...]
    
    2 回复  |  直到 7 年前
        1
  •  25
  •   Kevin Chen    5 年前

    LSan wiki design document 国家:

    另一个有用的功能是能够区分直接泄漏的 来自其他泄漏区块)。

    换句话说,间接泄漏是直接泄漏的结果。修复直接泄漏应使间接泄漏变为固定泄漏或直接泄漏(分别取决于其内存管理是否正确实施)。

        2
  •  6
  •   Employed Russian    3 年前

    这个 accepted answer 不太正确。特别地

    只有 间接泄漏。当构建并泄漏自引用结构时,可能会出现这种情况。

    例子:

    #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).
    

    注:否 仅泄漏 一个。