How to do things AI Noob vs. Pro
List biggest files Free Open Source: Swiss File Knifea command line
Depeche View
command line
free external tools,
cpp sources
articles |
Are you still using printf in your C++ code?
Read how to replace this easily by logfile based tracing, using the free sfk micro tracing kernel for windows and linux.
Chapter 1: from printf to a simple logfile. This article expects that your code currently looks like in this example:
Now follow these steps:
Then adapt your code like in this example:
then extend this to
(Linux users type something like "g++-4.0 myprog.cpp mtk/mtktrace.cpp" instead).
By default, mtk tracing is not active, and must be activated through an environment variable:
Now, running the above sample program will create a file "log.txt" containing:
The characters at the beginning of each line are nesting level and message type - for our simple example, you can ignore them.
Chapter 2: simple program flow tracing, using manually inserted statements.
Let's have a look at a variation of above example:
so we see: the last line reached is number 7, just before the pointer write.
And when you found the bug, you can easily deactivate the "_" traces by changing the macro definition into:
which replaces "_" by nothing in the code.
Chapter 3: advanced program flow tracing, using source code instrumentation.
Let's have a true C++ example, with a hierarchy of methods calling each other:
WARNING: before you try the following on any of your existing source code, always create a backup! The modified source may be useful for a temporary debug session, but you may NOT want to continue working with it for all time.
On the command line, go into the root of your source code base, then say:
The sfk command for windows and linux is available here. All .cpp files will be processed ("instrumented"), and the sources will be modified like this:
The source code now contains Block Nesting Control. Now modify the MTK_TRACE setting like this:
Which means "trace tracing and block statements both into an internal ring buffer, and to file".
After the next test run, log.txt will look like this:
as you see, the output is now indented by the nesting level. the deeper the call stack is, the more the output is shifted to the right.
Limitations:
Please note that the "sfk inst" command is very selective about the syntax of the source code:
Chapter 4: ring buffers and on-demand stack traces
In the above example, we traced the program flow directly into a tracefile using
the "file:tb" option. Now let's change the setting a bit:
As you will see, the program flow is no longer traced into the trace file,
speeding up program execution significantly. But how do we see now
the flow of execution? We found out that the program crashes in myfunc2(), so we want to know how we got there. Do this by inserting a call before the critical line:
the mtkDumpStackTrace call simply reads out the internal ring buffer, which is still tracing the program flow ("ring:tb" option). what you now get is:
the difference is now that we dump the last steps of the program on demand, instead of permanent flow tracing.
besides mtkDumpStackTrace, which lists only the last _mtkb_ statements reached, there is also a method mtkDumpLastSteps, which dumps the last mtklog() statements which are also recorded in the ring buffer.
furthermore, mtkDumpStackTrace(0) or mtkDumpLastSteps(0) dumps the stack trace/last steps of ALL threads, not just of the current thread. this may create a rather long output (last steps by default lists up to 10000 records).
so much for this short introduction to mtk.
experienced developers will find out by themselves how this can be used,
for example, in combination with other tracing systems already present
in their source base. mtk is very low-level, low-overhead, and can be
used as a layer below anything else, to mix tracing statements
of different tracing systems back together.
NOTE:
|