1# 2# 3# Nim's Runtime Library 4# (c) Copyright 2016 Andreas Rumpf 5# 6# See the file "copying.txt", included in this 7# distribution, for details about the copyright. 8# 9 10## Memory tracking support for Nim. 11 12when not defined(memTracker) and not isMainModule: 13 {.error: "Memory tracking support is turned off!".} 14 15{.push memtracker: off.} 16# we import the low level wrapper and are careful not to use Nim's 17# memory manager for anything here. 18import sqlite3 19 20var 21 dbHandle: PSqlite3 22 insertStmt {.threadvar.}: Pstmt 23 24const insertQuery = "INSERT INTO tracking(op, address, size, file, line) values (?, ?, ?, ?, ?)" 25 26template sbind(x: int; value) = 27 when value is cstring: 28 let ret = insertStmt.bindText(x, value, value.len.int32, SQLITE_TRANSIENT) 29 if ret != SQLITE_OK: 30 quit "could not bind value" 31 else: 32 let ret = insertStmt.bindInt64(x, value) 33 if ret != SQLITE_OK: 34 quit "could not bind value" 35 36when defined(memTracker): 37 proc logEntries(log: TrackLog) {.nimcall, locks: 0, tags: [], gcsafe.} = 38 if insertStmt.isNil: 39 if prepare_v2(dbHandle, insertQuery, 40 insertQuery.len, insertStmt, nil) != SQLITE_OK: 41 quit "could not bind query to insertStmt " & $sqlite3.errmsg(dbHandle) 42 for i in 0..log.count-1: 43 var success = false 44 let e = log.data[i] 45 discard sqlite3.reset(insertStmt) 46 discard clearBindings(insertStmt) 47 sbind 1, e.op 48 sbind(2, cast[int](e.address)) 49 sbind 3, e.size 50 sbind 4, e.file 51 sbind 5, e.line 52 if step(insertStmt) == SQLITE_DONE: 53 success = true 54 if not success: 55 quit "could not write to database! " & $sqlite3.errmsg(dbHandle) 56 57proc execQuery(q: string) = 58 var s: Pstmt 59 if prepare_v2(dbHandle, q, q.len.int32, s, nil) == SQLITE_OK: 60 discard step(s) 61 if finalize(s) != SQLITE_OK: 62 quit "could not finalize " & $sqlite3.errmsg(dbHandle) 63 else: 64 quit "could not prepare statement " & $sqlite3.errmsg(dbHandle) 65 66proc setupDb() = 67 execQuery """create table if not exists tracking( 68 id integer primary key, 69 op varchar not null, 70 address integer not null, 71 size integer not null, 72 file varchar not null, 73 line integer not null 74 )""" 75 execQuery "delete from tracking" 76 77if sqlite3.open("memtrack.db", dbHandle) == SQLITE_OK: 78 setupDb() 79 const query = "INSERT INTO tracking(op, address, size, file, line) values (?, ?, ?, ?, ?)" 80 if prepare_v2(dbHandle, insertQuery, 81 insertQuery.len, insertStmt, nil) == SQLITE_OK: 82 when defined(memTracker): 83 setTrackLogger logEntries 84 else: 85 quit "could not prepare statement B " & $sqlite3.errmsg(dbHandle) 86else: 87 quit "could not setup sqlite " & $sqlite3.errmsg(dbHandle) 88{.pop.} 89