C 谁叫atexit()?

C 谁叫atexit()?,c,debugging,exit,C,Debugging,Exit,我有一个C程序在Linux上意外退出,我很难找出原因(没有内核转储,请参阅)。我在程序的开头放了一个atexit(),并且在崩溃发生时确实调用了回调函数 我怎么知道什么叫做atexit回调函数?通过阅读手册页,atexit在出口(d'ho!)或从主菜单返回时被调用。我可以排除后者,因为在main的末尾有一堆printf,我没有看到它们。我可以排除前者,因为我的程序中没有任何exit() 这只剩下一个解决方案:从库函数调用exit。这是唯一的可能性吗?我怎么知道从哪里来的?是否可以从atexit回

我有一个C程序在Linux上意外退出,我很难找出原因(没有内核转储,请参阅)。我在程序的开头放了一个atexit(),并且在崩溃发生时确实调用了回调函数

我怎么知道什么叫做atexit回调函数?通过阅读手册页,atexit在出口(d'ho!)或从主菜单返回时被调用。我可以排除后者,因为在main的末尾有一堆printf,我没有看到它们。我可以排除前者,因为我的程序中没有任何exit()

这只剩下一个解决方案:从库函数调用exit。这是唯一的可能性吗?我怎么知道从哪里来的?是否可以从atexit回调内部打印堆栈跟踪或强制核心转储?

标准仅说明“在正常程序终止时”,因此在Linux上,这可能不仅仅是退出
或从
main
返回
。您还忘记了
pthread\u exit
,这也可能会终止
main
的线程,从而终止整个程序

在任何情况下,都无法立即从何处看到终止。
atexit
处理程序通常由初始化函数调用。根据定义,所有其他的应用程序代码,但是
atexit
处理程序在那一点上都消失了

您可以尝试通过调试器跟踪执行,而不锁定终止发生的位置。

在atexit处理程序中调用例如abort(),并在gdb中检查coredump。如果运行atexit处理程序,gdb backtrace命令将显示它的退出位置。下面是一个演示:

#include <stdlib.h>


void exit_handler(void)
{
    abort();
}

void startup()
{
#ifdef DO_EXIT
    exit(99);
#endif
}


int main(int argc, char *argv[])
{
    atexit(exit_handler);

    startup();

    return 0;
}
正如预期的那样,它显示startup()调用exit


当然,您也可以通过交互方式对此进行调试,在gdb中启动程序,并在atexit处理程序中设置断点。

您的目标平台是哪个?Windows、Linux和其他?我们可能会找到对您有帮助的特定API函数。“我有一个C程序在Linux上意外退出”我猜他是针对Linux的?在您当前的
atexit
函数中添加一些非常糟糕的内容。除以零?叠加/下溢?内存分配失败?(不幸的是,我只是偶然地得到了这些错误,从来不是故意的,所以我不能推荐任何特别的方法。)关于强制核心转储问题,有一个关于如何做到这一点的问题。如果您的程序意外退出,它可能根本不会调用exit()。您可以使用
ltrace-S
监视程序的执行,直到它退出,然后使用调试器在它退出之前的某个点设置断点,并进行更详细的检查。谢谢。我不知道中止功能。
$ gcc -DDO_EXIT -g atexit.c
$ ulimit -c unlimited
$ ./a.out
Aborted (core dumped)
$ gdb ./a.out core.28162
GNU gdb (GDB) Fedora 7.7.1-19.fc20
..
Core was generated by `./a.out'.
Program terminated with signal SIGABRT, Aborted.
#0  0xb77d7424 in __kernel_vsyscall ()
Missing separate debuginfos, use: debuginfo-install glibc-2.18-16.fc20.i686
(gdb) bt
#0  0xb77d7424 in __kernel_vsyscall ()
#1  0x42e1a8e7 in raise () from /lib/libc.so.6
#2  0x42e1c123 in abort () from /lib/libc.so.6
#3  0x0804851b in exit_handler () at atexit.c:6
#4  0x42e1dd61 in __run_exit_handlers () from /lib/libc.so.6
#5  0x42e1ddbd in exit () from /lib/libc.so.6
#6  0x0804852d in startup () at atexit.c:12
#7  0x08048547 in main (argc=1, argv=0xbfc39fb4) at atexit.c:21