diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pure/nimtracker.nim | 20 | ||||
-rw-r--r-- | lib/system/memtracker.nim | 37 |
2 files changed, 45 insertions, 12 deletions
diff --git a/lib/pure/nimtracker.nim b/lib/pure/nimtracker.nim index 52fa9da77..acc242257 100644 --- a/lib/pure/nimtracker.nim +++ b/lib/pure/nimtracker.nim @@ -19,7 +19,15 @@ import sqlite3 var dbHandle: PSqlite3 - insertStmt: Pstmt + insertStmt {.threadvar.}: Pstmt + +const insertQuery = "INSERT INTO tracking(op, address, size, file, line) values (?, ?, ?, ?, ?)" + +when compileOption("threads"): + onThreadCreation do(): + if prepare_v2(dbHandle, insertQuery, + insertQuery.len, insertStmt, nil) != SQLITE_OK: + quit "could not bind query to insertStmt " & $sqlite3.errmsg(dbHandle) template sbind(x: int; value) = when value is cstring: @@ -32,7 +40,7 @@ template sbind(x: int; value) = quit "could not bind value" when defined(memTracker): - proc logEntries(log: TrackLog) {.nimcall, locks: 0, tags: [].} = + proc logEntries(log: TrackLog) {.nimcall, locks: 0, tags: [], gcsafe.} = for i in 0..log.count-1: var success = false let e = log.data[i] @@ -46,7 +54,7 @@ when defined(memTracker): if step(insertStmt) == SQLITE_DONE: success = true if not success: - quit "could not write to database!" + quit "could not write to database! " & $sqlite3.errmsg(dbHandle) proc execQuery(q: string) = var s: Pstmt @@ -71,10 +79,12 @@ proc setupDb() = if sqlite3.open("memtrack.db", dbHandle) == SQLITE_OK: setupDb() const query = "INSERT INTO tracking(op, address, size, file, line) values (?, ?, ?, ?, ?)" - if prepare_v2(dbHandle, query, - query.len, insertStmt, nil) == SQLITE_OK: + if prepare_v2(dbHandle, insertQuery, + insertQuery.len, insertStmt, nil) == SQLITE_OK: when defined(memTracker): setTrackLogger logEntries else: quit "could not prepare statement B " & $sqlite3.errmsg(dbHandle) +else: + quit "could not setup sqlite " & $sqlite3.errmsg(dbHandle) {.pop.} diff --git a/lib/system/memtracker.nim b/lib/system/memtracker.nim index a9767bbca..f37b0c45a 100644 --- a/lib/system/memtracker.nim +++ b/lib/system/memtracker.nim @@ -28,23 +28,46 @@ type TrackLog* = object count*: int disabled: bool - data*: array[4000, LogEntry] - TrackLogger* = proc (log: TrackLog) {.nimcall, tags: [], locks: 0.} + 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: - if gLog.count > high(gLog.data): - gLogger(gLog) - gLog.count = 0 - gLog.data[gLog.count] = entry - inc gLog.count + 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 = true + break + if interesting: + cprintf("interesting %s:%ld\n", entry.file, entry.line) + if gLog.count > high(gLog.data): + gLogger(gLog) + gLog.count = 0 + gLog.data[gLog.count] = entry + inc gLog.count proc memTrackerWrite(address: pointer; size: int; file: cstring; line: int) {.compilerProc.} = addEntry LogEntry(op: "write", address: address, |