Experiments with gcc auto instrumentration of C/C++ source code for run-time function call tree tracing... a working example!
- In the original experiments [1] we managed to auto instrument C but not C++ via auto generating a wrapper function for every real function to be instrumented. However, this method does not lend itself well to C++, for example, it does not seem possible to double the number of functions in a class without modifying the class source code in place, thus displacing the original source lines.
- In the further experiments [2] it was possible to auto instrument both C and C++ via the somewhat brittle
CastXML
mechanism. While this method works,CastXML
is not very refined and somewhat slow, making this mechanism a little heavyweight. Also, it relies on the attribute cleanup mechanism too, which isn't the fastest if the instrumentation for a particular function is disabled. - In this working example below we show a new mechanism (but also using some elements of both previous experiments) with the following advantages:
- Each function instrumented gets its own individually addressable verbosity, e.g. 80,000 instrumented functions means 80,000 individually addressable function verbosities.
- Both the global verbosity and function verbosity can be dynamically manipulated at run-time to produce any desired level of verbosity, but limited to the precise area of source code under investigation.
- The overhead of disabled instrumentation at run-time is essentially the overhead of an inline
if(verbosity >= function_verbosity){...}
statement. - The gcc
-finstrument-functions
switch is used to identify function enter and leave points, which is faster, less brittle, and more lightweight than usingCastXML
. - By compiling C/C++ to assembler to object, the assembler can be modified to add an
if()
clause around the__cyg_profile_func_(enter|exit)
calls. - The C++ managled function name -- not available in C++, but available in assembler -- e.g.
_ZN3FooC2EPKc
is unique and can be used to create a unique data block for each instrumented function, e.g.cwrap_data__ZN3FooC2EPKc
. - Other non-enter, non-leave instrumentation can also have the
if()
clause, and the C++ mangled function name is determined automatically using the C++__PRETTY_FUNCTION__
macro which is the demangled form of the mangled function name.
The disadvantage of this mechanism is that it currently only works with gcc (although clang should work but is untested) and Intel assembler (although other assemblers can be supported in the future).
[1] Original auto instrumentation experiments [2] Further auto instrumentation experiments [3] gcc -finstrument-functions
The following steps are used to automatically instrument a C/C++ project:
- The project
makefile
is run withCC
pointing tocwrap.pl
. cwrap.pl
is invoked whenevergcc
is normally invoked bymake
.cwrap.pl
modifies the command line to add-finstrument-functions
[1], and also-S
[2] to compile to assembler.--include cwrap.h
is also added to the command line.cwrap.pl
executesgcc
with the modified command line, generating the assembler output.cwrap.pl
modifies the output assembler adding and/or modifying theif()
statements as necessary.cwrap.pl
executesgcc
again, on the modified assembler, assembling to the object file(s).- These steps are repeated for all compiled C/C++ files.
- Upon linking
cwrap.pl
collects the nundefined reference
errors for all the undefined function structs (try to use the very fastnm
, or falling back to the much slowergcc
linker if necessary). cwrap.pl
generatescwrap.c
on-the-fly with all necessary function structs.cwrap.pl
executesgcc
to link against the newly compiledcwrap.c
.
[1] gcc -finstrument-functions [2] gcc -S
- The assembler produced by the C and C++ compilers -- even on the same source code -- can produce a slightly different format assembler output.
- Differing levels of optimization can cause different assembler to be generated for
__cyg_profile_func_(enter|exit)
calls. Therefore, automated tests were created which test with-O0
,-O1
,-O2
, and-O3
for both C and C++. There seem to be two different patterns used by the compiler to generate assembler; one regular pattern, and one pattern used for sometimes optimizing inline function calls. Testing needs to be done on larger code bases. - C++ template functions needed special treatment because
__PRETTY_FUNCTION__
and internal assembler representation unexpectedly differ, e.g.int get_max<int>(int, int)
versusmy_type get_max(my_type, my_type) [with my_type = int]
. - Created a special output mode called 'curt' which compacts the number of instrumented output lines greatly for enhanced human readability. However, due to limitations with the instrumentation mechanism, it wasn't possible to make the curt output perfect.
- Could not find a demangling library or utility that 'just works' and existing tools disagree demangled output [1].
- Some demangled names can be 100s of KB long e.g. due to very many nested templates, so these names are 'skeletonized' to form a non-unique demangled name.
- The number of variants of non-unique skeletonized names are tracked.
[1] https://gist.github.com/simonhf/0d60bb94f2d90c1b32e4786b2d1062ad
- Create a smaller piece of source code which uses most types of instrumentable language features and which can be compiled either as C (with only a subset of functionality, e.g. C has no 'classes') or C++.
- Create two sets of makefiles; one compiles and links everything with one command line, and one compiles and links everything on separate command lines.
- Compile all variations of C or C++, 1 or n line makefile, no or curt or long instrumentation, and all levels of compiler optimation.
- Check that inline function special case happened during at least one tested project compilation.
- Test the demangled name skelotonization code with some different cases.
$ time perl cwrap-test.pl
- test: strategy: build common source code in all combinations of C / C++, without / with curt / with long cwrap, few / many gcc commands, O0 / 1 / 2 / 3 gcc optimization
- test: wiping folder: build/
- test: running: cd build ; make -j 2>&1
> cd language-c---example-1-cwrap-exclude------make-via-1-line-opt-O0 ; (time make -f c---example-1.via-1-line.mak OPT="-O0") > build.log 2>&1
> cd language-c---example-1-cwrap-exclude------make-via-1-line-opt-O1 ; (time make -f c---example-1.via-1-line.mak OPT="-O1") > build.log 2>&1
> cd language-c---example-1-cwrap-exclude------make-via-1-line-opt-O2 ; (time make -f c---example-1.via-1-line.mak OPT="-O2") > build.log 2>&1
> cd language-c---example-1-cwrap-exclude------make-via-1-line-opt-O3 ; (time make -f c---example-1.via-1-line.mak OPT="-O3") > build.log 2>&1
> cd language-c---example-1-cwrap-exclude------make-via-n-line-opt-O0 ; (time make -f c---example-1.via-n-line.mak OPT="-O0") > build.log 2>&1
> cd language-c---example-1-cwrap-exclude------make-via-n-line-opt-O1 ; (time make -f c---example-1.via-n-line.mak OPT="-O1") > build.log 2>&1
> cd language-c---example-1-cwrap-exclude------make-via-n-line-opt-O2 ; (time make -f c---example-1.via-n-line.mak OPT="-O2") > build.log 2>&1
> cd language-c---example-1-cwrap-exclude------make-via-n-line-opt-O3 ; (time make -f c---example-1.via-n-line.mak OPT="-O3") > build.log 2>&1
> cd language-c---example-1-cwrap-include-curt-make-via-1-line-opt-O0 ; (time make -f c---example-1.via-1-line.mak OPT="-O0" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=1") > build.log 2>&1
> cd language-c---example-1-cwrap-include-curt-make-via-1-line-opt-O1 ; (time make -f c---example-1.via-1-line.mak OPT="-O1" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=1") > build.log 2>&1
> cd language-c---example-1-cwrap-include-curt-make-via-1-line-opt-O2 ; (time make -f c---example-1.via-1-line.mak OPT="-O2" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=1") > build.log 2>&1
> cd language-c---example-1-cwrap-include-curt-make-via-1-line-opt-O3 ; (time make -f c---example-1.via-1-line.mak OPT="-O3" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=1") > build.log 2>&1
> cd language-c---example-1-cwrap-include-curt-make-via-n-line-opt-O0 ; (time make -f c---example-1.via-n-line.mak OPT="-O0" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=1") > build.log 2>&1
> cd language-c---example-1-cwrap-include-curt-make-via-n-line-opt-O1 ; (time make -f c---example-1.via-n-line.mak OPT="-O1" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=1") > build.log 2>&1
> cd language-c---example-1-cwrap-include-curt-make-via-n-line-opt-O2 ; (time make -f c---example-1.via-n-line.mak OPT="-O2" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=1") > build.log 2>&1
> cd language-c---example-1-cwrap-include-curt-make-via-n-line-opt-O3 ; (time make -f c---example-1.via-n-line.mak OPT="-O3" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=1") > build.log 2>&1
> cd language-c---example-1-cwrap-include-long-make-via-1-line-opt-O0 ; (time make -f c---example-1.via-1-line.mak OPT="-O0" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=0") > build.log 2>&1
> cd language-c---example-1-cwrap-include-long-make-via-1-line-opt-O1 ; (time make -f c---example-1.via-1-line.mak OPT="-O1" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=0") > build.log 2>&1
> cd language-c---example-1-cwrap-include-long-make-via-1-line-opt-O2 ; (time make -f c---example-1.via-1-line.mak OPT="-O2" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=0") > build.log 2>&1
> cd language-c---example-1-cwrap-include-long-make-via-1-line-opt-O3 ; (time make -f c---example-1.via-1-line.mak OPT="-O3" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=0") > build.log 2>&1
> cd language-c---example-1-cwrap-include-long-make-via-n-line-opt-O0 ; (time make -f c---example-1.via-n-line.mak OPT="-O0" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=0") > build.log 2>&1
> cd language-c---example-1-cwrap-include-long-make-via-n-line-opt-O1 ; (time make -f c---example-1.via-n-line.mak OPT="-O1" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=0") > build.log 2>&1
> cd language-c---example-1-cwrap-include-long-make-via-n-line-opt-O2 ; (time make -f c---example-1.via-n-line.mak OPT="-O2" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=0") > build.log 2>&1
> cd language-c---example-1-cwrap-include-long-make-via-n-line-opt-O3 ; (time make -f c---example-1.via-n-line.mak OPT="-O3" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=0") > build.log 2>&1
> cd language-cpp-example-1-cwrap-exclude------make-via-1-line-opt-O0 ; (time make -f cpp-example-1.via-1-line.mak OPT="-O0") > build.log 2>&1
> cd language-cpp-example-1-cwrap-exclude------make-via-1-line-opt-O1 ; (time make -f cpp-example-1.via-1-line.mak OPT="-O1") > build.log 2>&1
> cd language-cpp-example-1-cwrap-exclude------make-via-1-line-opt-O2 ; (time make -f cpp-example-1.via-1-line.mak OPT="-O2") > build.log 2>&1
> cd language-cpp-example-1-cwrap-exclude------make-via-1-line-opt-O3 ; (time make -f cpp-example-1.via-1-line.mak OPT="-O3") > build.log 2>&1
> cd language-cpp-example-1-cwrap-exclude------make-via-n-line-opt-O0 ; (time make -f cpp-example-1.via-n-line.mak OPT="-O0") > build.log 2>&1
> cd language-cpp-example-1-cwrap-exclude------make-via-n-line-opt-O1 ; (time make -f cpp-example-1.via-n-line.mak OPT="-O1") > build.log 2>&1
> cd language-cpp-example-1-cwrap-exclude------make-via-n-line-opt-O2 ; (time make -f cpp-example-1.via-n-line.mak OPT="-O2") > build.log 2>&1
> cd language-cpp-example-1-cwrap-exclude------make-via-n-line-opt-O3 ; (time make -f cpp-example-1.via-n-line.mak OPT="-O3") > build.log 2>&1
> cd language-cpp-example-1-cwrap-include-curt-make-via-1-line-opt-O0 ; (time make -f cpp-example-1.via-1-line.mak OPT="-O0" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=1") > build.log 2>&1
> cd language-cpp-example-1-cwrap-include-curt-make-via-1-line-opt-O1 ; (time make -f cpp-example-1.via-1-line.mak OPT="-O1" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=1") > build.log 2>&1
> cd language-cpp-example-1-cwrap-include-curt-make-via-1-line-opt-O2 ; (time make -f cpp-example-1.via-1-line.mak OPT="-O2" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=1") > build.log 2>&1
> cd language-cpp-example-1-cwrap-include-curt-make-via-1-line-opt-O3 ; (time make -f cpp-example-1.via-1-line.mak OPT="-O3" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=1") > build.log 2>&1
> cd language-cpp-example-1-cwrap-include-curt-make-via-n-line-opt-O0 ; (time make -f cpp-example-1.via-n-line.mak OPT="-O0" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=1") > build.log 2>&1
> cd language-cpp-example-1-cwrap-include-curt-make-via-n-line-opt-O1 ; (time make -f cpp-example-1.via-n-line.mak OPT="-O1" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=1") > build.log 2>&1
> cd language-cpp-example-1-cwrap-include-curt-make-via-n-line-opt-O2 ; (time make -f cpp-example-1.via-n-line.mak OPT="-O2" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=1") > build.log 2>&1
> cd language-cpp-example-1-cwrap-include-curt-make-via-n-line-opt-O3 ; (time make -f cpp-example-1.via-n-line.mak OPT="-O3" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=1") > build.log 2>&1
> cd language-cpp-example-1-cwrap-include-long-make-via-1-line-opt-O0 ; (time make -f cpp-example-1.via-1-line.mak OPT="-O0" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=0") > build.log 2>&1
> cd language-cpp-example-1-cwrap-include-long-make-via-1-line-opt-O1 ; (time make -f cpp-example-1.via-1-line.mak OPT="-O1" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=0") > build.log 2>&1
> cd language-cpp-example-1-cwrap-include-long-make-via-1-line-opt-O2 ; (time make -f cpp-example-1.via-1-line.mak OPT="-O2" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=0") > build.log 2>&1
> cd language-cpp-example-1-cwrap-include-long-make-via-1-line-opt-O3 ; (time make -f cpp-example-1.via-1-line.mak OPT="-O3" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=0") > build.log 2>&1
> cd language-cpp-example-1-cwrap-include-long-make-via-n-line-opt-O0 ; (time make -f cpp-example-1.via-n-line.mak OPT="-O0" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=0") > build.log 2>&1
> cd language-cpp-example-1-cwrap-include-long-make-via-n-line-opt-O1 ; (time make -f cpp-example-1.via-n-line.mak OPT="-O1" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=0") > build.log 2>&1
> cd language-cpp-example-1-cwrap-include-long-make-via-n-line-opt-O2 ; (time make -f cpp-example-1.via-n-line.mak OPT="-O2" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=0") > build.log 2>&1
> cd language-cpp-example-1-cwrap-include-long-make-via-n-line-opt-O3 ; (time make -f cpp-example-1.via-n-line.mak OPT="-O3" CC="perl ../../cwrap.pl -DCWRAP_LOG_CURT=0") > build.log 2>&1
ok 1 - test: build/language-c---example-1-cwrap-exclude------make-via-1-line-opt-O0
ok 2 - test: build/language-c---example-1-cwrap-exclude------make-via-1-line-opt-O1
ok 3 - test: build/language-c---example-1-cwrap-exclude------make-via-1-line-opt-O2
ok 4 - test: build/language-c---example-1-cwrap-exclude------make-via-1-line-opt-O3
ok 5 - test: build/language-c---example-1-cwrap-exclude------make-via-n-line-opt-O0
ok 6 - test: build/language-c---example-1-cwrap-exclude------make-via-n-line-opt-O1
ok 7 - test: build/language-c---example-1-cwrap-exclude------make-via-n-line-opt-O2
ok 8 - test: build/language-c---example-1-cwrap-exclude------make-via-n-line-opt-O3
ok 9 - test: build/language-c---example-1-cwrap-include-curt-make-via-1-line-opt-O0
ok 10 - test: build/language-c---example-1-cwrap-include-curt-make-via-1-line-opt-O1
ok 11 - test: build/language-c---example-1-cwrap-include-curt-make-via-1-line-opt-O2
ok 12 - test: build/language-c---example-1-cwrap-include-curt-make-via-1-line-opt-O3
ok 13 - test: build/language-c---example-1-cwrap-include-curt-make-via-n-line-opt-O0
ok 14 - test: build/language-c---example-1-cwrap-include-curt-make-via-n-line-opt-O1
ok 15 - test: build/language-c---example-1-cwrap-include-curt-make-via-n-line-opt-O2
ok 16 - test: build/language-c---example-1-cwrap-include-curt-make-via-n-line-opt-O3
ok 17 - test: build/language-c---example-1-cwrap-include-long-make-via-1-line-opt-O0
ok 18 - test: build/language-c---example-1-cwrap-include-long-make-via-1-line-opt-O1
ok 19 - test: build/language-c---example-1-cwrap-include-long-make-via-1-line-opt-O2
ok 20 - test: build/language-c---example-1-cwrap-include-long-make-via-1-line-opt-O3
ok 21 - test: build/language-c---example-1-cwrap-include-long-make-via-n-line-opt-O0
ok 22 - test: build/language-c---example-1-cwrap-include-long-make-via-n-line-opt-O1
ok 23 - test: build/language-c---example-1-cwrap-include-long-make-via-n-line-opt-O2
ok 24 - test: build/language-c---example-1-cwrap-include-long-make-via-n-line-opt-O3
ok 25 - test: build/language-cpp-example-1-cwrap-exclude------make-via-1-line-opt-O0
ok 26 - test: build/language-cpp-example-1-cwrap-exclude------make-via-1-line-opt-O1
ok 27 - test: build/language-cpp-example-1-cwrap-exclude------make-via-1-line-opt-O2
ok 28 - test: build/language-cpp-example-1-cwrap-exclude------make-via-1-line-opt-O3
ok 29 - test: build/language-cpp-example-1-cwrap-exclude------make-via-n-line-opt-O0
ok 30 - test: build/language-cpp-example-1-cwrap-exclude------make-via-n-line-opt-O1
ok 31 - test: build/language-cpp-example-1-cwrap-exclude------make-via-n-line-opt-O2
ok 32 - test: build/language-cpp-example-1-cwrap-exclude------make-via-n-line-opt-O3
ok 33 - test: build/language-cpp-example-1-cwrap-include-curt-make-via-1-line-opt-O0
ok 34 - test: build/language-cpp-example-1-cwrap-include-curt-make-via-1-line-opt-O1
ok 35 - test: build/language-cpp-example-1-cwrap-include-curt-make-via-1-line-opt-O2
ok 36 - test: build/language-cpp-example-1-cwrap-include-curt-make-via-1-line-opt-O3
ok 37 - test: build/language-cpp-example-1-cwrap-include-curt-make-via-n-line-opt-O0
ok 38 - test: build/language-cpp-example-1-cwrap-include-curt-make-via-n-line-opt-O1
ok 39 - test: build/language-cpp-example-1-cwrap-include-curt-make-via-n-line-opt-O2
ok 40 - test: build/language-cpp-example-1-cwrap-include-curt-make-via-n-line-opt-O3
ok 41 - test: build/language-cpp-example-1-cwrap-include-long-make-via-1-line-opt-O0
ok 42 - test: build/language-cpp-example-1-cwrap-include-long-make-via-1-line-opt-O1
ok 43 - test: build/language-cpp-example-1-cwrap-include-long-make-via-1-line-opt-O2
ok 44 - test: build/language-cpp-example-1-cwrap-include-long-make-via-1-line-opt-O3
ok 45 - test: build/language-cpp-example-1-cwrap-include-long-make-via-n-line-opt-O0
ok 46 - test: build/language-cpp-example-1-cwrap-include-long-make-via-n-line-opt-O1
ok 47 - test: build/language-cpp-example-1-cwrap-include-long-make-via-n-line-opt-O2
ok 48 - test: build/language-cpp-example-1-cwrap-include-long-make-via-n-line-opt-O3
ok 49 - test: as expected, at least one build has 'movq cwrap_data_.*, %rxx' where rxx is not rdi
ok 50 - test: compressed 100 bytes unique demangled name to expected 23 bytes non-unique name: (&std::forward<>()) [9]
ok 51 - test: compressed 109 bytes unique demangled name to expected 58 bytes non-unique name: caf::data_processor<>::apply()::{unnamed-type}::operator()
ok 52 - test: compressed 130 bytes unique demangled name to expected 32 bytes non-unique name: (*std::_Any_data::_M_access<>())
ok 53 - test: compressed 138 bytes unique demangled name to expected 13 bytes non-unique name: delete_each<>
ok 54 - test: compressed 175 bytes unique demangled name to expected 37 bytes non-unique name: caf::detail::tuple_inspect_delegate<>
ok 55 - test: compressed 178 bytes unique demangled name to expected 19 bytes non-unique name: (&std::forward<>())
ok 56 - test: compressed 299 bytes unique demangled name to expected 41 bytes non-unique name: caf::(anonymous-namespace)::fill_builtins
ok 57 - test: compressed 490 bytes unique demangled name to expected 70 bytes non-unique name: broker::core_actor()::{lambda()}::operator()()::{lambda()}::operator()
ok 58 - test: compressed 573 bytes unique demangled name to expected 60 bytes non-unique name: broker::detail::network_cache::fetch<>()::{lambda()}::~fetch
ok 59 - test: compressed 773 bytes unique demangled name to expected 16 bytes non-unique name: std::transform<>
ok 60 - test: compressed 1542 bytes unique demangled name to expected 42 bytes non-unique name: std::caf::default_sum_type_access<>::get<>
ok 61 - test: compressed 1944 bytes unique demangled name to expected 23 bytes non-unique name: std::forward_as_tuple<>
ok 62 - test: compressed 6200 bytes unique demangled name to expected 136 bytes non-unique name: caf::io::middleman::remote_group()::{lambda()}::operator()()::{lambda()}::operator()()::{lambda()}::operator()()::{lambda()}::operator()
ok 63 - test: compressed 6793 bytes unique demangled name to expected 33 bytes non-unique name: std::_Tuple_impl<>::_Tuple_impl<>
1..63
real 0m2.223s
- For C, executable size without instrumentation ranges from 22,368 to 32,328 bytes.
- For C, executable size with curt instrumentation ranges from 49,960 to 68,008 bytes.
- For C, executable size with long instrumentation ranges from 49,952 to 68,008 bytes.
- For C++, executable size without instrumentation ranges from 30,080 to 42,992 bytes.
- For C++, executable size with curt instrumentation ranges from 64,376 to 104,984 bytes.
- For C++, executable size with long instrumentation ranges from 64,376 to 104,984 bytes.
- Whether C or C++, and compiling with instrumentation, compiling n gcc command lines always results in a larger executable than compiling the same code with 1 gcc comand line. Not sure why.
$ find build/ -type f | egrep exe | sort | xargs wc --bytes
22360 build/language-c---example-1-cwrap-exclude------make-via-1-line-opt-O0/c---example-1.via-1-line.exe
28616 build/language-c---example-1-cwrap-exclude------make-via-1-line-opt-O1/c---example-1.via-1-line.exe
29328 build/language-c---example-1-cwrap-exclude------make-via-1-line-opt-O2/c---example-1.via-1-line.exe
32320 build/language-c---example-1-cwrap-exclude------make-via-1-line-opt-O3/c---example-1.via-1-line.exe
22360 build/language-c---example-1-cwrap-exclude------make-via-n-line-opt-O0/c---example-1.via-n-line.exe
28616 build/language-c---example-1-cwrap-exclude------make-via-n-line-opt-O1/c---example-1.via-n-line.exe
29328 build/language-c---example-1-cwrap-exclude------make-via-n-line-opt-O2/c---example-1.via-n-line.exe
32320 build/language-c---example-1-cwrap-exclude------make-via-n-line-opt-O3/c---example-1.via-n-line.exe
49960 build/language-c---example-1-cwrap-include-curt-make-via-1-line-opt-O0/c---example-1.via-1-line.exe
67600 build/language-c---example-1-cwrap-include-curt-make-via-1-line-opt-O1/c---example-1.via-1-line.exe
68000 build/language-c---example-1-cwrap-include-curt-make-via-1-line-opt-O2/c---example-1.via-1-line.exe
68008 build/language-c---example-1-cwrap-include-curt-make-via-1-line-opt-O3/c---example-1.via-1-line.exe
49952 build/language-c---example-1-cwrap-include-curt-make-via-n-line-opt-O0/c---example-1.via-n-line.exe
55616 build/language-c---example-1-cwrap-include-curt-make-via-n-line-opt-O1/c---example-1.via-n-line.exe
55728 build/language-c---example-1-cwrap-include-curt-make-via-n-line-opt-O2/c---example-1.via-n-line.exe
55736 build/language-c---example-1-cwrap-include-curt-make-via-n-line-opt-O3/c---example-1.via-n-line.exe
49960 build/language-c---example-1-cwrap-include-long-make-via-1-line-opt-O0/c---example-1.via-1-line.exe
67600 build/language-c---example-1-cwrap-include-long-make-via-1-line-opt-O1/c---example-1.via-1-line.exe
68000 build/language-c---example-1-cwrap-include-long-make-via-1-line-opt-O2/c---example-1.via-1-line.exe
68008 build/language-c---example-1-cwrap-include-long-make-via-1-line-opt-O3/c---example-1.via-1-line.exe
49952 build/language-c---example-1-cwrap-include-long-make-via-n-line-opt-O0/c---example-1.via-n-line.exe
55616 build/language-c---example-1-cwrap-include-long-make-via-n-line-opt-O1/c---example-1.via-n-line.exe
55728 build/language-c---example-1-cwrap-include-long-make-via-n-line-opt-O2/c---example-1.via-n-line.exe
55736 build/language-c---example-1-cwrap-include-long-make-via-n-line-opt-O3/c---example-1.via-n-line.exe
30080 build/language-cpp-example-1-cwrap-exclude------make-via-1-line-opt-O0/cpp-example-1.via-1-line.exe
41208 build/language-cpp-example-1-cwrap-exclude------make-via-1-line-opt-O1/cpp-example-1.via-1-line.exe
42360 build/language-cpp-example-1-cwrap-exclude------make-via-1-line-opt-O2/cpp-example-1.via-1-line.exe
42992 build/language-cpp-example-1-cwrap-exclude------make-via-1-line-opt-O3/cpp-example-1.via-1-line.exe
30080 build/language-cpp-example-1-cwrap-exclude------make-via-n-line-opt-O0/cpp-example-1.via-n-line.exe
41208 build/language-cpp-example-1-cwrap-exclude------make-via-n-line-opt-O1/cpp-example-1.via-n-line.exe
42360 build/language-cpp-example-1-cwrap-exclude------make-via-n-line-opt-O2/cpp-example-1.via-n-line.exe
42992 build/language-cpp-example-1-cwrap-exclude------make-via-n-line-opt-O3/cpp-example-1.via-n-line.exe
71992 build/language-cpp-example-1-cwrap-include-curt-make-via-1-line-opt-O0/cpp-example-1.via-1-line.exe
103512 build/language-cpp-example-1-cwrap-include-curt-make-via-1-line-opt-O1/cpp-example-1.via-1-line.exe
104984 build/language-cpp-example-1-cwrap-include-curt-make-via-1-line-opt-O2/cpp-example-1.via-1-line.exe
104984 build/language-cpp-example-1-cwrap-include-curt-make-via-1-line-opt-O3/cpp-example-1.via-1-line.exe
64376 build/language-cpp-example-1-cwrap-include-curt-make-via-n-line-opt-O0/cpp-example-1.via-n-line.exe
83888 build/language-cpp-example-1-cwrap-include-curt-make-via-n-line-opt-O1/cpp-example-1.via-n-line.exe
85216 build/language-cpp-example-1-cwrap-include-curt-make-via-n-line-opt-O2/cpp-example-1.via-n-line.exe
85216 build/language-cpp-example-1-cwrap-include-curt-make-via-n-line-opt-O3/cpp-example-1.via-n-line.exe
71992 build/language-cpp-example-1-cwrap-include-long-make-via-1-line-opt-O0/cpp-example-1.via-1-line.exe
103512 build/language-cpp-example-1-cwrap-include-long-make-via-1-line-opt-O1/cpp-example-1.via-1-line.exe
104984 build/language-cpp-example-1-cwrap-include-long-make-via-1-line-opt-O2/cpp-example-1.via-1-line.exe
104984 build/language-cpp-example-1-cwrap-include-long-make-via-1-line-opt-O3/cpp-example-1.via-1-line.exe
64376 build/language-cpp-example-1-cwrap-include-long-make-via-n-line-opt-O0/cpp-example-1.via-n-line.exe
83888 build/language-cpp-example-1-cwrap-include-long-make-via-n-line-opt-O1/cpp-example-1.via-n-line.exe
85216 build/language-cpp-example-1-cwrap-include-long-make-via-n-line-opt-O2/cpp-example-1.via-n-line.exe
85216 build/language-cpp-example-1-cwrap-include-long-make-via-n-line-opt-O3/cpp-example-1.via-n-line.exe
- Long auto instrumentation produces output which is about twice the number of lines whether C or C++.
- I.e. C without instrumentation is 40 lines, and with long instrumentation is 76 lines.
- I.e. C++ without instrumentation is 64 lines, and with long instrumentation is 132 lines.
- Interestingly the 'curt' instrumentation example produces less output lines than non-instrumented!
- I.e. C without instrumentation is 40 lines, and with curt instrumentation is 40 lines.
- I.e. C++ without instrumentation is 64 lines, and with long instrumentation is 58 lines.
$ find build/ -type f | egrep run | sort | xargs -n 1 perl -e '$f=$ARGV[0]; @l=`cat $f | egrep -v "(call.s. to|verbosity|cwrap_log_)"`; printf qq[%3d %s\n], scalar @l, $f;'
40 build/language-c---example-1-cwrap-exclude------make-via-1-line-opt-O0/run.log
40 build/language-c---example-1-cwrap-exclude------make-via-1-line-opt-O1/run.log
40 build/language-c---example-1-cwrap-exclude------make-via-1-line-opt-O2/run.log
40 build/language-c---example-1-cwrap-exclude------make-via-1-line-opt-O3/run.log
40 build/language-c---example-1-cwrap-exclude------make-via-n-line-opt-O0/run.log
40 build/language-c---example-1-cwrap-exclude------make-via-n-line-opt-O1/run.log
40 build/language-c---example-1-cwrap-exclude------make-via-n-line-opt-O2/run.log
40 build/language-c---example-1-cwrap-exclude------make-via-n-line-opt-O3/run.log
41 build/language-c---example-1-cwrap-include-curt-make-via-1-line-opt-O0/run.log
41 build/language-c---example-1-cwrap-include-curt-make-via-1-line-opt-O1/run.log
41 build/language-c---example-1-cwrap-include-curt-make-via-1-line-opt-O2/run.log
41 build/language-c---example-1-cwrap-include-curt-make-via-1-line-opt-O3/run.log
41 build/language-c---example-1-cwrap-include-curt-make-via-n-line-opt-O0/run.log
41 build/language-c---example-1-cwrap-include-curt-make-via-n-line-opt-O1/run.log
41 build/language-c---example-1-cwrap-include-curt-make-via-n-line-opt-O2/run.log
41 build/language-c---example-1-cwrap-include-curt-make-via-n-line-opt-O3/run.log
87 build/language-c---example-1-cwrap-include-long-make-via-1-line-opt-O0/run.log
87 build/language-c---example-1-cwrap-include-long-make-via-1-line-opt-O1/run.log
87 build/language-c---example-1-cwrap-include-long-make-via-1-line-opt-O2/run.log
87 build/language-c---example-1-cwrap-include-long-make-via-1-line-opt-O3/run.log
87 build/language-c---example-1-cwrap-include-long-make-via-n-line-opt-O0/run.log
87 build/language-c---example-1-cwrap-include-long-make-via-n-line-opt-O1/run.log
87 build/language-c---example-1-cwrap-include-long-make-via-n-line-opt-O2/run.log
87 build/language-c---example-1-cwrap-include-long-make-via-n-line-opt-O3/run.log
67 build/language-cpp-example-1-cwrap-exclude------make-via-1-line-opt-O0/run.log
67 build/language-cpp-example-1-cwrap-exclude------make-via-1-line-opt-O1/run.log
67 build/language-cpp-example-1-cwrap-exclude------make-via-1-line-opt-O2/run.log
67 build/language-cpp-example-1-cwrap-exclude------make-via-1-line-opt-O3/run.log
67 build/language-cpp-example-1-cwrap-exclude------make-via-n-line-opt-O0/run.log
67 build/language-cpp-example-1-cwrap-exclude------make-via-n-line-opt-O1/run.log
67 build/language-cpp-example-1-cwrap-exclude------make-via-n-line-opt-O2/run.log
67 build/language-cpp-example-1-cwrap-exclude------make-via-n-line-opt-O3/run.log
85 build/language-cpp-example-1-cwrap-include-curt-make-via-1-line-opt-O0/run.log
85 build/language-cpp-example-1-cwrap-include-curt-make-via-1-line-opt-O1/run.log
85 build/language-cpp-example-1-cwrap-include-curt-make-via-1-line-opt-O2/run.log
85 build/language-cpp-example-1-cwrap-include-curt-make-via-1-line-opt-O3/run.log
85 build/language-cpp-example-1-cwrap-include-curt-make-via-n-line-opt-O0/run.log
85 build/language-cpp-example-1-cwrap-include-curt-make-via-n-line-opt-O1/run.log
85 build/language-cpp-example-1-cwrap-include-curt-make-via-n-line-opt-O2/run.log
85 build/language-cpp-example-1-cwrap-include-curt-make-via-n-line-opt-O3/run.log
164 build/language-cpp-example-1-cwrap-include-long-make-via-1-line-opt-O0/run.log
164 build/language-cpp-example-1-cwrap-include-long-make-via-1-line-opt-O1/run.log
164 build/language-cpp-example-1-cwrap-include-long-make-via-1-line-opt-O2/run.log
164 build/language-cpp-example-1-cwrap-include-long-make-via-1-line-opt-O3/run.log
164 build/language-cpp-example-1-cwrap-include-long-make-via-n-line-opt-O0/run.log
164 build/language-cpp-example-1-cwrap-include-long-make-via-n-line-opt-O1/run.log
164 build/language-cpp-example-1-cwrap-include-long-make-via-n-line-opt-O2/run.log
164 build/language-cpp-example-1-cwrap-include-long-make-via-n-line-opt-O3/run.log
- There are already some 64
printf()
statements in the code which give hints as to what is happening at run-time:
$ cat build/language-cpp-example-1-cwrap-exclude------make-via-n-line-opt-O0/run.log
arg1=my_struct_1
constructing my_struct
arg1=my_struct_2
constructing my_struct
r=2
r=3
r=4
a=0
a=1
r=2
r=2
a=1
a=2
r=3
r=3
a=2
a=3
r=4
r=4
hello world
a=1
r=2
a=12345, b=67890
r=67890
a=43, b=21
r=43
arg1=my_struct_2
constructing my_struct
arg1=my_struct_3, arg2=a
constructing my_struct
constructing Foo
inside Foo
arg1=my_struct_3, arg2=b
constructing my_struct
constructing Foo
inside Foo
a=100
hello my_public
a=101
a=102
a=103
r=104
r=104
r=104
r=104
a=104
a=105
r=106
r=106
b=106
deconstructing Foo
inside ~Foo
deconstructing my_struct
deconstructing Foo
inside ~Foo
deconstructing my_struct
deconstructing my_struct
my_int=5
called via atexit() via baz()
called via atexit() via baz()
called via atexit() via baz()
called via atexit() via main()
called via atexit() via baz()
called via atexit() via baz()
called via atexit() via baz()
deconstructing my_struct
deconstructing my_struct
- The existing 64
printf()
statements mixed with the auto instrumentation output curt results in 58 output lines excluding thecwrap_log_verbosity_set()
andcwrap_log_stats()
functions. cwrap_log_verbosity_set()
is an example of how the individual verbosity of a function can be manipulated at run-time dynamically. In this example the functionbar()
is called many times, but output is disabled after the first invocation.cwrap_log_stats()
is an example of how all instrumented functions can be enumerated at run-time if need be to do reporting, in this example reporting on how many calls to each instrumented function.C0
is shown in the first column which identifies the coroutine which is always '0' in this example.- Other items can also be shown in the first columns such as CPU time and stack position and thread ID, but these have been disabled in the automated tests because they are not deterministic.
$ cat build/language-cpp-example-1-cwrap-include-curt-make-via-n-line-opt-O0/run.log
cwrap_log_init() {} // CWRAP_LOG: _VERBOSITY_SET_ALL=1 _STATS=1 _CURT=1 _FILE=0 _COR_ID=1 _THREAD_ID=0 _STACK_PTR=0 _TIMESTAMP=0
C0 + cwrap_log_verbosity_set_all(verbosity=1) {} // #1 set verbosity for 23 functions instrumented
C0 + _GLOBAL__sub_I_cpp_example_1_a_cpp() {
C0 + __static_initialization_and_destruction_0() {
C0 + my_struct::my_struct(arg1=my_struct_1) {} // #1 constructing my_struct
C0 } // __static_initialization_and_destruction_0() #1
C0 } // _GLOBAL__sub_I_cpp_example_1_a_cpp() #1
C0 + _GLOBAL__sub_I_cpp_example_1_b_cpp() {
C0 + __static_initialization_and_destruction_0() {
C0 + my_struct::my_struct(arg1=my_struct_2) {} // #2 constructing my_struct
C0 } // __static_initialization_and_destruction_0() #2
C0 } // _GLOBAL__sub_I_cpp_example_1_b_cpp() #1
C0 + main() {
C0 + qux() {
C0 + quux() {} = r=2 // #1
C0 + quux() {} = r=3 // #2
C0 + quux() {} = r=4 // #3
C0 } // qux() #1
C0 + bar(a=0) {
C0 + baz(a=1) {} = r=2 // #1
C0 } = r=2 // bar() #1
C0 + cwrap_log_verbosity_set(verbosity=2, name=bar) {} // #1 setting verbosity to 2 (was 1) for function bar()
C0 + baz(a=2) {} = r=3 // #2
C0 + baz(a=3) {} = r=4 // #3
C0 - hello world
C0 + baz(a=1) {} = r=2 // #4
C0 + int get_max<>(a=12345, b=67890) {} = r=67890 // #1
C0 + char get_max<>(a=43, b=21) {} = r=43 // #1
C0 + my_struct::my_struct(arg1=my_struct_2) {} // #3 constructing my_struct
C0 + Foo::Foo() {
C0 + my_struct::my_struct(arg1=my_struct_3, arg2=a) {} // #1 constructing my_struct
C0 - constructing Foo
C0 - inside Foo
C0 } // Foo::Foo() #1
C0 + Foo::Foo() {
C0 + my_struct::my_struct(arg1=my_struct_3, arg2=b) {} // #2 constructing my_struct
C0 - constructing Foo
C0 - inside Foo
C0 } // Foo::Foo() #2
C0 + Foo::my_public(a=100) {
C0 - hello my_public
C0 + Foo::my_private(a=101) {
C0 + baz(a=103) {} = r=104 // #5
C0 } = r=104 // Foo::my_private() #1
C0 } = r=104 // Foo::my_public() #1
C0 + baz(a=105) {} = r=106 // #6
C0 - return b=106
C0 + Foo::~Foo() { // deconstructing Foo
C0 - inside ~Foo
C0 + my_struct::~my_struct() {} // #1 deconstructing my_struct
C0 } // Foo::~Foo() #1
C0 + Foo::~Foo() { // deconstructing Foo
C0 - inside ~Foo
C0 + my_struct::~my_struct() {} // #2 deconstructing my_struct
C0 } // Foo::~Foo() #2
C0 + my_struct::~my_struct() {} // #3 deconstructing my_struct
C0 + clean_up() {} // #1 my_int=5
C0 } // main() #1
C0 + bye_baz() {} // #1 called via atexit() via baz()
C0 + bye_baz() {} // #2 called via atexit() via baz()
C0 + bye_baz() {} // #3 called via atexit() via baz()
C0 + bye() {} // #1 called via atexit() via main()
C0 + bye_baz() {} // #4 called via atexit() via baz()
C0 + bye_baz() {} // #5 called via atexit() via baz()
C0 + bye_baz() {} // #6 called via atexit() via baz()
C0 + my_struct::~my_struct() {} // #4 deconstructing my_struct
C0 + my_struct::~my_struct() {} // #5 deconstructing my_struct
C0 + cwrap_log_stats() {
C0 - 1 calls to 1 of 1 function variation for cwrap_log_verbosity_set()
C0 - 1 calls to 1 of 1 function variation for cwrap_log_stats()
C0 - 1 calls to 1 of 1 function variation for cwrap_log_verbosity_set_all()
C0 - 1 calls to 1 of 1 function variation for main()
C0 - 5 calls to 1 of 1 function variation for my_struct::~my_struct()
C0 - 2 calls to 2 of 2 function variation for my_struct::my_struct()
C0 - 3 calls to 1 of 2 function variation for my_struct::my_struct()
C0 - 2 calls to 1 of 1 function variation for Foo::~Foo()
C0 - 2 calls to 1 of 1 function variation for Foo::Foo()
C0 - 1 calls to 1 of 1 function variation for Foo::my_public()
C0 - 1 calls to 1 of 1 function variation for Foo::my_private()
C0 - 3 calls to 1 of 1 function variation for quux()
C0 - 1 calls to 1 of 1 function variation for qux()
C0 - 1 calls to 1 of 1 function variation for bar()
C0 - 1 calls to 1 of 1 function variation for clean_up()
C0 - 1 calls to 1 of 1 function variation for int get_max<>()
C0 - 1 calls to 1 of 1 function variation for char get_max<>()
C0 - 6 calls to 1 of 1 function variation for bye_baz()
C0 - 2 calls to 1 of 1 function variation for __static_initialization_and_destruction_0()
C0 - 1 calls to 1 of 1 function variation for bye()
C0 - 6 calls to 1 of 1 function variation for baz()
C0 - 1 calls to 1 of 1 function variation for _GLOBAL__sub_I_cpp_example_1_b_cpp()
C0 - 1 calls to 1 of 1 function variation for _GLOBAL__sub_I_cpp_example_1_a_cpp()
C0 - 45 calls to 23 of 23 functions instrumented
C0 } // cwrap_log_stats() #1
- The existing 64
printf()
statements mixed with the auto instrumentation output curt results in 132 output lines excluding thecwrap_log_verbosity_set()
andcwrap_log_stats()
functions.
$ cat build/language-cpp-example-1-cwrap-include-long-make-via-n-line-opt-O0/run.log
cwrap_log_init() {} // CWRAP_LOG: _VERBOSITY_SET_ALL=1 _STATS=1 _CURT=0 _FILE=0 _COR_ID=1 _THREAD_ID=0 _STACK_PTR=0 _TIMESTAMP=0
C0 + cwrap_log_verbosity_set_all() {
C0 - verbosity=1
C0 - set verbosity for 23 functions instrumented
C0 } // cwrap_log_verbosity_set_all() #1
C0 + _GLOBAL__sub_I_cpp_example_1_a_cpp() {
C0 + __static_initialization_and_destruction_0() {
C0 + my_struct::my_struct() {
C0 - arg1=my_struct_1
C0 - constructing my_struct
C0 } // my_struct::my_struct() #1
C0 } // __static_initialization_and_destruction_0() #1
C0 } // _GLOBAL__sub_I_cpp_example_1_a_cpp() #1
C0 + _GLOBAL__sub_I_cpp_example_1_b_cpp() {
C0 + __static_initialization_and_destruction_0() {
C0 + my_struct::my_struct() {
C0 - arg1=my_struct_2
C0 - constructing my_struct
C0 } // my_struct::my_struct() #2
C0 } // __static_initialization_and_destruction_0() #2
C0 } // _GLOBAL__sub_I_cpp_example_1_b_cpp() #1
C0 + main() {
C0 + qux() {
C0 + quux() {
C0 - return r=2
C0 } // quux() #1
C0 + quux() {
C0 - return r=3
C0 } // quux() #2
C0 + quux() {
C0 - return r=4
C0 } // quux() #3
C0 } // qux() #1
C0 + bar() {
C0 - a=0
C0 + baz() {
C0 - a=1
C0 - return r=2
C0 } // baz() #1
C0 - return r=2
C0 } // bar() #1
C0 + cwrap_log_verbosity_set() {
C0 - verbosity=2, name=bar
C0 - setting verbosity to 2 (was 1) for function bar()
C0 } // cwrap_log_verbosity_set() #1
C0 + baz() {
C0 - a=2
C0 - return r=3
C0 } // baz() #2
C0 + baz() {
C0 - a=3
C0 - return r=4
C0 } // baz() #3
C0 - hello world
C0 + baz() {
C0 - a=1
C0 - return r=2
C0 } // baz() #4
C0 + int get_max<>() {
C0 - a=12345, b=67890
C0 - return r=67890
C0 } // int get_max<>() #1
C0 + char get_max<>() {
C0 - a=43, b=21
C0 - return r=43
C0 } // char get_max<>() #1
C0 + my_struct::my_struct() {
C0 - arg1=my_struct_2
C0 - constructing my_struct
C0 } // my_struct::my_struct() #3
C0 + Foo::Foo() {
C0 + my_struct::my_struct() {
C0 - arg1=my_struct_3, arg2=a
C0 - constructing my_struct
C0 } // my_struct::my_struct() #1
C0 - constructing Foo
C0 - inside Foo
C0 } // Foo::Foo() #1
C0 + Foo::Foo() {
C0 + my_struct::my_struct() {
C0 - arg1=my_struct_3, arg2=b
C0 - constructing my_struct
C0 } // my_struct::my_struct() #2
C0 - constructing Foo
C0 - inside Foo
C0 } // Foo::Foo() #2
C0 + Foo::my_public() {
C0 - a=100
C0 - hello my_public
C0 + Foo::my_private() {
C0 - a=101
C0 + baz() {
C0 - a=103
C0 - return r=104
C0 } // baz() #5
C0 - return r=104
C0 } // Foo::my_private() #1
C0 - return r=104
C0 } // Foo::my_public() #1
C0 + baz() {
C0 - a=105
C0 - return r=106
C0 } // baz() #6
C0 - return b=106
C0 + Foo::~Foo() {
C0 - deconstructing Foo
C0 - inside ~Foo
C0 + my_struct::~my_struct() {
C0 - deconstructing my_struct
C0 } // my_struct::~my_struct() #1
C0 } // Foo::~Foo() #1
C0 + Foo::~Foo() {
C0 - deconstructing Foo
C0 - inside ~Foo
C0 + my_struct::~my_struct() {
C0 - deconstructing my_struct
C0 } // my_struct::~my_struct() #2
C0 } // Foo::~Foo() #2
C0 + my_struct::~my_struct() {
C0 - deconstructing my_struct
C0 } // my_struct::~my_struct() #3
C0 + clean_up() {
C0 - my_int=5
C0 } // clean_up() #1
C0 } // main() #1
C0 + bye_baz() {
C0 - called via atexit() via baz()
C0 } // bye_baz() #1
C0 + bye_baz() {
C0 - called via atexit() via baz()
C0 } // bye_baz() #2
C0 + bye_baz() {
C0 - called via atexit() via baz()
C0 } // bye_baz() #3
C0 + bye() {
C0 - called via atexit() via main()
C0 } // bye() #1
C0 + bye_baz() {
C0 - called via atexit() via baz()
C0 } // bye_baz() #4
C0 + bye_baz() {
C0 - called via atexit() via baz()
C0 } // bye_baz() #5
C0 + bye_baz() {
C0 - called via atexit() via baz()
C0 } // bye_baz() #6
C0 + my_struct::~my_struct() {
C0 - deconstructing my_struct
C0 } // my_struct::~my_struct() #4
C0 + my_struct::~my_struct() {
C0 - deconstructing my_struct
C0 } // my_struct::~my_struct() #5
C0 + cwrap_log_stats() {
C0 - 1 calls to 1 of 1 function variation for cwrap_log_verbosity_set()
C0 - 1 calls to 1 of 1 function variation for cwrap_log_stats()
C0 - 1 calls to 1 of 1 function variation for cwrap_log_verbosity_set_all()
C0 - 1 calls to 1 of 1 function variation for main()
C0 - 5 calls to 1 of 1 function variation for my_struct::~my_struct()
C0 - 2 calls to 2 of 2 function variation for my_struct::my_struct()
C0 - 3 calls to 1 of 2 function variation for my_struct::my_struct()
C0 - 2 calls to 1 of 1 function variation for Foo::~Foo()
C0 - 2 calls to 1 of 1 function variation for Foo::Foo()
C0 - 1 calls to 1 of 1 function variation for Foo::my_public()
C0 - 1 calls to 1 of 1 function variation for Foo::my_private()
C0 - 3 calls to 1 of 1 function variation for quux()
C0 - 1 calls to 1 of 1 function variation for qux()
C0 - 1 calls to 1 of 1 function variation for bar()
C0 - 1 calls to 1 of 1 function variation for clean_up()
C0 - 1 calls to 1 of 1 function variation for int get_max<>()
C0 - 1 calls to 1 of 1 function variation for char get_max<>()
C0 - 6 calls to 1 of 1 function variation for bye_baz()
C0 - 2 calls to 1 of 1 function variation for __static_initialization_and_destruction_0()
C0 - 1 calls to 1 of 1 function variation for bye()
C0 - 6 calls to 1 of 1 function variation for baz()
C0 - 1 calls to 1 of 1 function variation for _GLOBAL__sub_I_cpp_example_1_b_cpp()
C0 - 1 calls to 1 of 1 function variation for _GLOBAL__sub_I_cpp_example_1_a_cpp()
C0 - 45 calls to 23 of 23 functions instrumented
C0 } // cwrap_log_stats() #1