8

I would like to know if we can enable tracing in any C or C++ application.

For example, with a gcc option or a small tool, I will enable trace and either trace is printed on console or dumped to a file.

Since there are lots of files and function / classes, I don't want to start adding the trace prints manually.

If such tools are not available, next choice is use scripting and try to add at the trace printing.

strace is not much useful as it gives mainly the system calls.

unwind
  • 391,730
  • 64
  • 469
  • 606
hari
  • 1,419
  • 4
  • 19
  • 30
  • if this is just for a development environment you could compile compile everything with -g and run the programms inside of gdb. This will always give you a complete stack trace. – ftiaronsem Apr 28 '11 at 10:17
  • You might check the C++ interpreters... cint / ch / ...? Not sure what they can do, but they're more likely to do this than any compiler. FWIW, if you start looking at every line of trace, you're not far off using a debugger (except you've less control). – Tony Delroy Apr 28 '11 at 10:21
  • 2
    _What_ do you want to trace? There are about a million different answers, and a compiler cannot magically infer what you want traced. That makes it a lot harder to add traces automatically. – MSalters Apr 28 '11 at 11:36
  • Voting to close as too broad since it is not clear *what* OP wants to trace. More precise requests: source lines: http://stackoverflow.com/questions/764382/automate-tracing-in-gdb , function calls: http://stackoverflow.com/questions/311948/make-gdb-print-control-flow-of-functions-as-they-are-called , lines and data: http://stackoverflow.com/questions/763891/print-complete-control-flow-through-gdb – Ciro Santilli OurBigBook.com Jul 02 '15 at 19:30
  • Use tools provided by your fave CPU vendor. They are free and they leverage the hardware too keep your code working at a reasonable speed. You might want to investigate that. Both Intel and AMD have stuff available last I checked :) The trace capture is done by the CPU itself. No need to mess with any code! – Kuba hasn't forgotten Monica Oct 08 '21 at 18:08

6 Answers6

12

To trace the function entry/exit, you can recompile your code with the option -finstrument-functions so that each time a function is invoked, a __cyg_profile_func_enter() function is called, and __cyg_profile_func_exit() is called when the function returns.

You can implement those functions to trace the addresses on the called functions, and them use nm to convert the addresses into function names.

EDIT: etrace does all this: it provides the source code for the __cyg_profile_func_enter() and __cyg_profile_func_exit() and functions that write the addresses to a named pipe and a Perl and a Python script to read the addresses and do the actual tracing with the function names and indentation.

philant
  • 34,748
  • 11
  • 69
  • 112
  • For time being I had my own but a bit faster way of adding the print/entry point statement. I was able to do it with VIM script and shell script combination. Even though its not proper solution, but reduced my work by 90%. . First recorded macro in vim with source file to add entry point at start of every function (using '{{' ). Ran this macro for whole bunch of files using shell. This creates few issues like structures/class definitions etc etc in Source files. Also C functions should support declartion of variables at any point in the function. But it was 90% better as compared to manual:) – hari May 02 '11 at 04:10
4

For GCC, you could build with profiling support, and then run the program. That will create the gmon.out file, which in turn will contain a (sort of) trace of the functions executed by the program.

That will not even come close to the utility or ease of use of hand-written trace printf()s, though.

unwind
  • 391,730
  • 64
  • 469
  • 606
3

Since you were asking about gcc. It has the option -finstrument-functions that allows you to execute arbitrary code before and after calls to functions.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
0

I know you don't want to add something to each function, but if it's as simple as changing { to {_ does that win you over? A bit of scripting can do this automatically - ping me if you need that. If this does work, then look at this small utility I put together - just a single header file to include and then you get nice portable tracing

https://github.com/goblinhack/callstack

e.g.:

void my_function (void)
{_
  // rest of code
}

Call CALLSTACK_DUMP() at any time to dump the current callstack.

Just do

make
./callstack

Stack dump:
(stack) 1 main.cpp void foo3(int, int), line 7
(stack) 2 main.cpp void foo2(int), line 12
(stack) 3 main.cpp void foo1(), line 17
(stack) 4 main.cpp int main(int32_t, char **), line 22
TylerH
  • 20,799
  • 66
  • 75
  • 101
Goblinhack
  • 2,859
  • 1
  • 26
  • 26
0

USE Log4cxx.

This will log the details once you specify the file type,filename and file size in their configuration file.

Follow the steps to run the sample program.

karthik
  • 17,453
  • 70
  • 78
  • 122
  • Thanks - was not aware of this package; however, as I can see in https://logging.apache.org/log4cxx/usage.html, it simply defines new logging commands - and it is not capable of "automatic tracing" which is what this question was about. – sdaau Sep 30 '15 at 05:25
-1

If you don't want to modify all your printf() calls, I'd suggest doing something along those lines in a header file, and include it in all your C code files:

#ifndef DEBUG /* if not in debug mode, disable printf */
  #ifdef printf
    #undef printf
    #define printf(format, ...)
  #endif 
#endif

What's cool with that is that you can also replace printf with a logging function of your own:

#define printf(format, ...) my_log_function( format, ##__VA_ARGS__ )

Notice that I use here a nice macro trick: variadic macro.

Gui13
  • 12,993
  • 17
  • 57
  • 104
  • 1
    I dont have any printf in functions.. so I need to add it. Hence adding is the difficult part. – hari Apr 28 '11 at 10:55