Получение обратной трассировки другой нити
В Linux, чтобы получить обратную трассировку, вы можете использовать вызов библиотеки backtrace(), но она возвращает только обратную трассировку текущего потока. Есть ли способ получить обратную трассировку другого потока, если я знаю, что это TID (или pthread_t), и я могу гарантировать, что он спит?
Кажется, что проект libunwind (http://www.nongnu.org/libunwind/) может помочь. Проблема в том, что он не поддерживается CentOS, поэтому я предпочитаю не использовать его.
Любые другие идеи?
Спасибо.
Ответы
Ответ 1
Обработка сигналов с помощью backtrace может решить вашу задачу.
Я имею в виду, если у вас есть PID Thread, вы можете поднять сигнал для этого потока. и в обработчике вы можете использовать обратную линию. поскольку обработчик будет выполняться в этой частичной нити, backtrace будет выводить то, что вам нужно.
Ответ 2
Я реализовал это сам здесь.
Изначально я хотел реализовать что-то похожее, как предлагалось здесь, т.е. получить как-то верхний указатель потока потока и разматывать его вручную (связанный источник происходит из Яблоки backtrace
, поэтому может быть специфичным для Apple, но идея является общей).
Однако, чтобы иметь это безопасное (и источник выше не является и даже может быть сломан в любом случае), вы должны приостановить поток во время доступа к его стеку. Я искал различные способы приостановить поток и нашел этот, этот и это. В принципе, нет действительно хорошего способа. Обычным хаком, а также используемым Hotspot JAVA VM, является использование сигналов и отправка пользовательского сигнала в ваш поток через pthread_kill.
Итак, поскольку мне все равно нужен такой хакер, я могу немного упростить его и просто использовать backtrace
внутри обработчика вызываемого сигнала, который выполняется в целевом потоке (как также предлагается здесь sandeep). Это в основном то, что делает моя реализация.
Если вы также заинтересованы в печати backtrace, то есть получите некоторую полезную информацию отладки (имя функции, имя файла исходного кода, номер строки исходного кода,...), читайте здесь о расширенном backtrace_symbols
на основе libbfd. Или просто посмотрите источник здесь.
Ответ 3
gdb предоставляет эти средства для отладки программ с несколькими потоками:
- автоматическое уведомление о новых потоках
- 'thread thread-id, команда для переключения между потоками
- 'инфо-потоки, команда для запроса существующих потоков
- 'thread apply [thread-id-list] [all] args, команда для применения команды к списку потоков
- контрольные точки, зависящие от потока
- 'устанавливает поток событий печати, который контролирует печать сообщений при запуске и выходе потока.
- 'установить путь к каталогу libthread-db-search-path, который позволяет пользователю указать, какой libthread_db использовать, если выбор по умолчанию несовместим с программой.
Так что просто goto обязательный поток в GDB по cmd: 'thread thread-id'.
Затем выполните 'bt' в этом контексте потока, чтобы напечатать обратную трассировку потока.