1

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

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

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


在遵循 phd 的建议后:它确实会被杀死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==
4

2 回答 2

3

据我所知,valgrind 不会杀死像“杀死”这样冗长的程序。这样的事情看起来更像是另一个进程的杀戮。

尽管如此,您可以尝试几件事来调查为什么您的程序在 valgrind 下而不是在本机下表现不同:

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

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

    跟踪可能会提供有关它为什么中止/被杀死的线索。

  2. --tool=memcheck 在and下运行它--tool=helgrind (同样,如果崩溃,您可以运行更多跟踪)。

  3. 最后,--tool=callgrind+ 更多跟踪,如果上述内容尚未澄清。

于 2016-07-26T22:08:49.477 回答
2

这是一个老问题 - 但正在发生的事情是您正在接收 SIGPIPE(损坏的管道 - 写入另一端没有任何监听的管道)信号。

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

由于您可能没有指定收到 SIGPIPE 时应该发生什么,因此执行默认操作,即终止您的程序。请参阅为什么存在 SIGPIPE?. 请记住,Valgrind 下的程序运行速度要慢得多,因此行为(“在 Valgrind 下工作,否则不工作”,反之亦然)可能会因时间而不同。

如果您在常规使用期间期望 SIGPIPE 并希望忽略它(这样它不会杀死您的程序),请通过调用

#include <signal.h>
// ...
signal(SIGPIPE, SIG_IGN); // ignore broken pipe signal 

您可能希望对您可能期望的其他信号执行相同的操作,否则这对您的进程来说是致命的(SIGHUP,...)。

总而言之,Valgrind 并没有杀死你的进程,而是给了你一个关于你的进程为什么会死掉的提示。只有少数情况下我看到 Valgrind 杀死了我的进程(这当然是我自己的错)——通常不会。即使你读/写你不拥有的内存地址,Valgrind 也不会杀死你的进程。当然,它会抱怨,但它会执行指令,而真正杀死你的进程的是在你试图读/写内存之后马上出现的 SIGSEGV。

这就是 Valgrind 杀死你的进程时的样子: 当 Valgrind 必须终止您的进程时的屏幕截图。

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

于 2017-04-30T19:36:52.443 回答