summary refs log tree commit diff stats
path: root/tests/misc/tnot.nim
diff options
context:
space:
mode:
Diffstat (limited to 'tests/misc/tnot.nim')
0 files changed, 0 insertions, 0 deletions
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
#
#
#            Nim's Runtime Library
#        (c) Copyright 2016 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

## Memory tracking support for Nim.

when not defined(memTracker):
  {.error: "Memory tracking support is turned off! Enable memory tracking by passing `--memtracker:on` to the compiler (see the Nim Compiler User Guide for more options).".}

when defined(noSignalHandler):
  {.error: "Memory tracking works better with the default signal handler.".}

# We don't want to memtrack the tracking code ...
{.push memtracker: off.}

when declared(getThreadId):
  template myThreadId(): untyped = getThreadId()
else:
  template myThreadId(): untyped = 0

type
  LogEntry* = object
    op*: cstring
    address*: pointer
    size*: int
    file*: cstring
    line*: int
    thread*: int
  TrackLog* = object
    count*: int
    disabled: bool
    data*: array[400, LogEntry]
  TrackLogger* = proc (log: TrackLog) {.nimcall, tags: [], locks: 0, gcsafe.}

var
  gLog*: TrackLog
  gLogger*: TrackLogger = proc (log: TrackLog) = discard
  ilocs: array[4000, (int, int)]
  ilocn: int

proc trackLocation*(p: pointer; size: int) =
  let x = (cast[int](p), size)
  for i in 0..ilocn-1:
    # already known?
    if ilocs[i] == x: return
  ilocs[ilocn] = x
  inc ilocn

proc setTrackLogger*(logger: TrackLogger) =
  gLogger = logger

proc addEntry(entry: LogEntry) =
  if not gLog.disabled:
    var interesting = false
    for i in 0..ilocn-1:
      let p = ilocs[i]
      #  X..Y and C..D overlap iff (X <= D and C <= Y)
      let x = p[0]
      let y = p[0]+p[1]-1
      let c = cast[int](entry.address)
      let d = c + entry.size-1
      if x <= d and c <= y:
        interesting = myThreadId() != entry.thread # true
        break
    if interesting:
      gLog.disabled = true
      cprintf("interesting %s:%ld %s\n", entry.file, entry.line, entry.op)
      let x = cast[proc() {.nimcall, tags: [], gcsafe, locks: 0, raises: [].}](writeStackTrace)
      x()
      quit 1
      #if gLog.count > high(gLog.data):
      #  gLogger(gLog)
      #  gLog.count = 0
      #gLog.data[gLog.count] = entry
      #inc gLog.count
      #gLog.disabled = false

proc memTrackerWrite(address: pointer; size: int; file: cstring; line: int) {.compilerproc.} =
  addEntry LogEntry(op: "write", address: address,
      size: size, file: file, line: line, thread: myThreadId())

proc memTrackerOp*(op: cstring; address: pointer; size: int) {.tags: [],
         locks: 0, gcsafe.} =
  addEntry LogEntry(op: op, address: address, size: size,
      file: "", line: 0, thread: myThreadId())

proc memTrackerDisable*() =
  gLog.disabled = true

proc memTrackerEnable*() =
  gLog.disabled = false

proc logPendingOps() {.noconv.} =
  # forward declared and called from Nim's signal handler.
  gLogger(gLog)
  gLog.count = 0

addQuitProc logPendingOps

{.pop.}