如何正确处理信号,让 gperftools CPU profiler 仍然有效?
Posted
技术标签:
【中文标题】如何正确处理信号,让 gperftools CPU profiler 仍然有效?【英文标题】:How to properly handle signals, so that gperftools CPU profiler still works? 【发布时间】:2013-10-25 05:52:45 【问题描述】:我想分析我的守护程序,它会暂停主线程:
sigset_t signal_mask;
sigemptyset(&signal_mask);
sigaddset(&signal_mask, SIGTERM);
sigaddset(&signal_mask, SIGINT);
int sig;
sigwait(&signal_mask, &sig);
所有其他线程只是阻塞所有信号。
据我所知,分析器使用SIGPROF
信号进行操作。如果我开始使用这样的代码进行分析,则输出的 .prof 文件为空:
env CPUPROFILE=daemon.prof ./daemon
我应该如何正确处理主线程和其他线程中的信号以启用分析?或者可能是其他地方的问题?
【问题讨论】:
我正在“提高”你的问题,因为它提出了一个重要的问题 w.r.t.信号处理。 【参考方案1】:所有其他线程只是阻塞所有信号。
您只需要在所有线程(或您要分析的线程)中取消阻止SIGPROF
。我们只是在多线程守护进程中解决完全相同的问题。
【讨论】:
【参考方案2】:我需要查看更多您的代码,但是您“所有其他线程只是阻塞所有信号”的声明引发了......信号。
您必须记住,大多数系统调用是在线程概念出现之前创建的。信号处理就是其中之一。因此,当您在任何线程上阻塞信号时,它很可能会被所有线程阻塞。
事实上,查看 signal(2) 手册页:
The effects of signal() in a multithreaded process are unspecified.
是的,这很可悲,但这是您必须为使用低开销的统计抽样分析器付出的代价。解决这个问题非常简单:只需从信号掩码集中删除 SIGPROF(或 SIGALRM,如果您使用的是 REAL 模式)就可以了。
一般来说,除非你绝对必须这样做,否则你不应该在主线程以外的任何地方进行进程级信号屏蔽......其中“main”不一定意味着 MAIN() 正在运行的线程在你认为是所有其他人的“老板”的线程中,原因你已经说得太清楚了。 :)
您也可以尝试使用pthread library's sigmask wrapper pthread_sigmask,,但我不清楚它在子线程从 sigmask 中删除条目(pthread 继承其父 pthread sigmask)等情况下的效果如何。
【讨论】:
至少在Linux中,有两种信号,进程范围的(发送到任何线程)和per-pthread(可以直接发送信号到特定线程)。仍然不知道,setitimer
(发送 SIGPROF/SIGALRM)(my own question)使用了哪种信号。更新:主题groups.google.com/forum/#!topic/linux.kernel/DF-VwEf2AqE 说setitimer
使用了每线程信号。以上是关于如何正确处理信号,让 gperftools CPU profiler 仍然有效?的主要内容,如果未能解决你的问题,请参考以下文章
我已经安装了 gperftools-2.0,但我无法获取 cpu 配置文件统计信息