Получение обратной трассировки другого потока - PullRequest
16 голосов
/ 19 июня 2011

В Linux, чтобы получить обратную трассировку, вы можете использовать библиотечный вызов backtrace (), но он возвращает только обратную трассировку текущего потока.Есть ли способ получить обратную трассировку какого-либо другого потока, предполагая, что я знаю, что это TID (или pthread_t), и я могу гарантировать, что он спит?

Кажется, что проект libunwind (http://www.nongnu.org/libunwind/) может помочь. Проблема в том, чточто он не поддерживается CentOS, поэтому я предпочитаю не использовать его.

Любые другие идеи? Спасибо.

Ответы [ 3 ]

10 голосов
/ 07 апреля 2012

Я сам реализовал это здесь .

Изначально я хотел реализовать нечто подобное, как предлагалось здесь , то есть получить каким-то образом указатель верхнего кадра потока ираскручивать его вручную (связанный источник получен из реализации Apple backtrace, поэтому может быть специфичным для Apple, но идея универсальна).

Однако, чтобы это было безопасно (а источник выше неможет даже порваться), вы должны приостановить поток при доступе к его стеку.Я искал различные способы приостановить поток и нашел это , это и это .В принципе, нет действительно хорошего способа.Обычный взлом, также используемый Hotspot JAVA VM , заключается в использовании сигналов и отправке собственного потока в ваш поток с помощью pthread_kill .

Итак, как я хотел быв любом случае, мне нужен такой взлом сигнала, я могу сделать его немного проще и просто использовать backtrace внутри обработчика вызываемого сигнала, который выполняется в целевом потоке (как также предложено здесь sandeep ).Это в основном то, что делает моя реализация.

Если вам также интересно напечатать обратную трассировку, то есть получить некоторую полезную информацию об отладке (имя функции, имя файла исходного кода, номер строки исходного кода, ...), прочитайте здесь о расширенном backtrace_symbols на основе libbfd.Или просто посмотрите источник здесь .

8 голосов
/ 20 июня 2011

Обработка сигналов с помощью backtrace может решить вашу задачу.

Я имею в виду, если у вас есть PID потока, вы можете подать сигнал для этого потока. и в обработчике вы можете использовать обратную трассировку. так как обработчик будет выполняться в этом компонентном потоке, обратный след будет выводить то, что вам нужно.

0 голосов
/ 03 ноября 2016

GDB предоставляет следующие средства для отладки многопоточных программ:

  • автоматическое уведомление о новых потоках
  • 'thread-id', команда для переключения между потоками
  • 'info threads', команда для запроса о существующих потоках
  • 'thread apply [thread-id-list] [все] аргументы', команда для применения команды к списку потоков
  • специфичные для потока точки останова
  • 'set print thread-events', который управляет печатью сообщений при запуске и выходе из потока.
  • 'set libthread-db-search-path path', который позволяет пользователю указать, какой libthread_db использовать, если выбор по умолчанию не совместим с программой.

Так что простоПерейти к требуемому потоку в GDB по cmd: 'thread-id'.Затем выполните «bt» в контексте этого потока, чтобы напечатать его обратный след.

...