Я знаю, что могу получить трассировку стека текущего потока с помощью backtrace() или [NSThread callStackSymbols], но как я могу получить на трассе стека РАЗЛИЧНОГО потока (если он заморожен)?Печать трассировки стека из другого потока
ответ
EDIT: Мой первоначальный ответ не будет печатать из произвольной нити. Я с тех пор написал надлежащую реализацию в моем проекте обработчика аварии: https://github.com/kstenerud/KSCrash
В частности, эти файлы:
- https://github.com/kstenerud/KSCrash/blob/master/KSCrash/KSCrash/Reporting/Tools/KSBacktrace.h
- https://github.com/kstenerud/KSCrash/blob/master/KSCrash/KSCrash/Reporting/Tools/KSBacktrace.c
С некоторой помощью:
- https://github.com/kstenerud/KSCrash/blob/master/KSCrash/KSCrash/Reporting/Tools/KSMach.h
- https://github.com/kstenerud/KSCrash/blob/master/KSCrash/KSCrash/Reporting/Tools/KSMach.c
Что вы делаете:
- Сделать новый контекст машина структуру (_STRUCT_MCONTEXT)
- Заполните в своем состоянии стека с помощью thread_get_state()
- Получить счетчик программы (первая запись трассировки стека) и указатель кадра (все остальное)
- Пройдите через стек стека, на который указывает указатель кадра, и сохраните всю инструкцию a ddresses в буфере для последующего использования.
Обратите внимание, что перед этим следует приостановить поток, иначе вы сможете получить непредсказуемые результаты.
кадр стека заполняется структуры, содержащие два указателя:
- Указатель на следующий уровень в стеке
- адрес команды
Таким образом, вы должны принять это во внимание при идя по кадру, чтобы заполнить трассировку стека. Также есть возможность испорченного стека, приводящего к плохой указатель, которая приведет к сбою вашей программы. Вы можете обойти это, скопировав память, используя vm_read_overwrite(), который сначала запрашивает ядро, если он имеет доступ к памяти, поэтому он не сбой.
Как только у вас есть трассировка стека, вы можете просто вызвать backtrace() на нем, как обычно (обработчик аварии должен быть асинхронным, поэтому он реализует свой собственный метод обратной линии, но в нормальных случаях backtrace() в порядке) ,
Вот еще один более безопасный способ получить стоп-колл из другого потока: Implementation и some background information. Он использует обработку сигналов и порождает обработчик сигналов в целевом потоке. Преимущество заключается в том, что он является более кросс-платформенным, чем ваше решение, т. Е. Он должен работать где угодно, где у вас есть <signal.h>
и <execinfo.h>
.
Для печати вы можете использовать backtrace_symbols
, как и в своем собственном предложении. Но вам может быть интересна расширенная версия, которая реализована как here.Он использует libbfd (от binutils; последняя версия также в основном работает на MacOSX, см. here для небольшого ограничения, которое может вам не подходит), чтобы прочитать информацию об отладке и добавить номер строки и другую информацию (она также возвращается к dladdr
если все остальное терпит неудачу, то есть то, что делает backtrace_symbols
).
- 1. Печать трассировки стека в Logcat
- 2. Печать трассировки стека из обработчика сигнала
- 3. печать трассировки стека javascript-консоли
- 4. Печать трассировки стека в C++ (MSVC)?
- 5. Печать информации трассировки стека с C#
- 6. Печать трассировки стека в MinGW в Windows
- 7. Печать трассировки стека, включая законченные методы
- 8. печать трассировки стека python без исключения
- 9. Печать трассировки стека против самого исключения
- 10. Печать трассировки стека без блока try-catch
- 11. получение трассировки стека из отдельного потока в python
- 12. Печать трассировки стека из вновь созданного потока, когда исключено исключение исключений в Eclipse
- 13. Как создаются трассировки стека?
- 14. Получение трассировки стека из GDB
- 15. Интерпретация трассировки стека ANR
- 16. Печать трассировки стека C на Android 5/Lolipop
- 17. «Лучше» трассировки стека scala
- 18. Печать трассировки стека и продолжение после ошибки возникает в R
- 19. печать полной трассировки стека исключения в студии android
- 20. отключить PHP трассировки стека
- 21. Отслеживание трассировки стека
- 22. Чтение трассировки стека
- 23. Ошибка трассировки стека
- 24. инструменты анализа трассировки стека
- 25. Delphi 6 трассировки стека
- 26. Понимание трассировки стека
- 27. Очистка транспортир трассировки стека
- 28. Подсветка трассировки стека python
- 29. Ошибка трассировки стека
- 30. Ошибка трассировки стека узла
Обратите внимание, что вы должны приостановить поток во время чтения его стека. – Albert
Кроме того, вы уверены, что это работает? Он использует '__builtin_frame_address', который всегда находится в потоке ** current **. – Albert
Так получилось, что это действительно не работает (он печатает трассировку стека, но я не понимал, что это была печать из текущего потока). У меня есть новый код, который работает по назначению, но он еще не готов к выпуску. Я опубликую обновление после его готовности. – Karl