2016-07-26 65 views
0

我已經爲我正在使用的數據庫基礎結構編寫了多線程壓力測試,並且我正在嘗試使用callgrind對其進行配置。該程序完全在valgrind之外執行,並提供預期的結果。如何確定爲什麼valgrind/callgrind殺死進程

但是,在valgrind --tool=callgrind下運行程序時,程序會執行很短的時間,然後停止,valgrind會在上次輸出到stdout時報告Killed

有沒有辦法讓我確定爲什麼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 
    

    跟蹤可能會給出一個線索,然後說明它爲什麼會中止/被殺死。

  2. --tool=memcheck--tool=helgrind 下運行(同樣,如果崩潰,您可以用更多的跟蹤運行)。

  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它。 ;)