Я написал многопоточный стресс-тест для инфраструктуры базы данных, с которой я работаю, и я пытаюсь профилировать ее с помощью 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==
Насколько мне известно, 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 убивает ваш процесс:
Это случается так редко, я на самом деле сделал это. 😉