Как создать дамп потока с помощью MONO?
Как я могу показать потоки (stacktraces) в висячем приложении, которое работает с MONO?
Я знаю, что могу это сделать в .NET с помощью Managed Stack Explorer (MSE). Поскольку приложение зависает только с MONO, мне нужно сделать это с помощью MONO.
Или есть другие идеи, как я могу найти место висит?
Ответы
Ответ 1
Предполагая, что вы находитесь в Linux/Unix, а не в Windows, отправьте сигнал SIGQUIT в свою программу. Это можно сделать с помощью
kill -QUIT $PID
где $PID - это pid вашей программы. Затем Mono сбрасывает трассировки стека всех потоков в стандартный вывод. Обратите внимание, что, хотя процесс продолжает работать после этого, вы не должны ожидать, что он останется работоспособным/стабильным.
Посмотрите http://en.wikipedia.org/wiki/SIGQUIT для фона.
Ответ 2
Также можно быстро захватить трассировку управляемого стека с помощью GDB. Выполнить gdb
; используйте sudo, если вы не root или не отлаживаете процесс, принадлежащий вашему пользователю.
Выполните этот script, который я получил на странице отладки Mono на mono-project.org:
handle SIGXCPU SIG33 SIG35 SIGPWR nostop noprint
define mono_stack
set $mono_thread = mono_thread_current ()
if ($mono_thread == 0x00)
printf "No mono thread associated with this thread\n"
else
set $ucp = malloc (sizeof (ucontext_t))
call (void) getcontext ($ucp)
call (void) mono_print_thread_dump ($ucp)
call (void) free ($ucp)
end
end
Если вам нравится, вы можете отказаться от этих команд в своем ~/.gdbinit
, поэтому вам не нужно копировать и вставлять все время.
Теперь прикрепите к вашему PID:
attach 12345
Обратите внимание, что весь процесс теперь приостановлен, поэтому, если вы делаете это в процессе производства, рекомендуется script сделать это как можно быстрее.
Чтобы получить трассировку стека, выполните mono_stack
, как определено выше. Обратите внимание, что вы не увидите вывод в gdb, а в stdout. Если вы запускаете свой процесс с выскочкой, вы можете просто отредактировать задание выскочки, чтобы использовать console log
, чтобы записать его в /var/log/upstart
.
Возможно, вы заинтересованы в другом потоке, кроме основного. Для этого выполните info threads
, чтобы получить список потоков и thread 2
для переключения в поток # 2. Для получения дополнительной информации об отладке потоков см. отладка программ с несколькими потоками в документах GDB.
Как только вы закончите, выполните quit
, и ваша программа продолжит работу.