Complete SENFSCons documentation
[senf.git] / run-test-gdb.sh
1 #!/bin/sh
2
3 # This script helps finding the origin of unhandled exceptions in the
4 # unit tests. The unit test framework will tell, that an exception has
5 # been caught by the test driver but will not tell, where in the code
6 # it has occured.
7 #
8 # This script will run the .test.bin test driver within gdb and will
9 # create a backtrace for every exception caught by the test driver.
10 #
11 # NOTE: If your unit test (excplicitly) writes output to stderr, this
12 # output will be lost
13 #
14 # NOTE: This works by setting a breakpoint in the std::exception
15 # constructor. This is, where the backtrace is created from. If you do
16 # some funky manipulations with your exceptions, the backtrace might
17 # not point to the throw statement, however this is very unusual. Of
18 # course, this only works, if all your exceptions are derived from
19 # std::exception but that should always be the case.
20
21 trap 'rm -f .run-test-gdb.cmd' 0 1 2 15
22
23 # This gdb script will set the breakpoint and will then run the test
24 # driver. Whenever the execution stops, it will print a backtrace and
25 # will then continue execution. This will produce superflous
26 # backtraces for exceptions which are handled correctly. These will be
27 # filtered out later.
28 cat >.run-test-gdb.cmd <<EOF
29 break std::exception::exception()
30 run --build_info=yes --log_level=test_suite
31 while 1
32   bt
33   c
34 end
35 EOF
36
37 # The perl script will filter out exceptions which are handled
38 # correctly (cought before the reach the unit test driver). It will
39 # also truncate the backtrace at the first stackframe within the unit
40 # test subsystem since we are only interested in the user code.
41 gdb -batch -x .run-test-gdb.cmd ./.test.bin 2>/dev/null | perl -e '
42   while (<STDIN>) {
43     if (/^$/) { 
44       $_=<STDIN>; 
45       if (/^Breakpoint 1, exception/) {
46         @l=();
47         while (<STDIN>) {
48           last unless /^#?[0-9]|^ /;
49           push @l,$_ if /^#/;
50           $l[$#l] .= $_ if /^ /;
51         }
52         if (/: fatal error in /) {
53           for (@l[1..$#l]) {
54              last if /^#[0-9]+ +0x[0-9a-f]+ in boost::unit_test/;
55              print;
56           }
57         }
58       }
59       else { print "\n"; }
60     }
61     print;
62   }
63 '