Автоматическое добавление журналов функций входа / выхода в проект - PullRequest
25 голосов
/ 17 февраля 2010

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

printf("Entered into %s", __FUNCTION__)

и

printf("Exited from %s", __FUNCTION__)

для каждой функции, и я не хочу касаться какого-либо исходного файла.

У вас есть предложения? Есть ли флаг компилятора, который автоматически делает это для меня?

Пояснения к комментариям:

  • Я буду кросс-компилировать исходный код для запуска его на ARM.
  • Я скомпилирую его с помощью gcc.
  • Я не хочу анализировать статический код. Я хочу отслеживать время выполнения. Так что кислород не облегчит мне жизнь.
  • У меня есть источник, и я могу скомпилировать его.
  • Я не хочу использовать Аспектно-ориентированное программирование.

EDIT: Я обнаружил, что команда frame в приглашении gdb печатает текущий кадр (или, можно сказать, имя функции) в тот момент времени. Возможно, можно (используя сценарии GDB) вызывать команду frame каждый раз, когда вызывается функция. Что ты думаешь?

Ответы [ 5 ]

28 голосов
/ 18 февраля 2010

Помимо обычных методов отладчика и аспектно-ориентированного программирования, вы также можете вводить свои собственные инструментальные функции, используя опции командной строки gcc * -finstrument-functions. Вам придется реализовать свои собственные функции __cyg_profile_func_enter() и __cyg_profile_func_exit() (объявите их как extern "C" в C ++).

Они предоставляют средства для отслеживания того, какая функция была вызвана откуда. Однако интерфейс немного сложен в использовании, поскольку, например, адрес вызываемой функции и ее сайт вызова передаются вместо имени функции. Вы можете зарегистрировать адреса, а затем извлечь соответствующие имена из таблицы символов, используя что-то вроде objdump --syms или nm, при условии, конечно, что символы не были удалены из рассматриваемые двоичные файлы.

Возможно, будет проще использовать gdb. YMMV. :)

11 голосов
/ 18 февраля 2010

Вы сказали: «И при этом я не хочу трогать какой-либо исходный файл» ... Честная игра, если вы позволите сценарию сделать это для вас?

Запустите это на всех ваших .cpp файлах

sed 's/^{/{ENTRY/'

Чтобы он превратил их в это:

void foo()
{ENTRY
  // code here
}

Поместите это в заголовок, который может быть # # включен каждой единицей:

#define ENTRY EntryRaiiObject obj ## __LINE__ (__FUNCTION__);

struct EntryRaiiObject {
  EntryRaiiObject(const char *f) : f_(f) { printf("Entered into %s", f_); }
  ~EntryRaiiObject() { printf("Exited from %s", f_); }
  const char *f_;
};

Возможно, вам придется стать более изощренным с помощью скрипта sed. Вы также можете поместить макрос ENTRY в другое место, где хотите исследовать, например, в какую-то глубоко вложенную область видимости функции.

4 голосов
/ 17 февраля 2010

Использовать / Gh (включить _penter Hook Function) и / GH (включить _pexit Hook Function) переключатели компилятора (если вы можете скомпилировать источники конечно)

ПРИМЕЧАНИЕ: вы не сможете использовать эти макросы. См. Здесь («вам нужно получить адрес функции (в регистре EIP) и сравнить его с адресами в файле карты, которые могут быть сгенерированы компоновщиком (при условии, что перебазировка не произошла). будь очень медленным. ")

2 голосов
/ 17 февраля 2010

Согласитесь с Уильямом, используйте gdb, чтобы увидеть поток времени выполнения.
Есть некоторый статический анализатор кода, который может сказать, какие функции вызывают, и может дать вам некоторый граф потока вызовов. Одним из инструментов является «Понимание C ++» (поддержка C / C ++), но это не бесплатно, я думаю. Но вы можете найти похожие инструменты.

1 голос
/ 17 февраля 2010

Если вы используете gcc, флаг волшебного компилятора будет -g. Скомпилируйте с символами отладки, запустите программу под GDB и сгенерируйте трассировки стека. Вы также можете использовать ptrace, но, вероятно, намного проще просто использовать gdb.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...