- Notifications
You must be signed in to change notification settings - Fork1.1k
AddressSanitizerBasicBlockTracing
We want to get a complete trace of program execution as a sequence of basic block IDs.In general this task is quite challenging due to performance, IO, threads, memory consumption and what not.Here we describe a very simple and limited prototype of basic-blocktracer built into theSanitizer Coverage.
Usage:
clang++ -O1 -g -fsanitize=address -fsanitize-coverage=3 -mllvm -sanitizer-coverage-experimental-tracing your-app.ccASAN_OPTIONS=coverage=1 ./a.outThis will produce two files
trace-points.PID.sancovtrace-events.PID.sancovThe first file contains unique PCs executed by the application as text lines of the form "module_name offset".The second file is binary and contains the trace represented as a set of 4-byte indexes into the first file.
As we've said, the current implementation is a toy:
- not thread-safe
- not tuned for performance
- supports only relatively small traces
- uses 4 bytes per block (1 bit per edge is theoretically possible)
If you want something more robust come back later or wait forIntel's Processor Tracing
Here is a complete example of running the trace on a RE2 test:
mkdir tracing_examplecd tracing_examplecat << EOF > re2_hello_world.cc#include "re2/re2.h"#include <cassert>int main(int argc, char **argv) { assert(argc == 3); return RE2::PartialMatch(/*text*/argv[1], /*re=*/argv[2]);}EOFhg clone https://re2.googlecode.com/hg re2ASAN="-fsanitize=address" TRACE="-fsanitize-coverage=3 -mllvm -sanitizer-coverage-experimental-tracing"(cd re2 && CXX="clang++ $ASAN $TRACE" make -j)clang++ -fsanitize=address re2_hello_world.cc -Ire2 re2/obj/libre2.aASAN_OPTIONS=coverage=1:verbosity=1 ./a.out hello 'h.*o'# ==6102== CovDump: Trace: 1440 PCs written# ==6102== CovDump: Trace: 16834 Events writtenls -l trace-*sancov# -rw-r----- 1 xxx xxx 67336 Nov 18 16:38 trace-events.6102.sancov# -rw-r----- 1 xxx xxx 90720 Nov 18 16:38 trace-points.6102.sancovhead -n 5 trace-points.*.sancov# a.out 0x49ccb8# a.out 0x49cf45# a.out 0x49cf74# a.out 0x49d9b5wc -l trace-points.*sancov# 1440 trace-points.6102.sancovtrace-dump trace-points.*.sancov trace-events.*.sancov | head -n 5# a.out 0x49ccb8# a.out 0x49cf45# a.out 0x49cf74# a.out 0x49d9b5# a.out 0x49db50trace-dump trace-points.*.sancov trace-events.*.sancov | wc -l# 16834In case you want a simpletrace-dump utility:
#include <cassert>#include <iostream>#include <fstream>#include <vector>#include <string>int main(int argc, char **argv) { assert(argc == 3); std::string s; std::ifstream points(argv[1]); std::vector<std::string> p; while (std::getline(points, s)) p.push_back(s); unsigned e; std::ifstream events(argv[2], std::ios::in | std::ifstream::binary); while (events.read(reinterpret_cast<char *>(&e), sizeof(e))) std::cout << p[e] << std::endl;}