heapdump2dot.nim 2.1 KB

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