1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
include prelude
proc main(input, output: string) =
type NodeKind = enum
local, localInvalid, global, globalInvalid
#c_fprintf(file, "%s %p %d rc=%ld color=%c\n",
# msg, c, kind, c.refcount shr rcShift, col)
# cell 0x10a908190 22 rc=2 color=w
var i, o: File
var roots = initTable[string, NodeKind]()
if open(i, input):
if open(o, output, fmWrite):
o.writeLine("digraph $1 {\n" % extractFilename(input))
var currNode = ""
for line in lines(i):
let data = line.split()
if data.len == 0: continue
case data[0]
of "end":
currNode = ""
of "cell":
currNode = data[1]
let rc = data[3].substr("rc=".len)
let col = case data[4].substr("color=".len)
of "b": "black"
of "w": "green"
of "g": "grey"
else: ""
o.write("N" & currNode)
if currNode in roots:
let v = roots[currNode]
case v
of local: o.write(" [label=\"local \\N\" fillcolor=$1]" % col)
of localInvalid: o.write(" [label=\"local invalid \\N\" fillcolor=$1]" % col)
of global: o.write(" [label=\"global \\N\" fillcolor=$1]" % col)
of globalInvalid: o.write(" [label=\"global invalid \\N\" fillcolor=$1]" % col)
else:
o.write(" [fillcolor=$1]" % col)
o.writeLine(";")
of "child":
assert currNode.len > 0
o.writeLine("N$1 -> N$2;" % [currNode, data[1]])
of "global_root":
roots[data[1]] = global
of "global_root_invalid":
roots[data[1]] = globalInvalid
of "onstack":
roots[data[1]] = local
of "onstack_invalid":
roots[data[1]] = localInvalid
else: discard
close(i)
o.writeLine("\n}")
close(o)
else:
quit "error: cannot open " & output
else:
quit "error: cannot open " & input
if paramCount() == 1:
main(paramStr(1), changeFileExt(paramStr(1), "dot"))
elif paramCount() == 2:
main(paramStr(1), paramStr(2))
else:
quit "usage: heapdump2dot inputfile outputfile"
|