Как определить, почему valgrind/callgrind убивает процесс
Я написал многопоточный стресс-тест для инфраструктуры базы данных, с которой я работаю, и я пытаюсь профилировать ее с помощью callgrind. Программа отлично работает за пределами valgrind и обеспечивает ожидаемые результаты.
Однако при запуске под valgrind --tool=callgrind
программа выполняется в течение короткого промежутка времени, а затем останавливается с отчетностью valgrind Killed
как это последний вывод на стандартный вывод.
Есть ли способ определить, почему Вальгринд убил мою задачу?
Следуя совету доктора философии: он убивается 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==
2 ответа
Насколько мне известно, valgrind не убивает программу с таким малым количеством слов, как "kill". Такие вещи больше похожи на убийство из другого процесса.
Тем не менее, вы можете попробовать несколько вещей, чтобы выяснить, почему ваша программа ведет себя по-разному в valgrind, а не в натуре:
сначала запустите его под
valgrind --tool=none
, Это более быстрый инструмент (ничего не делать). Затем вы можете увидеть, ведет ли ваша программа так, как ожидалось. Если нет, то запустите с дополнительной внутренней трассировкой valgrind, например,--tool=none -v -v -v -d -d -d --trace-syscalls=yes --trace-signals=yes
След может дать подсказку о том, почему он прерывается / убивается.
запустить его под
--tool=memcheck
а также--tool=helgrind
(и аналогичным образом, если происходит сбой, вы можете запустить с большим количеством трассировки).и, наконец,
--tool=callgrind
+ еще трассировка, если выше не уточнил.
Это немного старый вопрос, но происходит то, что вы получаете сигнал SIGPIPE (сломанный канал - запись в канал, который ничего не слушает на другом конце).
Valgrind принимает это к сведению ("эй, я вижу SIGPIPE, предназначенный для вашей программы") и продолжает доставлять его в вашу программу (так как в конце концов он был предназначен для него).
Поскольку вы, вероятно, не указали, что должно произойти при получении SIGPIPE, выполняется действие по умолчанию, которое завершает вашу программу. См. Почему существует SIGPIPE?, Помните, что программы под Valgrind работают намного медленнее, поэтому поведение ("работает под Valgrind и не работает иначе" и наоборот) может отличаться в зависимости от времени.
Если вы ожидаете SIGPIPE при регулярном использовании и хотите игнорировать его (чтобы он не убивал вашу программу), сделайте это, вызвав
#include <signal.h>
// ...
signal(SIGPIPE, SIG_IGN); // ignore broken pipe signal
Возможно, вы захотите сделать то же самое для других сигналов, которые вы можете ожидать и которые в противном случае были бы фатальными для вашего процесса (SIGHUP, ...).
Таким образом, чтобы подвести итог, Valgrind не убил ваш процесс, но вместо этого дал вам подсказку о том, почему ваш процесс умирает. Лишь в нескольких случаях я видел, как Вальгринд убивал мой процесс (что, конечно, было моей собственной ошибкой) - обычно это не так. Даже когда вы читаете / пишете по адресам памяти, которые вам не принадлежат, Valgrind не убьет ваш процесс. Конечно, он будет жаловаться, но выполнит инструкцию, а то, что на самом деле убивает ваш процесс, это SIGSEGV, который появится сразу после того, как вы попытаетесь прочитать / записать память.
Вот как это выглядит, когда Valgrind убивает ваш процесс:
Это случается так редко, я на самом деле сделал это.;)