Отладка макроса с помощью gdb

Я знаю, что альтернативный подход заключается в преобразовании макроса во встроенную функцию, которая позволит GDB войти в него.

Но я хочу знать, есть ли способ отладки каждой строки определения макроса с помощью gdb, как и любой другой функции.

например, в приведенном ниже фрагменте кода.

#define print_macro printf("We're inside the macro now");\
     for(int i=0; i<100; i++) \
     { \
          if(i%2 == 0) \
              printf("%d is even number", i); \
          else \
              printf("%d is odd number);\
     }

int main()
{
    print_macro;
    return 0;
}

В приглашении GDB мы можем взломать основной и затем перейти в print_macro и пройти каждую строку своего определения по одному с помощью next

2 ответа

Ознакомьтесь с командами gdb:

gdb> macro expand *expression using macros*
gdb> info macro *macro name*

В зависимости от вашей версии g++ вам может потребоваться добавить -ggdb3 в команду компиляции.

Если макрос определен несколько раз, info macro по умолчанию будет отображаться тот, который применяется в текущем местоположении. info macro -all ... перечисляет возможные альтернативы.

Трудность отладки является одной из причин, по которой следует избегать макросов. Нет, вы не можете отладить макрокоманды построчно, вы не можете установить точку останова в макросе, вы не можете видеть значения переменных в макросе и т. Д. Причины по крайней мере две:

Технический. Компилятор вообще ничего не знает о расширении макросов. Все макросы раскрываются препроцессором до вызова компилятора. Компилятор не сможет добавить отладочную информацию для адресации строк макросов, у компилятора ее нет! Таким образом, отладчик может только предполагать, как именно препроцессор выполняет расширение макроса.

Логично Выходная команда кода C++ не обязательно соответствует одной строке (одной) макрокоманды. Структурно и синтаксически, макрокод может совершенно не походить на код C++. Такая построчная отладка макросов кажется логичной только для простых примеров, подобных вашему, где результирующий код C++ легко просматривается (легко для вас, а не для отладчика!). Но рассмотрим более замысловатый пример. На какую строку должен указывать отладчик в этом примере? Я думаю ASSIGN(VAR(INT, i), 10); единственный логичный вариант.

#define INT int
#define VAR(TYPE, NAME)  TYPE NAME
#define ASSIGN(V, VAL) V = VAL

ASSIGN(VAR(INT, i), 10);

Вы не можете отлаживать макросы как код С++, так как они не являются непосредственно кодом С++! Тем не менее, вы можете расширить макрос для отладки в соответствии с рекомендациями. Если вам нужна гибкость, такая как макросы, но без проблем с отладкой, используйте шаблонные функции.

Вы не можете пройти через макросы, но вы можете использовать -E флаг, чтобы увидеть, что макросы расширяются до:

g++ main.cpp -E | less
Другие вопросы по тегам