在终止进程之前保存 gmon.out

Posted

技术标签:

【中文标题】在终止进程之前保存 gmon.out【英文标题】:Saving gmon.out before killing a process 【发布时间】:2012-04-18 08:21:10 【问题描述】:

我想使用 gprof 来分析一个守护进程。我的守护进程使用第 3 方库,它注册一些回调,然后调用 main 函数,该函数永远不会返回。我需要调用kill(SIGTERM 或 SIGKILL)来终止守护进程。不幸的是,gprof 的手册页显示如下:

分析的程序必须调用“exit”(2) 或正常返回 要保存在 gmon.out 文件中的分析信息。

有没有办法保存被 SIGTERM 或 SIGKILL 杀死的进程的分析信息?

【问题讨论】:

【参考方案1】:

首先,我要感谢@wallyk 给了我很好的初步指导。我解决了我的问题如下。显然,libc 的 gprof 退出处理程序称为 _mcleanup。因此,我为 SIGUSR1 注册了一个信号处理程序(第 3 方库未使用)并调用 _mcleanup_exit。完美运行!代码如下:

#include <dlfcn.h>
#include <stdio.h>
#include <unistd.h>

void sigUsr1Handler(int sig)

    fprintf(stderr, "Exiting on SIGUSR1\n");
    void (*_mcleanup)(void);
    _mcleanup = (void (*)(void))dlsym(RTLD_DEFAULT, "_mcleanup");
    if (_mcleanup == NULL)
         fprintf(stderr, "Unable to find gprof exit hook\n");
    else _mcleanup();
    _exit(0);


int main(int argc, char* argv[])

    signal(SIGUSR1, sigUsr1Handler);
    neverReturningLibraryFunction();

【讨论】:

您还需要在编译器和链接器中添加一些标志。对于 g++,您应该使用: -Wl,--no-as-needed -ldl -pg 。来源:***.com/questions/20369672/…【参考方案2】:

您可以为第三方库未捕获或忽略的信号添加信号处理程序。可能 SIGUSR1 已经足够好,但如果足够全面,则必须进行试验或阅读库的文档。

您的信号处理程序可以简单地调用exit()

【讨论】:

不错的答案,但它并不能真正解决我的问题。第 3 方库使用全线程并在执行期间持有互斥锁。 omn​​ithread 似乎使用 atexit 注册了一些东西,因为我得到了terminate called after throwing an instance of 'omni_thread_fatal'。进程核心转储,没有 gmon.out。不能直接调用gprof的atexit() hook吗?

以上是关于在终止进程之前保存 gmon.out的主要内容,如果未能解决你的问题,请参考以下文章

使用gcc -pg -g编译后不会写入gmon.out

WinPhone 应用程序事件对应用程序进程终止作出反应

多进程池不会在所有进程之前关闭并加入终止脚本

我们是不是应该在分叉进程终止之前分离共享内存

函数wait和waitpid

如何等待进程终止以在批处理文件中执行另一个进程