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

发出SIGINT停止循环时如何获取地址消毒剂的输出

  •  1
  • Bungow  · 技术社区  · 7 年前

    当我编译这个简单的测试程序时,我从地址消毒剂那里得到了明显的泄漏报告,但是当我编译同一个程序时,却有一个无限的循环,并中断它发出 SIGINT 我没有任何输出。

    检查asm输出 malloc

    这是地址消毒剂的预期行为吗?我在其他发展中没有遇到这个问题。

    工作示例:

    #include <stdlib.h>
    int main(void)
    {
        char *a = malloc(1024);
        return 1;
    }
    

    #include <stdlib.h>
    int main(void)
    {
        char *a = malloc(1024);
        for(;;);
        return 1;
    }
    

    编译: gcc test.c -o test -fsanitize=address

    我在一个完整的程序中遇到了这个问题,但我把它简化为这个最小的例子。

    2 回复  |  直到 7 年前
        1
  •  3
  •   KamilCuk    7 年前

    我试了很多方法 exit() abort() 呼叫,这有效:

    #include <stdlib.h>
    #include <signal.h>
    #include <stdio.h>
    #include <setjmp.h>
    
    jmp_buf jmpbuf;
    void handler (int signum) {    
            printf("handler %d \n", signum);
            // we jump from here to main()
            // and then call return
            longjmp(jmpbuf, 1);
    }
    
    int main(int argc, char *argv[])
    {
        if (setjmp(jmpbuf)) { 
            // we are in signal context here
            return 2;
        }
        signal(SIGINT, handler);
        signal(SIGTERM, handler);
    
        char *a = malloc(1024);
        while (argc - 1);
        return 1;
    }
    

    结果:

    > gcc file.c -fsanitize=address && timeout 1 ./a.out arg
    handler 15 
    
    =================================================================
    ==12970==ERROR: LeakSanitizer: detected memory leaks
    
    Direct leak of 1024 byte(s) in 1 object(s) allocated from:
        #0 0x7f4798c9bd99 in __interceptor_malloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:86
        #1 0x5569e64e0acd in main (/tmp/a.out+0xacd)
        #2 0x7f479881206a in __libc_start_main (/usr/lib/libc.so.6+0x2306a)
    
    SUMMARY: AddressSanitizer: 1024 byte(s) leaked in 1 allocation(s).
    

        2
  •  2
  •   Neowizard    7 年前

    负责打印错误输出的代码称为析构函数(fini)过程。由于程序在不调用任何进程析构函数的情况下终止(由于SIGINT),因此不会得到任何错误输出。