如何确定valgrind / callgrind杀死进程的原因

时间:2016-07-26 12:44:19

标签: c++ multithreading profiling valgrind callgrind

我为我正在使用的数据库基础架构编写了多线程压力测试,我正在尝试使用callgrind对其进行配置。该程序在valgrind之外完美执行,并提供预期的结果。

然而,当在valgrind --tool=callgrind下运行时,程序会执行很短的时间,然后停止,valgrind报告Killed,因为它的最后一次输出到stdout。

我有办法确定为什么valgrind杀了我的任务吗?

遵循博士的建议:它确实被valgrind --tool=none杀死了,但是,我不完全确定如何分析我给出的消息,似乎有我的帖子中有很多sigvgkill个信号。第一个例子是:

--13713:1:syswrap- run_a_thread_NORETURN(tid=104): pre-thread_wrapper
 --> [pre-success] Success(0x0:0x365c)--13713:1:syswrap- thread_wrapper(tid=104): entry
 SYSCALL[13713,104](311) sys_set_robust_list ( 0x4f213be0, 12 )[sync] --> Success(0x0:0x0)
SYSCALL[13713,104](240) sys_futex ( 0xbeaf348, 128, 2, 0x0, 0x0 ) --> [async] ...
--13713-- async signal handler: signal=13, tid=32, si_code=0
--13713-- interrupted_syscall: tid=32, ip=0x380b197c, restart=False, sres.isErr=True, sres.val=32
--13713--   completed, but uncommitted: committing
--13713:1:gdbsrv   VG core calling VG_(gdbserver_report_signal) vki_nr 13 SIGPIPE gdb_nr 13 SIGPIPE tid 32
--13713:1:gdbsrv   not connected => pass
--13713-- delivering signal 13 (SIGPIPE):0 to thread 32
--13713-- delivering 13 (code 0) to default handler; action: terminate
==13713==

2 个答案:

答案 0 :(得分:2)

据我所知,valgrind并没有用这么少的东西杀死一个程序 冗长为“被杀”。这样的事情看起来更像是来自另一个进程的杀戮。

尽管如此,您可以尝试几种方法来调查您的程序行为的原因 在valgrind下而不是本地地不同:

  1. 首先在valgrind --tool=none下运行它。这是更快的工具(什么都不做)。然后,您可以查看您的程序是否按预期运行。 如果没有,则运行额外的valgrind内部跟踪,例如

    --tool=none -v -v -v -d -d -d --trace-syscalls=yes --trace-signals=yes
    

    跟踪可能会给出一个线索,然后说明它为什么会中止/被杀死。

  2. --tool=memcheck--tool=helgrind下运行 (同样地,如果崩溃,你可以运行更多的跟踪)。

  3. 然后最后,--tool=callgrind +更多跟踪,如果上面没有 但澄清。

答案 1 :(得分:0)

这是一个古老的问题 - 但是发生的事情是你收到了SIGPIPE(断管 - 写入另一端没有监听的管道)信号。

Valgrind注意到它(“嘿,我看到了一个适用于你的程序的SIGPIPE”),并继续将它传递给你的程序(因为它毕竟是为它而设)。

由于您可能未指定收到SIGPIPE时应发生的情况,因此将执行默认操作,即终止您的程序。见Why does SIGPIPE exist?。请记住,Valgrind下的程序运行速度要慢得多,因此行为(“在Valgrind下工作而不起作用”,反之亦然)可能会因时间而有所不同。

如果您在常规使用期间期望SIGPIPE并且想要忽略它(以便它不会杀死您的程序),请通过调用

来执行此操作
#include <signal.h>
// ...
signal(SIGPIPE, SIG_IGN); // ignore broken pipe signal 

你可能想对你可能期望的其他信号做同样的事情,否则你的过程会致命(SIGHUP,......)。

总而言之,Valgrind没有杀死你的过程,而是给了你一个关于你的过程为什么会死的暗示。只有少数情况我看到Valgrind杀了我的进程(这当然是我自己的错) - 通常它没有。即使您读取/写入您不拥有的内存地址,Valgrind也不会终止您的进程。它肯定会抱怨,但是它会执行指令,而实际杀死你的过程的是SIGSEGV,它是在你试图读/写内存之后才发生的。

这是Valgrind杀死你的过程时的样子: Screenshot of what it looks like when Valgrind has to kill your process.

它很少发生,我实际上截了它。 ;)