Подтвердить что ты не робот

Получение обратной трассировки другой нити

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

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

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

4b9b3361

Ответ 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' в этом контексте потока, чтобы напечатать обратную трассировку потока.