Show inlined functions with bt-akaros.sh (kernel) I noticed syzkaller was printing out additional backtrace lines with info about inlining functions. addr2line does that for us, spitting the info out on two lines. With a little Bash magic, we can parse those lines too. Now something like this: #04 [<0xffffffffc2059e3e>] in __try_wait_any.isra.7 #05 [<0xffffffffc205bf3a>] in sys_waitpid #06 [<0xffffffffc205c849>] in syscall will show up as: #04 [<0xffffffffc2059e3e>] in __try_wait_any() at kern/src/syscall.c:1221 #05 [<0xffffffffc205bf3a>] in wait_any() at kern/src/syscall.c:1286 #05 [< (inlined by) >] in sys_waitpid() at kern/src/syscall.c:1329 #06 [<0xffffffffc205c849>] in syscall() at kern/src/syscall.c:2582 Frame 5 is repeated twice. The actual address, which the kernel's symtab says in in sys_waitpid(), is actually in wait_any(). Both the inlined function (wait_any()) and the function it is in are reported. The previous version of bt_akaros was printing the correct line number (1286); you'd just have to notice when you opened the code that it is in wait_any(), which might not be obvious if you're looking at a slightly different kernel source. Overall, this gives us more info when processing backtraces in that we can see the inlining and call graph. For example, here's a backtrace syzkaller caught: #03 [<0xffffffffc20496db>] in kref_put #04 [<0xffffffffc204d520>] in proc_destroy #05 [<0xffffffffc2058c36>] in sys_proc_destroy That doesn't tell us much. It is much better with inlining: #03 [<0xffffffffc20496db>] in kref_put at include/kref.h:68 #04 [< [inline] >] in proc_decref at src/process.c:587 #04 [< [inline] >] in proc_disown_children at src/process.c:853 #04 [<0xffffffffc204d520>] in proc_destroy at src/process.c:932 #05 [<0xffffffffc2058c36>] in sys_proc_destroy at src/syscall.c:852 Note this is independent of CONFIG_BETTER_BACKTRACES, which just sets -fno-optimize-sibling-calls. This change is all about getting more info from the backtrace the kernel spits out. BETTER_BACKTRACES is about making the kernel spit out more frames. Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
diff --git a/scripts/bt-akaros.sh b/scripts/bt-akaros.sh index d1b13b0..7bf6227 100755 --- a/scripts/bt-akaros.sh +++ b/scripts/bt-akaros.sh
@@ -24,11 +24,27 @@ line=$1 addr=`echo $line | cut -c 7-25` + frame_num=`echo $line | cut -f 1 -d ' '` - echo -n $line " " - # sed cleans out build paths. All kernel files have 'kern', unlike - # arbitrary user binaries. - addr2line -e $KERNEL_BINARY $addr | sed 's/^.*kern\//at kern\//' + IFS=' ' + addr2line -afip -e $KERNEL_BINARY $addr | while read -ra RET + do + if [ "${RET[0]}" == "(inlined" ]; then + # (inlined by) with spaces to line up with a 64 bit addr + addr=" ${RET[0]} ${RET[1]} " + func="${RET[2]}" + srcl="${RET[4]}" + else + addr="${RET[0]}" + addr="${addr%?}" # drop the trailing ':' + func="${RET[1]}" + srcl="${RET[3]}" + fi + # sed cleans out build paths. All kernel files start with + # '/kern', unlike arbitrary user binaries. + srcl=`echo $srcl | sed 's/^.*\/kern\//kern\//'` + echo "$frame_num [<$addr>] in ${func}() at $srcl" + done } user_line() {