#!/usr/bin/tclsh # # Parse the output of # # objdump -d sqlite3.o # # for x64 and generate a report showing: # # (1) Stack used by each function # (2) Recursion paths and their aggregate stack depth # set getStack 0 while {![eof stdin]} { set line [gets stdin] if {[regexp {^[0-9a-f]+ <([^>]+)>:\s*$} $line all procname]} { set curfunc $procname set root($curfunc) 1 set calls($curfunc) {} set calledby($curfunc) {} set recursive($curfunc) {} set stkdepth($curfunc) 0 set getStack 1 continue } if {[regexp {callq? +[0-9a-z]+ <([^>]+)>} $line all other]} { set key [list $curfunc $other] set callpair($key) 1 unset -nocomplain root($curfunc) continue } if {[regexp {sub +\$(0x[0-9a-z]+),%[er]sp} $line all xdepth]} { if {$getStack} { scan $xdepth %x depth set stkdepth($curfunc) $depth set getStack 0 } continue } } puts "****************** Stack Usage By Function ********************" set sdlist {} foreach f [array names stkdepth] { lappend sdlist [list $stkdepth($f) $f] } foreach sd [lsort -integer -decr -index 0 $sdlist] { foreach {depth fname} $sd break puts [format {%6d %s} $depth $fname] } puts "****************** Stack Usage By Recursion *******************" foreach key [array names callpair] { foreach {from to} $key break lappend calls($from) $to # lappend calledby($to) $from } proc all_descendents {root} { global calls recursive set todo($root) $root set go 1 while {$go} { set go 0 foreach f [array names todo] { set path $todo($f) unset todo($f) if {![info exists calls($f)]} continue foreach x $calls($f) { if {$x==$root} { lappend recursive($root) [concat $path $root] } elseif {![info exists d($x)]} { set go 1 set todo($x) [concat $path $x] set d($x) 1 } } } } return [array names d] } set pathlist {} foreach f [array names recursive] { all_descendents $f foreach m $recursive($f) { set depth 0 foreach b [lrange $m 0 end-1] { set depth [expr {$depth+$stkdepth($b)}] } lappend pathlist [list $depth $m] } } foreach path [lsort -integer -decr -index 0 $pathlist] { foreach {depth m} $path break set first [lindex $m 0] puts [format {%6d %s %d} $depth $first $stkdepth($first)] foreach b [lrange $m 1 end] { puts " $b $stkdepth($b)" } }