This is a draft of a control flow tracer based on source code instrumentation with a low overhead.
Instrument your software with instrumenter.py. When running instrumented software, the trace is written into a file.
The format is basically one character (plus an optional number)
for each source code block on the trace.
For accurate retracing, retrace.py uses symbolic execution.
abstract_retrace.py is an experimental abstract retracing, using no
symbolic execution and just the AST from libclang parser.
Any software which is written in C/C++, with the source code available.
- python3
- libclang (
pip install libclang)
- C compiler (or your build system at choice) to compile the instrumented software
- C compiler (or your build system at choice) to compile the instrumented software
- python3
- angr for symbolic execution (
pip install angr)
- Run make
make - Install the python package
pip install .
-
Optionally: Change configuration in
include/src_tracer/constants.h. -
Load the environmental variables
source env.sh -
First run the pre-processor
cd examples/ cpp -I${SRC_TRACER_INCL} checksum.c -o checksum.i -
Instrument it (the pre-processed version)
instrumenter.py checksum.i -o checksum_inst.cFor a list of functions together with the
numgenerated by the instrumenter, have a look at the newly createdfunctions_database.db.
- Compile it with
_TRACE_MODEgcc -D_TRACE_MODE -L${SRC_TRACER_LIB} -I${SRC_TRACER_INCL} checksum_inst.c -o checksum_trace -lsrc_tracer- Note: you might want to use a diferent compiler like
clanginstead ofgcc - Note: you might also want compiler optimizations like
-O3for recording/replaying - Note: if you enabled
TRACEFORK_ZSTDininclude/src_tracer/constants.h, you would need-lzstdhere
- Note: you might want to use a diferent compiler like
- Run it (replace
42to get another trace)The name of the recorded trace corresponds to the current time, e.g../checksum_trace 422023-04-28-143402-checksum.c.trace. - Display the trace (replace the trace name with the correct one!)
print_trace.py 2023-04-28-143402-checksum.c.trace- Note: if you enabled
TRACEFORK_ZSTDininclude/src_tracer/constants.h, you would need to decompress the trace first usingzstd -d
- Note: if you enabled
- Compile it with
_RETRACE_MODE(you might also want different compiler optimizations for recording/replaying)gcc -D_RETRACE_MODE -g -I${SRC_TRACER_INCL} -L${SRC_TRACER_LIB} checksum_inst.c -o checksum_retrace -lsrc_tracer - Retrace it (use
python -ito work with the tracedstatein the interactive shell)The last one just retraces functionretrace.py checksum_retrace 2023-04-28-143402-checksum.c.trace echo "C1 IIO" > sub.trace.txt retrace.py checksum_retrace sub.trace.txtchecksum.
- For abstract retracing, you don't need to recompile. Make sure that you are in the folder of the database:
abstract_retrace.py 2023-04-28-143402-checksum.c.trace
You can do it manually as for the checksum.c example.
For a more automatic way that works well with make scripts, make use of cc_wrapper/ for the gcc compiler.
- Set some envirenmental variables.
This will set CC, CFLAGS and LIBS.
source gcc_env.sh - Now you can ./configure your project:
export SRC_TRACER="" ./configure - Before the actual compilation:
export SRC_TRACER="-D_TRACE_MODE" - Then build your project with
make,gccor similar. Example:gcc $CFLAGS checksum.c -o checksum_trace2 $LIBS - Traces will be stored in
~/.src_tracerby default!
- Same envirenmental variables as before.
- If you want to
./configureyour project again (e.g. with other options likeCFLAGSwith-g) make sure to setSRC_TRACER=""(as empty string) before you run./configure. - Before the actual compilation:
export SRC_TRACER="-D_RETRACE_MODE" - Then build your project with
make,gccor similar. Example:gcc $CFLAGS checksum.c -o checksum_retrace2 $LIBS
It can be a bit tricky to get the binary linking correctly, make sure that the record/replay executable includes the record/replay version of the app and its libraries.