minor fixes for clang++
[senf.git] / tools / 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: This works by setting a breakpoint in the std::exception
12 # constructor. This is, where the backtrace is created from. If you do
13 # some funky manipulations with your exceptions, the backtrace might
14 # not point to the throw statement, however this is very unusual. Of
15 # course, this only works, if all your exceptions are derived from
16 # std::exception but that should always be the case.
17
18 trap 'rm -f .run-test-gdb.cmd' 0 1 2 15
19
20 # This gdb script will set the breakpoint and will then run the test
21 # driver. Whenever the execution stops, it will print a backtrace and
22 # will then continue execution. This will produce superflous
23 # backtraces for exceptions which are handled correctly. These will be
24 # filtered out later.
25 cat >.run-test-gdb.cmd <<EOF
26 break std::exception::exception()
27 run --build_info=yes --log_level=test_suite
28 while 1
29   bt
30   c
31 end
32 EOF
33
34 # The perl script will filter out exceptions which are handled
35 # correctly (cought before the reach the unit test driver). It will
36 # also truncate the backtrace at the first stackframe within the unit
37 # test subsystem since we are only interested in the user code.
38 gdb -batch -x .run-test-gdb.cmd ./.test.bin 2>&1 | perl -e '
39   $mode=0;
40   $silent=0;
41   while (<STDIN>) {
42     if ($mode==0) {
43       if (/^$/) {
44         $mode=1;
45       } else {
46         print;
47       }
48     }
49     elsif ($mode==1) {
50       if (/^(Breakpoint 1, exception|Program received signal )/) {
51         $mode=2;
52         @l=();
53       } else {
54         print "\n";
55         print;
56         $mode=0;
57       }
58     }
59     elsif ($mode==2) {
60       if (/^(#?[0-9]| )/) {
61         push @l,$_ if /^#/;
62         $l[$#l] .= $_ if @l && /^ /;
63       } elsif (/^(Current language:  auto;|\[Switching to Thread)/) {
64         ;
65       } else {
66         $mode=0;
67         if (/: fatal error in /) {
68           print "\n";
69           for (@l[1..$#l]) {
70             last if /^#[0-9]+ +0x[0-9a-f]+ in boost::unit_test::ut_detail::invoker/;
71             if ($silent) {
72               unless (/at \/usr\/lib\/gcc\//) {
73                 print;
74                 $silent=0;
75               }
76             } else {
77               print unless /in \?\?/;
78               $silent=1 if /__gnu_debug::/;
79              }
80           }
81           print;
82           print "\n";
83         } else {
84           redo;
85         }
86       }
87     }
88   }
89 '