2016-07-26 8 views
0

Я написал многопоточный стресс-тест для инфраструктуры базы данных, с которой я работаю, и пытаюсь профилировать ее с помощью callgrind. Программа отлично работает вне valgrind и обеспечивает ожидаемые результаты.Как определить, почему процесс valgrind/callgrind убивает

Однако при запуске под valgrind --tool=callgrind программа выполняется в течение короткого промежутка времени, а затем останавливается с сообщением valgrind 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 Заставляет ли addgrind добавить значительные накладные расходы памяти? Я не выделяю много памяти в своем приложении, и у нее никогда не хватало памяти, прежде чем при обычном запуске в ядре? Как я могу это определить? –

+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 его. ;)