2016-07-26 65 views
0

私が作業しているデータベースインフラストラクチャのマルチスレッドストレステストを書いており、callgrindを使用してプロファイリングしようとしています。プログラムはvalgrindの外で完全に実行され、期待される結果が得られます。valgrind/callgrindがプロセスをkillする理由を調べる方法

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== 
+0

あなたはそれがvalgrindから始まったと確信していますか?あるいは、あなたはメモリがなくなり、カーネルがそのプロセスを殺していますか? – pah

+0

@threadp callgrindはかなりのメモリオーバーヘッドを追加しますか?私は自分のアプリケーションで多くのメモリを割り当てているわけではなく、通常はカーネルで実行する前にメモリが不足していることはありませんか?どのように私はこれを決定するだろうか? –

+0

強制終了後に 'dmesg'出力を確認してください。これは問題になる可能性は低いですが、可能性もあります。 – pah

答えて

2

、valgrindの「殺した」のような非常に少ない 冗長でプログラムを強制終了しない:この最初のインスタンスがここにあります。このようなことは、別のプロセスからの殺人のように見えます。

それにもかかわらず、あなたはあなたのプログラムがValgrindの下ではなく、ネイティブに異なっ を振る舞う理由を調査するためにいくつかのことを試してみることができます。

  1. は最初valgrind --tool=noneの下でそれを実行します。これは速いツールです(何もしません)。プログラムが期待どおりに動作するかどうかを確認できます。 そうでない場合は、追加のvalgrind内部トレースを使用して実行します。

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

    トレースは、なぜそれが打ち切られ/殺されたかの手がかりを与えるかもしれません。 --tool=memcheck--tool=helgrind

  2. 実行それが(と同様に、クラッシュした場合、あなたはより多くのトレースを実行することができます)。

  3. そして最後に--tool=callgrind+以上のトレースがない場合は、 まだ明確になります。

+0

あなたのアドバイスありがとう、私はそれに応じて私の質問を更新しました! –

+1

トレースによると、あなたのプロセスはSIGPIPEシグナル13を受け取ったようです。このようなシグナルはデフォルトでプロセスを停止させます。 – phd

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.

それはそうめったに起こらない、私は実際にそれをscreenshotted。 ;)

関連する問題