【问题标题】:How to determine why valgrind/callgrind kills process如何确定为什么 valgrind/callgrind 会杀死进程
【发布时间】:2016-11-30 02:59:04
【问题描述】:

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

但是,当在 valgrind --tool=callgrind 下运行时,程序会执行一小段时间,然后停止,valgrind 报告 Killed 作为它的最后一个输出到 stdout。

有没有办法让我确定 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==

【问题讨论】:

  • 你确定它起源于 valgrind 吗?还是您的内存不足并且内核正在杀死该进程?
  • @threadp callgrind 会增加显着的内存开销吗?我没有在我的应用程序中分配太多内存,并且在通常在内核中运行之前它从未耗尽内存?我将如何确定这一点?
  • 在杀死发生后检查你的dmesg 输出。这不太可能是问题,但有可能。
  • dmesg 输出中没有与我的进程或 valgrind 相关的任何内容

标签: c++ multithreading profiling valgrind callgrind


【解决方案1】:

据我所知,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 + 更多跟踪,如果上面没有 还是要澄清一下。

【讨论】:

  • 感谢您的建议,我已经相应地更新了我的问题!
  • 根据跟踪,您的进程似乎收到了 SIGPIPE 信号 13。默认情况下,此类信号会杀死您的进程。
【解决方案2】:

这是一个有点老的问题 - 但正在发生的事情是您正在接收 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 杀死你的进程时的样子:

这种情况很少发生,我实际上截取了它。 ;)

【讨论】:

  • 我很惊讶这有 0 票。您对为什么截屏它的原因是正确的。你的帖子的其余部分也是 +1。
  • 我认为这仅仅是因为这个问题来自 2016 年,而我在 2017 年回答了这个问题。很少有人关注旧问题,这是一个相当低调的问题 ;)
  • 可能是这样。但是,如果我遇到它,许多其他人肯定会这样做。谁能告诉?嗯,好吧,我想这并不重要 - 我只是认为它值得一票,所以你去吧。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-29
  • 1970-01-01
  • 2014-09-25
  • 2021-09-13
  • 2020-01-10
  • 2014-12-17
相关资源
最近更新 更多