Как создать дамп потока с помощью 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, и ваша программа продолжит работу.