Существует ли макрос gcc для определения того, что указатели кадра не исключены? - PullRequest
2 голосов
/ 12 сентября 2009

Когда используется -fomit-frame-pointer (автоматически для различных настроек -O), выполнение обратной трассировки проблематично. Мне интересно, есть ли способ определить во время компиляции, что код скомпилирован с этим переключателем? В этом случае я мог бы добавить #ifndef, чтобы защититься от обратного отслеживания в случае дурного обращения.

Установлен ли какой-либо макрос при включенном переключателе -fomit-frame-pointer?

Спасибо

SetJmp

Ответы [ 3 ]

2 голосов
/ 12 сентября 2009

Я только что попробовал это:

gcc -E -fomit-frame-pointer -Wp,-dM foo.c > fpo.out
gcc -E -Wp,-dM foo.c > no-fpo.out
diff no-fpo.out fpo.out

где foo.c - простая программа «Hello World», которая не дала никаких результатов. Это означает, что все макросы препроцессора были идентичны, независимо от того, использовался -fomit-frame-pointer или нет. Поэтому я думаю, что ответ на ваш вопрос «нет».

Вероятно, лучшее, что вы можете сделать, - это изменить ваш Makefile (или то, что использует ваш процесс сборки), чтобы определить ваш собственный макрос (например, -DNO_FRAME_POINTERS или что-то еще) при использовании -fomit-frame-pointer.

1 голос
/ 12 сентября 2009

Что касается проверки, то во время выполнения проверьте, указывает ли регистр ebp (с учетом вашей архитектуры) на несколько байтов ниже вершины стека, а затем, если имеет смысл следовать за указателем, сохраненным в [ebp].

1 голос
/ 12 сентября 2009

Вы не можете сделать это во время компиляции, но во время выполнения вы можете проверить, оптимизирована ли ваша программа или нет.

Напишите код, который определенно будет изменен оптимизатором, например, смешивая энергонезависимую переменную с setjmp / longjmp, и по значению этой переменной вы будете знать, оптимизирована ваша программа или нет.

#include <setjmp.h>
#include <stdio.h>

int is_optimised(void) {
    int i = 1;
    jmp_buf jmp_loc;

    if (setjmp(jmp_loc)) {
        return i;  // optimiser changes it to "return 1"
    }

    i = 0;
    longjmp(jmp_loc, 1);

    return 0;
}

int main(int argc, char *argv[]) {
    printf("%soptimised\n", is_optimised() ? "" : "non-");

    return 0;
}

Если скомпилировано с GCC без ключа -O, выводится «non-optimised», для переключателей -O1 - -O4 выводится «optimised».

Конечно, ваш пробег (с другими компиляторами) может отличаться.

...