OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/tclsh |
| 2 # |
| 3 # Parse the output of |
| 4 # |
| 5 # objdump -d sqlite3.o |
| 6 # |
| 7 # for x64 and generate a report showing: |
| 8 # |
| 9 # (1) Stack used by each function |
| 10 # (2) Recursion paths and their aggregate stack depth |
| 11 # |
| 12 set getStack 0 |
| 13 while {![eof stdin]} { |
| 14 set line [gets stdin] |
| 15 if {[regexp {^[0-9a-f]+ <([^>]+)>:\s*$} $line all procname]} { |
| 16 set curfunc $procname |
| 17 set root($curfunc) 1 |
| 18 set calls($curfunc) {} |
| 19 set calledby($curfunc) {} |
| 20 set recursive($curfunc) {} |
| 21 set stkdepth($curfunc) 0 |
| 22 set getStack 1 |
| 23 continue |
| 24 } |
| 25 if {[regexp {callq? +[0-9a-z]+ <([^>]+)>} $line all other]} { |
| 26 set key [list $curfunc $other] |
| 27 set callpair($key) 1 |
| 28 unset -nocomplain root($curfunc) |
| 29 continue |
| 30 } |
| 31 if {[regexp {sub +\$(0x[0-9a-z]+),%[er]sp} $line all xdepth]} { |
| 32 if {$getStack} { |
| 33 scan $xdepth %x depth |
| 34 set stkdepth($curfunc) $depth |
| 35 set getStack 0 |
| 36 } |
| 37 continue |
| 38 } |
| 39 } |
| 40 |
| 41 puts "****************** Stack Usage By Function ********************" |
| 42 set sdlist {} |
| 43 foreach f [array names stkdepth] { |
| 44 lappend sdlist [list $stkdepth($f) $f] |
| 45 } |
| 46 foreach sd [lsort -integer -decr -index 0 $sdlist] { |
| 47 foreach {depth fname} $sd break |
| 48 puts [format {%6d %s} $depth $fname] |
| 49 } |
| 50 |
| 51 puts "****************** Stack Usage By Recursion *******************" |
| 52 foreach key [array names callpair] { |
| 53 foreach {from to} $key break |
| 54 lappend calls($from) $to |
| 55 # lappend calledby($to) $from |
| 56 } |
| 57 proc all_descendents {root} { |
| 58 global calls recursive |
| 59 set todo($root) $root |
| 60 set go 1 |
| 61 while {$go} { |
| 62 set go 0 |
| 63 foreach f [array names todo] { |
| 64 set path $todo($f) |
| 65 unset todo($f) |
| 66 if {![info exists calls($f)]} continue |
| 67 foreach x $calls($f) { |
| 68 if {$x==$root} { |
| 69 lappend recursive($root) [concat $path $root] |
| 70 } elseif {![info exists d($x)]} { |
| 71 set go 1 |
| 72 set todo($x) [concat $path $x] |
| 73 set d($x) 1 |
| 74 } |
| 75 } |
| 76 } |
| 77 } |
| 78 return [array names d] |
| 79 } |
| 80 set pathlist {} |
| 81 foreach f [array names recursive] { |
| 82 all_descendents $f |
| 83 foreach m $recursive($f) { |
| 84 set depth 0 |
| 85 foreach b [lrange $m 0 end-1] { |
| 86 set depth [expr {$depth+$stkdepth($b)}] |
| 87 } |
| 88 lappend pathlist [list $depth $m] |
| 89 } |
| 90 } |
| 91 foreach path [lsort -integer -decr -index 0 $pathlist] { |
| 92 foreach {depth m} $path break |
| 93 set first [lindex $m 0] |
| 94 puts [format {%6d %s %d} $depth $first $stkdepth($first)] |
| 95 foreach b [lrange $m 1 end] { |
| 96 puts " $b $stkdepth($b)" |
| 97 } |
| 98 } |
OLD | NEW |