Фон:
У меня есть один большой инструмент моделирования, и мне нужно понять его логическое поведение. Чтобы сделать это, большую часть помощи я получу, если у меня есть хронологический порядок вызовов функций, для минимального рабочего примера.
Я нашел много инструментов в Интернете, например CygProfiler и etrace. Я стал настолько несчастным в поиске решения, которое я начал придерживаться самого сумасшедшего решения, использующего "шаг в" с отладчиком. Это хороший вариант, если у вас небольшая программа, но не полный инструмент моделирования.
Проблема:
Одна из проблем, с которыми я сталкиваюсь, заключается в том, что вышеупомянутые решения изначально предназначены для C
, и они сгенерируют статический файл (*.o
) при компиляции. С другой стороны, инструмент моделирования генерирует общую библиотеку (.so
). У меня мало знаний о материалах более низкого уровня, поэтому я, кажется, терплю неудачу, когда я пытаюсь связать их.
Я посмотрел на etrace
документацию, и он говорит:
Чтобы узнать, как изменить ptrace.c для работы с динамической библиотекой, посмотрите каталог example2. Источники также создают автономные исполняемый файл, но макрос PTRACE_REFERENCE_FUNCTION определяется так же, как и это будет для динамической библиотеки.
Если вы посмотрите на репо, нет никакой разницы между файлами в папках example
и example2
. Только в файле example2
есть дополнительный .h
файл.
С другой стороны, если вы посмотрите src/ptrace.c
, там написано:
При использовании ptrace в динамической библиотеке вы должны установить Макрос PTRACE_REFERENCE_FUNCTION должен быть именем функции в библиотека. Адрес этой функции при загрузке будет первым вывод строки в файл трассировки и разрешить перевод другие указатели на вход и выход к их символическим именам. Вы можете установить макрос PTRACE_INCLUDE с любыми директивами #include, необходимыми для эта функция будет доступна для этого исходного файла.
немного ниже есть прокомментированный код:
/* When using ptrace on a dynamic library, the following must be defined:
#include "any files needed for PTRACE_REFERENCE_FUNCTION"
#define PTRACE_REFERENCE_FUNCTION functionName
`*/
Вопрос:
В сущности, вопрос заключается в следующем: как использовать etrace
с динамической библиотекой?
Нужно ли мне # включать любые файлы?
Для отслеживания автономной программы нет необходимости включать #include any дополнительный файл. Просто свяжите свой код с ptrace.c и используйте -finstrument-functions в качестве опции компиляции для gcc. Это должно сделать это.
Как связать код С++, который создается с помощью make файлов с помощью ptrace.c
Заключительное примечание:. Я был бы признателен, если бы кто-то несла с моим невежеством и обеспечил пошаговое решение моего вопроса.
Обновление 1:
Мне удалось добавить библиотеки, связанные с etrace, в инструмент моделирования, и он отлично работает.
Однако (вероятно, потому, что скрипты слишком стары или не предназначены для использования с С++), я получаю следующую ошибку при использовании perl script, предоставленный по умолчанию etrace
Hexadecimal number > 0xffffffff non-portable"
Вероятно, это немного изменяет характер этого вопроса, превращая его больше в проблему, связанную с perl.
Если эта проблема решена, я надеюсь, что etrace
будет работать со сложным проектом, и я расскажу подробности
Обновление 2:
Я принял предложения от @Harry, и я считаю, что это будет работать в большинстве проектов. Однако в моем случае я получаю следующее из perl script:
Use of uninitialized value within %SYMBOLTABLE in list assignment at etrace2.pl line 99, <CALL_DATA> line 1.
\-- ???
| \-- ???
\-- ???
| \-- ???
| | \-- ???
\-- ???
| \-- ???
\-- ???
| \-- ???
\-- ???
| \-- ???
\-- ???
| \-- ???
\-- ???
| \-- ???
Из-за автогенерированных make файлов я использовал LD_PRELOAD для загрузки общей библиотеки для etrace.so, которую получил следующим образом:
gcc -g -finstrument-functions -shared -fPIC ptrace.c -o etrace.so -I <path-to-etrace>
Я создал dummy etrace.h внутри инструмента:
#ifndef __ETRACE_H_
#define __ETRACE_H_
#include <stdio.h>
void Crumble_buy(char * what, int quantity, char * unit);
void Crumble_buy(char * what, int quantity, char * unit)
{
printf("buy %d %s of %s\n", quantity, unit, what);
}
#endif
и использовал Crumble_buy
для #define
и etrace.h
для #include
.