Как определить, почему 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==

0

Решение

Насколько мне известно, 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 + еще трассировка, если выше не сделал
    пока уточню.

2

Другие решения

Это немного старый вопрос, но происходит то, что вы получаете сигнал SIGPIPE (сломанный канал — запись в канал, который ничего не слушает на другом конце).

Valgrind принимает это к сведению («эй, я вижу SIGPIPE, предназначенный для вашей программы») и продолжает доставлять его в вашу программу (так как в конце концов он был предназначен для него).

Поскольку вы, вероятно, не указали, что должно произойти при получении SIGPIPE, выполняется действие по умолчанию, которое завершает вашу программу. Увидеть Почему существует SIGPIPE? . Помните, что программы под Valgrind работают намного медленнее, поэтому поведение («работает под Valgrind и не работает иначе» и наоборот) может отличаться в зависимости от времени.

Если вы ожидаете SIGPIPE при регулярном использовании и хотите игнорировать его (чтобы он не убивал вашу программу), сделайте это, вызвав

#include <signal.h>
// ...
signal(SIGPIPE, SIG_IGN); // ignore broken pipe signal

Возможно, вы захотите сделать то же самое для других сигналов, которые вы можете ожидать и которые в противном случае были бы фатальными для вашего процесса (SIGHUP, …).

Таким образом, чтобы подвести итог, Valgrind не убил ваш процесс, но вместо этого дал вам подсказку о том, почему ваш процесс умирает. Лишь в нескольких случаях я видел, как Вальгринд убивал мой процесс (что, конечно, было моей собственной ошибкой) — обычно это не так. Даже когда вы читаете / пишете по адресам памяти, которые вам не принадлежат, Valgrind не убьет ваш процесс. Конечно, он будет жаловаться, но выполнит инструкцию, а то, что на самом деле убивает ваш процесс, это SIGSEGV, который появится сразу после того, как вы попытаетесь прочитать / записать память.

Вот как это выглядит, когда Valgrind убивает ваш процесс:
Скриншот того, как это выглядит, когда Valgrind должен убить ваш процесс.

Это случается так редко, я на самом деле сделал это. 😉

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector