#gdb #freertos #backtrace
#gdb #freertos #обратная трассировка
Вопрос:
У меня есть FreeRTOS, работающий на процессоре ARM, и у меня нет dump_stack(), доступного для меня… Я пытаюсь проверить цепочку вызовов и сильно пропускаю dump_stack()… Я немного погуглил и нашел что-то близкое к тому, что искал, используя утилиту GCC(/ GDB) _Unwind_Backtrace(), но она печатает только адрес stack_frame . Он не обеспечивает сопоставление значимым символам (например, именам функций). Любая помощь действительно ценится.
#include <stdio.h>
#include <unwind.h>
#include <stdint.h>
static _Unwind_Reason_Code unwind_backtrace_callback(struct _Unwind_Context* context, void* arg)
{
uintptr_t pc = _Unwind_GetIP(context);
if (pc) {
printf("unwind got pc ...0x%xn", pc);
}
return _URC_NO_REASON;
}
ssize_t unwind_backtrace()
{
_Unwind_Reason_Code rc = _Unwind_Backtrace(unwind_backtrace_callback, 0);
return rc == _URC_END_OF_STACK ? 0 : -1;
}
void func_1()
{
int ret = unwind_backtrace();
printf("unwind_backtrace return ...%dn", ret);
}
void func_2()
{
func_1();
}
int main()
{
func_2();
return 0;
}
Result:
unwind got pc ...0x40076b
unwind got pc ...0x400796
unwind got pc ...0x4007bd
unwind got pc ...0x400819
unwind got pc ...0x67314b15
unwind got pc ...0x400649
unwind_backtrace return ...0
Ответ №1:
Все IDE, которые я использую (а я использую много), показывают мне трассировку стека в окне — но только для текущей выполняемой задачи. Если я хочу видеть трассировку для всех задач, мне нужен полностью потокоустойчивый плагин FreeRTOS типа, предоставляемого Segger, IAR и Code Confidence .
Комментарии:
1. Привет, Ричард, спасибо за ответ. На самом деле я использую комбинацию Linux-Cscope-Ctags для записи / просмотра кода прошивки и кросс-компиляции по цепочке GCC / ARM. Теперь загрузил двоичный файл в устройство (у меня нет устройства JTAG) и хочу проверить цепочку вызовов в какой-либо функции.
Ответ №2:
Он не обеспечивает сопоставление значимому символу
«Стандартный» способ выполнить это сопоставление — использовать addr2line . Что-то вроде:
addr2line -fe a.out 0x40076b 0x400796 0x4007bd ...
Обновить:
Я хочу конвертировать на лету…
Ну, тогда вы должны были попросить об этом.
Это простой вопрос написания кода. Вам нужно написать код, который будет сопоставлять диапазоны адресов с именами символов (точно так же, как addr2line
это делается).
На платформе ELF это на самом деле довольно просто: прочитайте Elf32_Sym
s из .symtab
раздела, чтобы построить адрес для сопоставления символов, и найдите свои адреса в этой карте. Вам также нужно будет прочитать соответствующие имена символов из .strtab
раздела ( Elf32_Sym.st_name
это смещение в .strtab
).
Комментарии:
1. спасибо за предложение «addr2line». Это делается для преобразования шестнадцатеричных символов в имя ФУНКЦИИ в автономном режиме. Я хочу конвертировать на лету….