corelight / cwrap Goto Github PK
View Code? Open in Web Editor NEWAuto wrap C and C++ functions with instrumentation
License: MIT License
Auto wrap C and C++ functions with instrumentation
License: MIT License
Yes, here's an example:
$ git clone https://github.com/nim-lang/Nim.git
$ pushd ./Nim/
$ time ./build_all.sh
...
real 4m24.324s
$ popd
$ ./Nim/bin/nim --version | egrep -i nim
Nim Compiler Version 1.7.1 [Linux: amd64]
cwrap
:$ cat helloworld.nim
proc foo(): void =
echo "Hello World from foo()"
proc bar(): void =
foo()
echo "Hello World 2"
bar()
$ ./Nim/bin/nim c -r --verbosity:2 helloworld.nim
...
CC: helloworld.nim: gcc -c -w -fmax-errors=3 -pthread -I/home/simon/work/20220722-nim/Nim/lib -I/home/simon/work/20220722-nim -o /home/simon/.cache/nim/helloworld_d/@mhelloworld.nim.c.o /home/simon/.cache/nim/helloworld_d/@mhelloworld.nim.c
Hint: gcc -o /home/simon/work/20220722-nim/helloworld /home/simon/.cache/nim/helloworld_d/@mNim@slib@sstd@[email protected] /home/simon/.cache/nim/helloworld_d/@mNim@slib@[email protected] /home/simon/.cache/nim/helloworld_d/@mNim@slib@spure@[email protected] /home/simon/.cache/nim/helloworld_d/@mNim@slib@[email protected] /home/simon/.cache/nim/helloworld_d/@mNim@[email protected] /home/simon/.cache/nim/helloworld_d/@mhelloworld.nim.c.o -pthread -ldl [Link]
/home/simon/work/20220722-nim/Nim/compiler/extccomp.nim(402, 13) compiler msg initiated here [MsgOrigin]
...
Hello World 2
Hello World from foo()
$ wc -c helloworld
116680 helloworld
$ ./Nim/bin/nim c --cc:xyz -r --verbosity:2 helloworld.nim
...
command line(1, 2) Error: unknown C compiler: 'xyz'. Available options are: gcc, switch_gcc, llvm_gcc, clang, bcc, vcc, tcc, env, icl, icc, clang_cl
cwrap
to wrap Nim
compilation, we're going to have to trick Nim into thinking we want to to use one of its supported compilers, e.g. icc
:$ which icc
$
$ ./Nim/bin/nim c --cc:icc -r --verbosity:2 helloworld.nim
...
Error: execution of an external compiler program 'icc -c -pthread -I/home/simon/work/20220722-nim/Nim/lib -I/home/simon/work/20220722-nim -o /home/simon/.cache/nim/helloworld_d/@mNim@slib@sstd@[email protected] /home/simon/.cache/nim/helloworld_d/@mNim@slib@sstd@[email protected]' failed with exit code: 127
icc
"compiler" for Nim to run:$ PATH=$PATH:`pwd`
$ cat icc
echo "hello from icc"
exit 1
$ chmod +x icc
$ ./Nim/bin/nim c --cc:icc --forceBuild:on -r --verbosity:2 helloworld.nim
...
Error: execution of an external compiler program 'icc -c -pthread -I/home/simon/work/20220722-nim/Nim/lib -I/home/simon/work/20220722-nim -o /home/simon/.cache/nim/helloworld_d/@mNim@slib@sstd@[email protected] /home/simon/.cache/nim/helloworld_d/@mNim@slib@sstd@[email protected]' failed with exit code: 1
...
hello from icc
cwrap
and install its dependencies:$ git clone $ https://github.com/corelight/cwrap.git
$ sudo apt-get install liblist-moreutils-perl
$ sudo apt install cpanminus
$ sudo cpanm FFI::Platypus::Lang::CPP::Demangle::XS
$ sudo apt install llvm
$ which llvm-cxxfilt
/usr/bin/llvm-cxxfilt
icc
fake compiler to point to cwrap
(which uses gcc
under the covers):$ cat icc
`pwd`/cwrap/cwrap.pl "$@"
cwrap
:$ git diff
diff --git a/cwrap.pl b/cwrap.pl
- $gcc_4_s =~ s~$source_file_argument~$s_file.2.s~;
+ if ($gcc_4_s =~ s~$source_file_argument[ ]~$s_file.2.s ~) {} # if source file is not at the end of the command line
+ elsif ($gcc_4_s =~ s~$source_file_argument$~$s_file.2.s~) {} # if source file is at the end of the command line
+ else { cwrap_die(sprintf qq[%f ERROR: cwrap regex failed to substitute source files; gcc_4_s=%s!\n], Time::HiRes::time() - $ts, $gcc_4_s); }
Nim
to force re-build helloworld.nim
using icc
:$ ./Nim/bin/nim c --cc:icc --forceBuild:on -r --verbosity:2 helloworld.nim
...
Hello World 2
Hello World from foo()
$ wc -c helloworld
226696 helloworld
helloworld
executable is now bigger because 100s of functions are instrumented by cwrap
.helloworld
and ask cwrap
to list all the instruction function (note: many functions are grepped away for brevity):$ CWRAP_LOG_SHOW=1 ./helloworld | egrep -v "(system|sdigitsutils|ssyncio|ssharedlist)"
C0 + cwrap_log_show() { #1
C0 - func_addr=(nil)
C0 - #1: verbosity 9 for 1 of 1 function variation(s) for cwrap_log_show() from helloworld.cwrap.c
C0 - #2: verbosity 9 for 1 of 1 function variation(s) for cwrap_log_stats() from helloworld.cwrap.c
C0 - #3: verbosity 9 for 1 of 1 function variation(s) for cwrap_log_verbosity_set() from helloworld.cwrap.c
C0 - #4: verbosity 9 for 1 of 1 function variation(s) for cwrap_log_quiet_until() from helloworld.cwrap.c
C0 - #107: verbosity 9 for 1 of 1 function variation(s) for main() from /home/simon/.cache/nim/helloworld_d/@mhelloworld.nim.c.o
C0 - #126: verbosity 9 for 1 of 1 function variation(s) for initStackBottomWith() from /home/simon/.cache/nim/helloworld_d/@mhelloworld.nim.c.o
C0 - #153: verbosity 9 for 1 of 1 function variation(s) for foo__helloworld_1() from /home/simon/.cache/nim/helloworld_d/@mhelloworld.nim.c.o
C0 - #194: verbosity 9 for 1 of 1 function variation(s) for bar__helloworld_2() from /home/simon/.cache/nim/helloworld_d/@mhelloworld.nim.c.o
C0 - #225: verbosity 9 for 1 of 1 function variation(s) for PreMainInner() from /home/simon/.cache/nim/helloworld_d/@mhelloworld.nim.c.o
C0 - #226: verbosity 9 for 1 of 1 function variation(s) for PreMain() from /home/simon/.cache/nim/helloworld_d/@mhelloworld.nim.c.o
C0 - #227: verbosity 9 for 1 of 1 function variation(s) for NimMainModule() from /home/simon/.cache/nim/helloworld_d/@mhelloworld.nim.c.o
C0 - #228: verbosity 9 for 1 of 1 function variation(s) for NimMainInner() from /home/simon/.cache/nim/helloworld_d/@mhelloworld.nim.c.o
C0 - #229: verbosity 9 for 1 of 1 function variation(s) for NimMain() from /home/simon/.cache/nim/helloworld_d/@mhelloworld.nim.c.o
C0 } // cwrap_log_show()
helloworld
and ask cwrap
to run with full verbosity except for functions in ssystem.nim.c
and sdigitsutils.nim.c
:$ CWRAP_LOG_STATS=1 CWRAP_LOG_NUM=1 CWRAP_LOG_TIMESTAMP=1 CWRAP_LOG_THREAD_ID=1 CWRAP_LOG_CURT=1 CWRAP_LOG_VERBOSITY_SET=1/9=file-ssystem.nim.c/9=file-sdigitsutils.nim.c ./helloworld | less +G
cwrap_log_init() {} // CWRAP_LOG: _VERBOSITY_SET=1/9=file-ssystem.nim.c/9=file-sdigitsutils.nim.c (<verbosity>[={file|function}-<keyword>][/...]) _QUIET_UNTIL=(null) _STATS=1 _SHOW=0 _CURT=1 _FILE=0 _NUM=1 _COR_ID=1 _LIMIT=10,000 _THREAD_ID=1 _STACK_PTR=0
#1 T06822 C0 0.000011s + cwrap_log_verbosity_set(verbosity=1/9=file-ssystem.nim.c/9=file-sdigitsutils.nim.c) { // #1 [cwrap_log_verbosity_set() ignores verbosity!]
#2 T06822 C0 0.000029s - verbosity 1 set for 240 matches in 240 functions for 1 byte clause '1' // type=FILE|FUNCTION keyword=(null)
#3 T06822 C0 0.000031s - verbosity 9 set for 210 matches in 240 functions for 20 byte clause '9=file-ssystem.nim.c' // type=FILE keyword=ssystem.nim.c
#4 T06822 C0 0.000032s - verbosity 9 set for 10 matches in 240 functions for 25 byte clause '9=file-sdigitsutils.nim.c' // type=FILE keyword=sdigitsutils.nim.c
#5 T06822 C0 0.000034s } // cwrap_log_verbosity_set()
#6 T06822 C0 0.000036s + main() { // #1
#7 T06822 C0 0.000039s + NimMain() { // #1
#8 T06822 C0 0.000040s + PreMain() { // #1
#9 T06822 C0 0.000042s + initStackBottomWith() {} // #1
#10 T06822 C0 0.000102s + init__system_6081() { // #1
#11 T06822 C0 0.000105s + initLock__coreZlocks_64() {} // #1
#12 T06822 C0 0.000106s } // init__system_6081()
#13 T06822 C0 0.000109s + PreMainInner() {} // #1
#14 T06822 C0 0.000110s } // PreMain()
#15 T06822 C0 0.000111s + initStackBottomWith() {} // #2
#16 T06822 C0 0.000112s + NimMainInner() { // #1
#17 T06822 C0 0.000113s + NimMainModule() { // #1
#18 T06822 C0 0.000114s + echoBinSafe() { // #1
#19 T06822 C0 0.000115s + nimToCStringConv() {} // #1
Hello World 2
#20 T06822 C0 0.000120s } // echoBinSafe()
#21 T06822 C0 0.000121s + bar__helloworld_2() { // #1
#22 T06822 C0 0.000122s + foo__helloworld_1() { // #1
#23 T06822 C0 0.000122s + echoBinSafe() { // #2
#24 T06822 C0 0.000123s + nimToCStringConv() {} // #2
Hello World from foo()
#25 T06822 C0 0.000125s } // echoBinSafe()
#26 T06822 C0 0.000126s } // foo__helloworld_1()
#27 T06822 C0 0.000126s } // bar__helloworld_2()
#28 T06822 C0 0.000127s } // NimMainModule()
#29 T06822 C0 0.000128s } // NimMainInner()
#30 T06822 C0 0.000129s } // NimMain()
#31 T06822 C0 0.000129s } // main()
#32 T06822 C0 0.000131s + cwrap_log_stats() { // #1 [cwrap_log_stats() ignores verbosity!]
#33 T06822 C0 0.000132s - 1 calls to 1 of 1 function variation(s) for cwrap_log_stats()
#34 T06822 C0 0.000133s - 1 calls to 1 of 1 function variation(s) for cwrap_log_verbosity_set()
#35 T06822 C0 0.000135s - 2 calls to 1 of 1 function variation(s) for nimToCStringConv()
#36 T06822 C0 0.000136s - 1 calls to 1 of 1 function variation(s) for main()
#37 T06822 C0 0.000137s - 1 calls to 1 of 1 function variation(s) for init__system_6081()
#38 T06822 C0 0.000138s - 2 calls to 1 of 1 function variation(s) for initStackBottomWith()
#39 T06822 C0 0.000139s - 1 calls to 1 of 1 function variation(s) for initLock__coreZlocks_64()
#40 T06822 C0 0.000140s - 1 calls to 1 of 1 function variation(s) for foo__helloworld_1()
#41 T06822 C0 0.000140s - 2 calls to 1 of 1 function variation(s) for echoBinSafe()
#42 T06822 C0 0.000142s - 1 calls to 1 of 1 function variation(s) for bar__helloworld_2()
#43 T06822 C0 0.000143s - 1 calls to 1 of 1 function variation(s) for PreMainInner()
#44 T06822 C0 0.000143s - 1 calls to 1 of 1 function variation(s) for PreMain()
#45 T06822 C0 0.000144s - 1 calls to 1 of 1 function variation(s) for NimMainModule()
#46 T06822 C0 0.000145s - 1 calls to 1 of 1 function variation(s) for NimMainInner()
#47 T06822 C0 0.000146s - 1 calls to 1 of 1 function variation(s) for NimMain()
#48 T06822 C0 0.000147s - 18 calls to 15 of 240 functions instrumented
#49 T06822 C0 0.000148s } // cwrap_log_stats()
helloworld
Nim executable.helloworld
and ask cwrap
to run with no verbosity until function NimMainInner()
is called for the first time.nimFrame()
:$ CWRAP_LOG_QUIET_UNTIL=NimMainInner CWRAP_LOG_STATS=1 CWRAP_LOG_NUM=1 CWRAP_LOG_TIMESTAMP=1 CWRAP_LOG_THREAD_ID=1 CWRAP_LOG_CURT=1 CWRAP_LOG_VERBOSITY_SET=1 ./helloworld
cwrap_log_init() {} // CWRAP_LOG: _VERBOSITY_SET=1 (<verbosity>[={file|function}-<keyword>][/...]) _QUIET_UNTIL=NimMainInner _STATS=1 _SHOW=0 _CURT=1 _FILE=0 _NUM=1 _COR_ID=1 _LIMIT=10,000 _THREAD_ID=1 _STACK_PTR=0 _TIMESTAMP=1 _UNWIND=0 _ON_VALGRIND=0
#1 T06837 C0 0.000036s + cwrap_log_verbosity_set(verbosity=1) { // #1 [cwrap_log_verbosity_set() ignores verbosity!]
#2 T06837 C0 0.000055s - verbosity 1 set for 240 matches in 240 functions for 1 byte clause '1' // type=FILE|FUNCTION keyword=(null)
#3 T06837 C0 0.000062s } // cwrap_log_verbosity_set()
#4 T06837 C0 0.000064s + cwrap_log_quiet_until(name=NimMainInner) {} // #1 going quiet until function NimMainInner() [cwrap_log_quiet_until() ignores verbosity!]
#5 T06837 C0 0.000127s + NimMainInner() { // #1
#6 T06837 C0 0.000129s + NimMainModule() { // #1
#7 T06837 C0 0.000147s + nimFrame() {} // #1
#8 T06837 C0 0.000150s + echoBinSafe() { // #1
#9 T06837 C0 0.000151s + nimFrame() {} // #2
#10 T06837 C0 0.000154s + nimToCStringConv() {} // #1
Hello World 2
#11 T06837 C0 0.000156s + nimAddInt() {} // #1
#12 T06837 C0 0.000158s + popFrame() {} // #1
#13 T06837 C0 0.000159s } // echoBinSafe()
#14 T06837 C0 0.000161s + bar__helloworld_2() { // #1
#15 T06837 C0 0.000162s + nimFrame() {} // #3
#16 T06837 C0 0.000164s + foo__helloworld_1() { // #1
#17 T06837 C0 0.000165s + nimFrame() {} // #4
#18 T06837 C0 0.000167s + echoBinSafe() { // #2
#19 T06837 C0 0.000168s + nimFrame() {} // #5
#20 T06837 C0 0.000170s + nimToCStringConv() {} // #2
Hello World from foo()
#21 T06837 C0 0.000172s + nimAddInt() {} // #2
#22 T06837 C0 0.000174s + popFrame() {} // #2
#23 T06837 C0 0.000175s } // echoBinSafe()
#24 T06837 C0 0.000177s + popFrame() {} // #3
#25 T06837 C0 0.000178s } // foo__helloworld_1()
#26 T06837 C0 0.000180s + popFrame() {} // #4
#27 T06837 C0 0.000181s } // bar__helloworld_2()
#28 T06837 C0 0.000183s + popFrame() {} // #5
#29 T06837 C0 0.000185s } // NimMainModule()
#30 T06837 C0 0.000187s } // NimMainInner()
#31 T06837 C0 0.000189s } // NimMain()
#32 T06837 C0 0.000206s } // main()
#33 T06837 C0 0.000208s + colonanonymous___system_5714() {} // #1
#34 T06837 C0 0.000221s + cwrap_log_stats() { // #1 [cwrap_log_stats() ignores verbosity!]
#35 T06837 C0 0.000223s - 1 calls to 1 of 1 function variation(s) for cwrap_log_stats()
#36 T06837 C0 0.000226s - 1 calls to 1 of 1 function variation(s) for cwrap_log_verbosity_set()
#37 T06837 C0 0.000228s - 1 calls to 1 of 1 function variation(s) for cwrap_log_quiet_until()
#38 T06837 C0 0.000230s - 5 calls to 1 of 1 function variation(s) for popFrame()
#39 T06837 C0 0.000233s - 2 calls to 1 of 1 function variation(s) for nimToCStringConv()
#40 T06837 C0 0.000234s - 5 calls to 1 of 1 function variation(s) for nimFrame()
#41 T06837 C0 0.000236s - 2 calls to 1 of 1 function variation(s) for nimAddInt()
#42 T06837 C0 0.000239s - 1 calls to 1 of 1 function variation(s) for foo__helloworld_1()
#43 T06837 C0 0.000242s - 2 calls to 1 of 1 function variation(s) for echoBinSafe()
#44 T06837 C0 0.000244s - 1 calls to 1 of 1 function variation(s) for colonanonymous___system_5714()
#45 T06837 C0 0.000246s - 1 calls to 1 of 1 function variation(s) for bar__helloworld_2()
#46 T06837 C0 0.000248s - 1 calls to 1 of 1 function variation(s) for NimMainModule()
#47 T06837 C0 0.000249s - 1 calls to 1 of 1 function variation(s) for NimMainInner()
#48 T06837 C0 0.000251s - 24 calls to 13 of 240 functions instrumented
#49 T06837 C0 0.000253s } // cwrap_log_stats()
Hi Simon,
thanks for your awesome project! I love it!
I am trying to compile the examples from the raylib project with cwrap but get the following error:
ERROR: internal: cwrap: zero cwrap structs; should never be zero
Do you have any idea what that error message could hint to?
I can be more specific but I don't want to waste your precious time. Just a push in the right direction would be sufficient.
Kind regards,
Michael
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.