Monday, February 17, 2014

Colorizing GDB backtrace

Being in a startup, we get to see a lot of core dumps, every day ;-). With too many stack frames and long file+function names, I hate the output!. In fact the visual clutter is so much, that it takes me long time to compare two tracebacks! I was thinking what can be done about it - hit upon gdb hooks in a SO post. Put together with my all time fav - Perl, to color the output, got some nice colorful tracebacks! ;-). The following is what I put in my ~/.gdbinit
shell mkfifo /tmp/colorPipe.gdb
# no pause/automore 
set height 0
# dont break line
set width 0
define hook-backtrace
        shell cat /tmp/colorPipe.gdb |  ~/highlgdb.pl &
        set logging redirect on
        set logging on /tmp/colorPipe.gdb
end
define hookpost-backtrace
        set logging off
        set logging redirect off
        shell sleep 0.1
end
define hook-quit
        shell rm /tmp/colorPipe.gdb
end
define re
   echo \033[0m
end

And the Perl script (highlgdb.pl) to do the highlight:
#!/usr/bin/perl -w
##
# Mon Feb 17 14:38:23 IST 2014
# Aniruddha. A (aniruddha.a@gmail.com)
##
$FG_RESET = "";
$FG_RED = "";
$FG_GREEN = "";
$FG_YELLOW = "";
$FG_BLUE = "";
#$FG_MAGENTA="";
#$FG_CYAN="";
#0 0x00007ff994229425 in __GI_raise (sig=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
$usual = qr/^(#\d+)\s+(0x.*) in (\w+) (.*) (at|from) (.*)/;
#12 a_handler_internal (handler=<optimized out>) at ../usr/lib/libutils/a_handler.c:350
$noaddr = qr/^(#\d+)\s+(\w+) (.*) (at|from) (.*)/;
while (<STDIN>) {
if (/$usual/) {
if ( length( $1 . $2 . $3 . $4 ) > 79 ) {
print "$FG_YELLOW$1 $FG_BLUE $2 $FG_RED $3 $FG_YELLOW $4\n $5 $FG_GREEN $6 $FG_RESET\n";
} else {
print "$FG_YELLOW$1 $FG_BLUE $2 $FG_RED $3 $FG_YELLOW $4 $5 $FG_GREEN $6 $FG_RESET\n";
}
} elsif (/$noaddr/) {
if ( length( $1 . $2 . $3 ) > 79 ) {
print "$FG_YELLOW$1 $FG_RED $2 $FG_YELLOW $3\n $4 $FG_GREEN $5 $FG_RESET\n";
} else {
print "$FG_YELLOW$1 $FG_RED $2 $FG_YELLOW $3 $4 $FG_GREEN $5 $FG_RESET\n";
}
} else {
print;
}
}

Try it!, at least identifying the culprit will be much quicker, if not fixing the issue! ;-)

Tuesday, February 04, 2014

Using API docs as a test aid

I wrote about my custom documentation using Lua embedded in my C source. With the complete description of the function - its arguments [and their type], return type etc, can we do more with it?
I wanted some test stubs for the Lua APIs (that I am defining from my C back-end) and all I had to do, was re-define the mydoc function which will consume the same data, but instead of generating documentation, generate some Lua code to test the APIs.
i.e, if I have a function that takes a number and returns a string (on success) and nil on failure, I generate:
function Stub.test (n)
  assert(type(n) == 'number', 'n should be a number)
  if g_nil_path then return nil end
  return 'rand-str'
end 

With this, I can see and get a feel of the Lua APIs that my C functions are exposing, also I can invoke the user scripts just to check the argument types for correctness, and I can exercise the success path as well as the failure path by setting the global g_nil_path. And of course for more randomness, I use 
math.random
 when I return a number and
string.rep(string.char(math.random(65,90)), math.random(1,10)) 
when returning strings.