summaryrefslogtreecommitdiff
path: root/support
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2016-09-06 21:06:23 -0700
committerOri Bernstein <ori@eigenstate.org>2016-09-06 21:06:23 -0700
commitd5c4a8280725d9430ba07530e5be0f08f29be936 (patch)
treeede3a52e54e12af8741fb2b025ae2e759c583eb9 /support
parentd260994d8a89a651868a21677a42a9d21de7e46f (diff)
downloadmc-d5c4a8280725d9430ba07530e5be0f08f29be936.tar.gz
Add in support for dumping a summary of leaks.
Thanks to Andrew Chambers for writing the initial draft of this code.
Diffstat (limited to 'support')
-rw-r--r--support/bld.sub2
-rw-r--r--support/dumpleak.myr51
2 files changed, 41 insertions, 12 deletions
diff --git a/support/bld.sub b/support/bld.sub
index bdb34cc..4f76208 100644
--- a/support/bld.sub
+++ b/support/bld.sub
@@ -1,4 +1,4 @@
-bin dumpleak =
+bin mdumpleak =
dumpleak.myr
lib ../lib/sys:sys
diff --git a/support/dumpleak.myr b/support/dumpleak.myr
index 06a4953..9ab20e8 100644
--- a/support/dumpleak.myr
+++ b/support/dumpleak.myr
@@ -2,15 +2,26 @@ use std
use bio
var stackaggr = 10
+var summary
+
+type memstats = struct
+ allocs : uint64
+ allocsz : uint64
+ frees : uint64
+ freesz : uint64
+ tab : std.htab(uint64, (uint64, uint64[:]))#
+;;
+
const main = {args
- var tab : std.htab(int64, (int64, int64[:]))#
var cmd
+ var stats : memstats
cmd = std.optparse(args, &[
.argdesc="dumps...",
.opts=[
[.opt='d', .arg="depth", .desc="aggregate by at most `depth` stack elements"],
+ [.opt='s', .arg="", .desc="only show a summary of memory activity"],
][:]
])
@@ -21,33 +32,47 @@ const main = {args
| `std.Some d: stackaggr = d
| `std.None: std.fatal("could not parse stack depth {}\n", depth)
;;
+ | ('s', ""):
+ summary = true
| _: std.die("unreachable")
;;
;;
- tab = std.mkht(std.inthash, std.inteq)
+ stats.tab = std.mkht(std.inthash, std.inteq)
for d in cmd.args
match bio.open(d, bio.Rd)
- | `std.Ok f: dump(d, f, tab)
+ | `std.Ok f: dump(d, f, &stats)
| `std.Err e: std.fatal("could not open {}: {}\n", d, e)
;;
;;
}
-const dump = {path, f, tab
+const dump = {path, f, stats
while true
match bio.getle64(f)
- | `bio.Ok 0: tracealloc(path, f, tab)
- | `bio.Ok 1: tracefree(path, f, tab)
+ | `bio.Ok 0: tracealloc(path, f, stats)
+ | `bio.Ok 1: tracefree(path, f, stats)
| `bio.Eof: break
| `bio.Ok wat: std.fatal("unknown action type {x}\n", wat)
| `bio.Err e: std.fatal("failed to read {}: {}\n", path, e)
;;
;;
- dumptrace(tab)
+ if !summary
+ dumptrace(stats.tab)
+ ;;
+ dumpsummary(stats)
}
-const tracealloc = {path, f, tab
+const dumpsummary = {stats
+ std.put("allocs:\t{}\n", stats.allocs)
+ std.put("allocsz:\t{}\n", stats.allocsz)
+ std.put("frees:\t{}\n", stats.frees)
+ std.put("freesz:\t{}\n", stats.freesz)
+ std.put("livesz:\t{}\n", stats.allocsz - stats.freesz)
+}
+
+
+const tracealloc = {path, f, stats
var ptr, sz, stk
ptr = get64(path, f)
@@ -56,15 +81,19 @@ const tracealloc = {path, f, tab
for var i = 0; i < 10; i++
std.slpush(&stk, get64(path, f))
;;
- std.htput(tab, ptr, (sz, stk))
+ stats.allocs++
+ stats.allocsz += sz
+ std.htput(stats.tab, ptr, (sz, stk))
}
-const tracefree = {path, f, tab
+const tracefree = {path, f, stats
var ptr, sz
ptr = get64(path, f)
sz = get64(path, f)
- std.htdel(tab, ptr)
+ stats.allocs++
+ stats.allocsz += sz
+ std.htdel(stats.tab, ptr)
}
const dumptrace = {tab