aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/sqlite/unix/sqlite-3.5.1/tool/memleak3.tcl
diff options
context:
space:
mode:
authordan miller2007-10-20 02:49:29 +0000
committerdan miller2007-10-20 02:49:29 +0000
commite36d23a85ebff914d74bb541558c2b6082b78edb (patch)
tree54b58fdf162e78af64055282a6035c8d2443389d /libraries/sqlite/unix/sqlite-3.5.1/tool/memleak3.tcl
parent* Fixed an issue whereby avatar chat distances were being calculated against ... (diff)
downloadopensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.zip
opensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.tar.gz
opensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.tar.bz2
opensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.tar.xz
sqlite source (unix build) added to libraries
Diffstat (limited to 'libraries/sqlite/unix/sqlite-3.5.1/tool/memleak3.tcl')
-rw-r--r--libraries/sqlite/unix/sqlite-3.5.1/tool/memleak3.tcl233
1 files changed, 233 insertions, 0 deletions
diff --git a/libraries/sqlite/unix/sqlite-3.5.1/tool/memleak3.tcl b/libraries/sqlite/unix/sqlite-3.5.1/tool/memleak3.tcl
new file mode 100644
index 0000000..3c6e9b9
--- /dev/null
+++ b/libraries/sqlite/unix/sqlite-3.5.1/tool/memleak3.tcl
@@ -0,0 +1,233 @@
1#/bin/sh
2# \
3exec `which tclsh` $0 "$@"
4#
5# The author disclaims copyright to this source code. In place of
6# a legal notice, here is a blessing:
7#
8# May you do good and not evil.
9# May you find forgiveness for yourself and forgive others.
10# May you share freely, never taking more than you give.
11######################################################################
12
13set doco "
14This script is a tool to help track down memory leaks in the sqlite
15library. The library must be compiled with the preprocessor symbol
16SQLITE_MEMDEBUG set to at least 2. It must be set to 3 to enable stack
17traces.
18
19To use, run the leaky application and save the standard error output.
20Then, execute this program with the first argument the name of the
21application binary (or interpreter) and the second argument the name of the
22text file that contains the collected stderr output.
23
24If all goes well a summary of unfreed allocations is printed out. If the
25GNU C library is in use and SQLITE_DEBUG is 3 or greater a stack trace is
26printed out for each unmatched allocation.
27
28If the \"-r <n>\" option is passed, then the program stops and prints out
29the state of the heap immediately after the <n>th call to malloc() or
30realloc().
31
32Example:
33
34$ ./testfixture ../sqlite/test/select1.test 2> memtrace.out
35$ tclsh $argv0 ?-r <malloc-number>? ./testfixture memtrace.out
36"
37
38
39proc usage {} {
40 set prg [file tail $::argv0]
41 puts "Usage: $prg ?-r <malloc-number>? <binary file> <mem trace file>"
42 puts ""
43 puts [string trim $::doco]
44 exit -1
45}
46
47proc shift {listvar} {
48 upvar $listvar l
49 set ret [lindex $l 0]
50 set l [lrange $l 1 end]
51 return $ret
52}
53
54# Argument handling. The following vars are set:
55#
56# $exe - the name of the executable (i.e. "testfixture" or "./sqlite3")
57# $memfile - the name of the file containing the trace output.
58# $report_at - The malloc number to stop and report at. Or -1 to read
59# all of $memfile.
60#
61set report_at -1
62while {[llength $argv]>2} {
63 set arg [shift argv]
64 switch -- $arg {
65 "-r" {
66 set report_at [shift argv]
67 }
68 default {
69 usage
70 }
71 }
72}
73if {[llength $argv]!=2} usage
74set exe [lindex $argv 0]
75set memfile [lindex $argv 1]
76
77# If stack traces are enabled, the 'addr2line' program is called to
78# translate a binary stack address into a human-readable form.
79set addr2line addr2line
80
81# When the SQLITE_MEMDEBUG is set as described above, SQLite prints
82# out a line for each malloc(), realloc() or free() call that the
83# library makes. If SQLITE_MEMDEBUG is 3, then a stack trace is printed
84# out before each malloc() and realloc() line.
85#
86# This program parses each line the SQLite library outputs and updates
87# the following global Tcl variables to reflect the "current" state of
88# the heap used by SQLite.
89#
90set nBytes 0 ;# Total number of bytes currently allocated.
91set nMalloc 0 ;# Total number of malloc()/realloc() calls.
92set nPeak 0 ;# Peak of nBytes.
93set iPeak 0 ;# nMalloc when nPeak was set.
94#
95# More detailed state information is stored in the $memmap array.
96# Each key in the memmap array is the address of a chunk of memory
97# currently allocated from the heap. The value is a list of the
98# following form
99#
100# {<number-of-bytes> <malloc id> <stack trace>}
101#
102array unset memmap
103
104proc process_input {input_file array_name} {
105 upvar $array_name mem
106 set input [open $input_file]
107
108 set MALLOC {([[:digit:]]+) malloc ([[:digit:]]+) bytes at 0x([[:xdigit:]]+)}
109 # set STACK {^[[:digit:]]+: STACK: (.*)$}
110 set STACK {^STACK: (.*)$}
111 set FREE {[[:digit:]]+ free ([[:digit:]]+) bytes at 0x([[:xdigit:]]+)}
112 set REALLOC {([[:digit:]]+) realloc ([[:digit:]]+) to ([[:digit:]]+)}
113 append REALLOC { bytes at 0x([[:xdigit:]]+) to 0x([[:xdigit:]]+)}
114
115 set stack ""
116 while { ![eof $input] } {
117 set line [gets $input]
118 if {[regexp $STACK $line dummy stack]} {
119 # Do nothing. The variable $stack now stores the hexadecimal stack dump
120 # for the next malloc() or realloc().
121
122 } elseif { [regexp $MALLOC $line dummy mallocid bytes addr] } {
123 # If this is a 'malloc' line, set an entry in the mem array. Each entry
124 # is a list of length three, the number of bytes allocated , the malloc
125 # number and the stack dump when it was allocated.
126 set mem($addr) [list $bytes "malloc $mallocid" $stack]
127 set stack ""
128
129 # Increase the current heap usage
130 incr ::nBytes $bytes
131
132 # Increase the number of malloc() calls
133 incr ::nMalloc
134
135 if {$::nBytes > $::nPeak} {
136 set ::nPeak $::nBytes
137 set ::iPeak $::nMalloc
138 }
139
140 } elseif { [regexp $FREE $line dummy bytes addr] } {
141 # If this is a 'free' line, remove the entry from the mem array. If the
142 # entry does not exist, or is the wrong number of bytes, announce a
143 # problem. This is more likely a bug in the regular expressions for
144 # this script than an SQLite defect.
145 if { [lindex $mem($addr) 0] != $bytes } {
146 error "byte count mismatch"
147 }
148 unset mem($addr)
149
150 # Decrease the current heap usage
151 incr ::nBytes [expr -1 * $bytes]
152
153 } elseif { [regexp $REALLOC $line dummy mallocid ob b oa a] } {
154 # "free" the old allocation in the internal model:
155 incr ::nBytes [expr -1 * $ob]
156 unset mem($oa);
157
158 # "malloc" the new allocation
159 set mem($a) [list $b "realloc $mallocid" $stack]
160 incr ::nBytes $b
161 set stack ""
162
163 # Increase the number of malloc() calls
164 incr ::nMalloc
165
166 if {$::nBytes > $::nPeak} {
167 set ::nPeak $::nBytes
168 set ::iPeak $::nMalloc
169 }
170
171 } else {
172 # puts "REJECT: $line"
173 }
174
175 if {$::nMalloc==$::report_at} report
176 }
177
178 close $input
179}
180
181proc printstack {stack} {
182 set fcount 10
183 if {[llength $stack]<10} {
184 set fcount [llength $stack]
185 }
186 foreach frame [lrange $stack 1 $fcount] {
187 foreach {f l} [split [exec $::addr2line -f --exe=$::exe $frame] \n] {}
188 puts [format "%-30s %s" $f $l]
189 }
190 if {[llength $stack]>0 } {puts ""}
191}
192
193proc report {} {
194
195 foreach key [array names ::memmap] {
196 set stack [lindex $::memmap($key) 2]
197 set bytes [lindex $::memmap($key) 0]
198 lappend summarymap($stack) $bytes
199 }
200
201 set sorted [list]
202 foreach stack [array names summarymap] {
203 set allocs $summarymap($stack)
204 set sum 0
205 foreach a $allocs {
206 incr sum $a
207 }
208 lappend sorted [list $sum $stack]
209 }
210
211 set sorted [lsort -integer -index 0 $sorted]
212 foreach s $sorted {
213 set sum [lindex $s 0]
214 set stack [lindex $s 1]
215 set allocs $summarymap($stack)
216 puts "$sum bytes in [llength $allocs] chunks ($allocs)"
217 printstack $stack
218 }
219
220 # Print out summary statistics
221 puts "Total allocations : $::nMalloc"
222 puts "Total outstanding allocations: [array size ::memmap]"
223 puts "Current heap usage : $::nBytes bytes"
224 puts "Peak heap usage : $::nPeak bytes (malloc #$::iPeak)"
225
226 exit
227}
228
229process_input $memfile memmap
230report
231
232
233