Автоматическое добавление журналов функций входа / выхода в проект

Решением моей проблемы было объединение gmock и gtest, как описано по ссылке

https://github.com/google/googletest/blob/master/googlemock/docs/CookBook. md # делегирование-звонки-подделка

Единственное изменение, которое я сделал в своем коде, состоит в том, что вместо определения пути к данным конфигурации с помощью #define я создал функцию getConfigFilePath () который возвращает жестко заданный путь к файлу конфигурации в установленном приложении. Отсюда я издевался над классом, и в моем макете я вызываю фальшивую функцию getConfigFilePath (), которая при выполнении реального кода возвращает жесткий код пути к файлу конфигурации в дереве проекта в ClearCase. Это именно то, что я искал.

25
задан 03.10.2019, 02:14

5 ответов

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

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

Это может быть проще в использовании gdb. YMMV. :)

28
ответ дан 03.10.2019, 02:16
  • 1
    хотя... я думаю, что этот вид вещи представил бы значительные издержки, даже если пользовательское перед/после того, как функцией легко. – Trevor Boyd Smith 03.10.2019, 02:17
  • 2
    Точно, что я искал:) – Benji Mizrahi 03.10.2019, 02:17
  • 3
    gcc FTW снова =) – Trevor Boyd Smith 03.10.2019, 02:17
  • 4
    Почему бы не использовать e.key вместо e.which? – ratskin 25.01.2020, 13:25

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

1
ответ дан 03.10.2019, 02:15
  • 1
    Поскольку фас, как я знаю, отслеживание стека, является состоянием стопки вызова функции в определенный момент. Я могу произвести имена функций вызванных функций в последовательности в файл с помощью опции отслеживания стека в gdb? – Benji Mizrahi 03.10.2019, 02:15
  • 2
    Потрясающий, Спасибо! – julien_c 25.01.2020, 13:26

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

Запустите это на всех ваших файлах .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 в любое другое место, где хотите исследовать, например, в какую-то глубоко вложенную область видимости функции.

11
ответ дан 03.10.2019, 02:15
  • 1
    Hehe, хорошо отличная работа тогда – ratskin 25.01.2020, 13:25

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

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

4
ответ дан 03.10.2019, 02:17
  • 1
    Спасибо PoweRoy. Вы знаете соответствующий флаг компилятора для gcc? Или каково название этой техники, так, чтобы я мог погуглить его? – Benji Mizrahi 03.10.2019, 02:17
  • 2
    Don' t знают для gcc, '-g' от William выглядит одинаково. Я искал ' C++ вводит/выходит функцию hook' на Google: gcc.gnu.org/onlinedocs/gccint/Function-Entry.html – RvdK 03.10.2019, 02:18
  • 3
    Вы уверены там, что действительно ли такая вещь как ':input' псевдоселектор? Я haven' t бывший в состоянии для нахождения ссылки для этого. – julien_c 25.01.2020, 13:25

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

2
ответ дан 03.10.2019, 02:17
  • 1
    редкий, " семантический parser" имеет утилиту построения графика. Это генерирует graphviz файл, который может быть преобразован в диаграмму. sparse.wiki.kernel.org/index.php/Main_Page – Tim Schaeffer 03.10.2019, 02:18
  • 2
    Каков точный флаг опции для gdb, который позволит ему распечатать каждую функцию, которая вызывается в тот момент? – Benji Mizrahi 03.10.2019, 02:18
  • 3

Теги

Похожие вопросы