Добавление пропуска в gcc? - PullRequest
       14

Добавление пропуска в gcc?

8 голосов
/ 09 апреля 2009

Кто-нибудь добавил пропуск в gcc? или не совсем пас, но добавив опцию, чтобы сделать некоторые неприятные вещи ... :-) ...

У меня все еще остается та же проблема с вызовом функции непосредственно перед возвратом из другой ... поэтому я хотел бы исследовать ее, внедрив что-то в gcc ...

Приветствие.

РЕДАКТИРОВАТЬ : Добавление прохода в компилятор означает повторное посещение дерева для выполнения некоторых оптимизаций или некоторого анализа. Я хотел бы эмулировать поведение __cyg_profile_func_exit, но только для некоторых функций и иметь возможность доступа к исходному возвращаемому значению.

Так что я собираюсь попытаться улучшить свой вопрос. Я хотел бы подражать действительно базовому AOSD-подобному поведению. AOSD или Аспектно-ориентированное программирование позволяет добавлять сквозные задачи (отладка - сквозная задача).

int main(int argc, char ** argv) {
  return foo(argc);
}

int foo(int arg_num) { 
   int result = arg_num > 3 ? arg_num : 42;
   return result;
}

int dbg(int returned) {
   printf("Return %d", returned);
}

Я хотел бы сказать, что я хотел бы вызвать функцию dbg после выполнения функции foo. Проблема в том, как сказать компилятору изменить поток управления и выполнить dbg. dbg должен выполняться между return и foo (argc) ...

Это действительно похоже на __cyg_profile_function_exit, но только в некоторых случаях (а проблема в __cyg_profile_function_exit заключается в том, что вы не можете легко увидеть и изменить возвращенное значение).

Ответы [ 6 ]

4 голосов
/ 23 апреля 2009

Если вы по-прежнему заинтересованы в добавлении пропуска GCC, вы можете начать читать материал GCC Wiki примерно так:

3 голосов
/ 19 мая 2009

Только для дальнейшего использования: в следующих версиях gcc (4.4.0+) будет поддерживаться плагинов , специально предназначенных для таких случаев использования, как добавление оптимизационных проходов в компилятор без необходимости загрузить весь компилятор.

6 мая 2009: GCC теперь может быть расширен с помощью универсальной инфраструктуры плагинов на хост-платформах, которые поддерживают динамически загружаемые объекты. (см. gcc.gnu.org )

1 голос
/ 09 апреля 2009

Вам нужно использовать GCC? LLVM похоже, что это будет работать. Он написан на C ++, и очень легко написать пропуск .

1 голос
/ 09 апреля 2009

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

Вы, вероятно, уже изучили некоторые манипуляции с исходным кодом на более высоком уровне для достижения того, чего хотите достичь; какой-то

int main(int argc, char ** argv) {
    return dbg(foo(argc));
}

вставлено с макросом на функцию "foo", возможно. Если вы ищете взлом компилятора, то, вероятно, вы не хотите изменять исходный код.

Здесь обсуждаются некоторые расширения gcc здесь , которые звучат немного как то, что вы собираетесь. Если у gcc есть что-то, что делает то, что вы хотите, это, вероятно, будет задокументировано в области документации C-language extensions . Я не смог найти ничего похожего на то, что вы описали, но, возможно, поскольку вы лучше понимаете, что ищете, вы лучше поймете, как его найти.

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

Что напоминает мне некоторые трюки с динамическими компоновщиками, с которыми я недавно сталкивался. Библиотека , вставляющая , может вставлять код вокруг вызовов функций, не затрагивая исходный источник. Пример, с которым я столкнулся, был на Solaris, но, вероятно, есть аналог на других платформах.

Только что наткнулся на заданную опцию -finstrument-functions здесь

-finstrument-функции

Генерация инструментария для входа и выхода из функций. Сразу после функции entry и непосредственно перед выходом из функции будут вызваны следующие функции профилирования с адресом текущей функции и ее сайта вызова. (На некоторых платформах __builtin_return_address не работает за пределами текущей функции, поэтому сайт вызова в противном случае информация может быть недоступна для функций профилирования.)

          void __cyg_profile_func_enter (void *this_fn,
                                         void *call_site);
          void __cyg_profile_func_exit  (void *this_fn,
                                         void *call_site);

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

1 голос
/ 09 апреля 2009

Чтобы ответить на ваш вопрос: gcc - довольно популярная платформа компилятора, на которой проводятся исследования компиляторов, так что да, я уверен, что кто-то это сделал.

Однако я не думаю, что это что-то сделано в выходные. Заниматься генерацией кода в gcc - это не то, чем вы будете заниматься на выходных. (Я не уверен, какова ваша сфера деятельности и сколько времени вы готовы потратить.) Если вы действительно хотите взломать gcc, чтобы делать то, что вы хотите, вы наверняка захотите начать с обсуждения на одном из gcc списки рассылки .

Советы: не думайте, что люди читали ваши другие вопросы. Если вы хотите сослаться на вопрос, добавьте ссылку на него, если вы хотите, чтобы люди его нашли.

0 голосов
/ 09 апреля 2009

GCC, GNU Compiler Collection, - это большой набор, и я не думаю, что взлом его исходного кода - это ваш ответ на проблемы с поиском в одном приложении.

Звучит так, как будто вы больше ищете инструменты для отладки или профилирования, такие как gdb и его различные интерфейсы (xgdb, ddd) и gprof . Инструменты проверки памяти / границ, такие как электрический забор, glibc memcheck , valgrind и mudflap , могут помочь, если это проблемы с памятью или указателем. Включение флагов компилятора для предупреждений и новых стандартов C может быть полезным -std=c99 -Wall -pedantic.

Я не могу понять, что вы подразумеваете под

У меня все еще та же проблема с вызов функции как раз перед возвращаясь из другого.

Так что я не уверен, что вы ищете. Можете ли вы привести пример тривиального или псевдокода?

т.е.

#include <stdio.h>
void a(void) {
   b();
}
void b(void) {
   printf("Hello World\n");
}
int main(int ac, char *av[]) {
   a();
   return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...