GDB и OpenOCD: вывод всех выполненных функций

В настоящее время я занимаюсь отладкой микроконтроллера STM32F4 (плата Nucleo), и теперь моя задача — знать все функции, которые так или иначе вызывались во время выполнения. Конечно, с OpenOCD и GDB я уже могу видеть обратную трассировку, когда цель приостановлена, но на самом деле она не может отражать полную историю работы прошивки. Кроме того, есть некоторые аппаратные ISR, которые, я думаю, не имеют «родителей» с точки зрения стека вызовов C.

Упрощенный пример. Предположим, у нас есть такой источник:

#include "math.h"

ISR tick_10ms() {
    asm("nope");
}

void foo(double x) {
    double y = sin(x);
}

int bar(int a, int b, int c) {
    foo((double)(a-b+c));
    return 0;
}

void main() {
    foo(3.14);
    int z = bar(1, 2, 3);

    while (1) {}
}

и когда мы программируем MCU с его помощью, я хочу видеть что-то вроде (в реальном времени или на остановке — не имеет значения):

main()
  foo(3.14)
    sin(3.14)
  bar(1, 2, 3)
    foo(2.0)
      sin(2.0)
tick_10ms()
tick_10ms()
tick_10ms()
...

Так можно ли как-то (или хотя бы похоже)?


person Hello Human    schedule 20.03.2018    source источник


Ответы (1)


Попробуйте запустить вашу программу "под" gdb.

Затем скажите что-то вроде:

rbreak .
commands
frame
cont
end

Это должно поставить точку останова на все функции (см. rbreak о том, как выборочно поставить точку останова на функцию в определенных модулях) и запускать frame+continue при каждом попадании.

person dbrank0    schedule 21.03.2018
comment
Я думаю, что это отличное решение для настольных приложений и, к сожалению, не применимо для STM32F4 из-за ограниченного количества аппаратных точек останова. Для моего MCU это (через OpenOCD): Info : stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpoints. - person Hello Human; 29.03.2018
comment
Моя программа слишком велика, чтобы полностью храниться в оперативной памяти (я использую сторонние библиотеки), так что да, она во флэш-памяти. - person Hello Human; 29.03.2018