Background:
I have one big simulation tool, and I need to understand its logical behavior. In order to do that, the most of help I would get if I have the chronological order of function calls, for a minimal working example.
I found many tools online, like CygProfiler and etrace. I became so miserable on finding a solution that I started to follow the craziest solution of using "step into" with the debugger. Which is a good option if you have a small program but not a complete simulation tool.
Problem:
One of the problems I face is that the above-mentioned solutions are originally meant for C
and they generate a static file (*.o
) when compiled. On the other hand the simulation tool generates a shared library (.so
). I don't have much knowledge on lower level stuff so I seem to fail when I try linking them.
I looked specifically at the etrace
documentation, and it says:
To see how to modify ptrace.c to work with a dynamic library, look at the example2 directory. The sources there also create a stand-alone executable, but the PTRACE_REFERENCE_FUNCTION macro is defined just as it would be for a dynamic library.
If you look at the repo there is no difference between the files in example
and example2
folders. Only there is an extra .h
file in example2
.
On the other hand, if you look at src/ptrace.c
there it says:
When using ptrace on a dynamic library, you must set the PTRACE_REFERENCE_FUNCTION macro to be the name of a function in the library. The address of this function when loaded will be the first line output to the trace file and will permit the translation of the other entry and exit pointers to their symbolic names. You may set the macro PTRACE_INCLUDE with any #include directives needed for that function to be accesible to this source file.
a little below there is the commented code:
/* 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
`*/
Question:
In essence the question is the following: How to use etrace
with a dynamic library?
Do I need to #include any files?
To trace a stand-alone program, there is no need to #include any additional file. Just link your code against ptrace.c and use the -finstrument-functions option as a compile option for gcc. This should do it.
How do I link a C++ code which is built via makefiles against ptrace.c
Final Note: I would appreciate if someone bears with my ignorance and provides a step-by-step solution to my question.
Update 1:
I managed to add the libraries related to etrace to the simulation tool, and it executes fine.
However, (probably because the scripts are too old, or are not meant for use with C++) I get the following error when using the perl script provided by default by etrace
Hexadecimal number > 0xffffffff non-portable"
Probably this changes a bit the nature of this question, turning it more to a perl related issue at this point.
If this problem is solved, I hope etrace
will work with a complicated project and I will provide the details
Update 2:
I took the suggestions from @Harry, and I believe that would work in most projects. However in my case I get the following from the perl script:
Use of uninitialized value within %SYMBOLTABLE in list assignment at etrace2.pl line 99, <CALL_DATA> line 1.
\-- ???
| \-- ???
\-- ???
| \-- ???
| | \-- ???
\-- ???
| \-- ???
\-- ???
| \-- ???
\-- ???
| \-- ???
\-- ???
| \-- ???
\-- ???
| \-- ???
Due to autegenerated makefiles I used the LD_PRELOAD to load the shared library for etrace.so which I got as follows:
gcc -g -finstrument-functions -shared -fPIC ptrace.c -o etrace.so -I <path-to-etrace>
I created the dummy etrace.h inside the tool:
#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
and used Crumble_buy
for the #define
and the etrace.h
for the #include
.