preparations for easier debugging
This commit is contained in:
parent
3197ec8e72
commit
42a8ab34f1
5 changed files with 41 additions and 27 deletions
|
|
@ -18,6 +18,8 @@ type
|
||||||
when trackAllocationSource:
|
when trackAllocationSource:
|
||||||
filename: cstring
|
filename: cstring
|
||||||
line: int
|
line: int
|
||||||
|
when useCellIds:
|
||||||
|
id: int
|
||||||
|
|
||||||
PCell = ptr TCell
|
PCell = ptr TCell
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -170,24 +170,24 @@ proc `!$`(h: THash): THash {.inline.} =
|
||||||
result = result xor (result shr 11)
|
result = result xor (result shr 11)
|
||||||
result = result +% result shl 15
|
result = result +% result shl 15
|
||||||
|
|
||||||
proc hash(Data: Pointer, Size: int): THash =
|
proc hash(data: pointer, size: int): THash =
|
||||||
var h: THash = 0
|
var h: THash = 0
|
||||||
var p = cast[cstring](Data)
|
var p = cast[cstring](data)
|
||||||
var i = 0
|
var i = 0
|
||||||
var s = size
|
var s = size
|
||||||
while s > 0:
|
while s > 0:
|
||||||
h = h !& ord(p[i])
|
h = h !& ord(p[i])
|
||||||
Inc(i)
|
inc(i)
|
||||||
Dec(s)
|
cec(s)
|
||||||
result = !$h
|
result = !$h
|
||||||
|
|
||||||
proc hashGcHeader(data: pointer): THash =
|
proc hashGcHeader(data: pointer): THash =
|
||||||
const headerSize = sizeof(int)*2
|
const headerSize = sizeof(int)*2
|
||||||
result = hash(cast[pointer](cast[int](data) -% headerSize), headerSize)
|
result = hash(cast[pointer](cast[int](data) -% headerSize), headerSize)
|
||||||
|
|
||||||
proc genericHashAux(dest: Pointer, mt: PNimType, shallow: bool,
|
proc genericHashAux(dest: pointer, mt: PNimType, shallow: bool,
|
||||||
h: THash): THash
|
h: THash): THash
|
||||||
proc genericHashAux(dest: Pointer, n: ptr TNimNode, shallow: bool,
|
proc genericHashAux(dest: pointer, n: ptr TNimNode, shallow: bool,
|
||||||
h: THash): THash =
|
h: THash): THash =
|
||||||
var d = cast[TAddress](dest)
|
var d = cast[TAddress](dest)
|
||||||
case n.kind
|
case n.kind
|
||||||
|
|
@ -203,7 +203,7 @@ proc genericHashAux(dest: Pointer, n: ptr TNimNode, shallow: bool,
|
||||||
if m != nil: result = genericHashAux(dest, m, shallow, result)
|
if m != nil: result = genericHashAux(dest, m, shallow, result)
|
||||||
of nkNone: sysAssert(false, "genericHashAux")
|
of nkNone: sysAssert(false, "genericHashAux")
|
||||||
|
|
||||||
proc genericHashAux(dest: Pointer, mt: PNimType, shallow: bool,
|
proc genericHashAux(dest: pointer, mt: PNimType, shallow: bool,
|
||||||
h: THash): THash =
|
h: THash): THash =
|
||||||
sysAssert(mt != nil, "genericHashAux 2")
|
sysAssert(mt != nil, "genericHashAux 2")
|
||||||
case mt.Kind
|
case mt.Kind
|
||||||
|
|
@ -253,7 +253,7 @@ proc genericHashAux(dest: Pointer, mt: PNimType, shallow: bool,
|
||||||
else:
|
else:
|
||||||
result = h !& hash(dest, mt.size) # hash raw bits
|
result = h !& hash(dest, mt.size) # hash raw bits
|
||||||
|
|
||||||
proc genericHash(dest: Pointer, mt: PNimType): int =
|
proc genericHash(dest: pointer, mt: PNimType): int =
|
||||||
result = genericHashAux(dest, mt, false, 0)
|
result = genericHashAux(dest, mt, false, 0)
|
||||||
|
|
||||||
proc dbgRegisterWatchpoint(address: pointer, name: cstring,
|
proc dbgRegisterWatchpoint(address: pointer, name: cstring,
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ proc `==`(a: TStaticStr, b: cstring): bool =
|
||||||
proc write(f: TFile, s: TStaticStr) =
|
proc write(f: TFile, s: TStaticStr) =
|
||||||
write(f, cstring(s.data))
|
write(f, cstring(s.data))
|
||||||
|
|
||||||
proc ListBreakPoints() =
|
proc listBreakPoints() =
|
||||||
write(stdout, EndbBeg)
|
write(stdout, EndbBeg)
|
||||||
write(stdout, "| Breakpoints:\n")
|
write(stdout, "| Breakpoints:\n")
|
||||||
for b in listBreakpoints():
|
for b in listBreakpoints():
|
||||||
|
|
@ -117,7 +117,7 @@ proc writeVariable(stream: TFile, slot: TVarSlot) =
|
||||||
write(stream, " = ")
|
write(stream, " = ")
|
||||||
writeln(stream, dbgRepr(slot.address, slot.typ))
|
writeln(stream, dbgRepr(slot.address, slot.typ))
|
||||||
|
|
||||||
proc ListFrame(stream: TFile, f: PFrame) =
|
proc listFrame(stream: TFile, f: PFrame) =
|
||||||
write(stream, EndbBeg)
|
write(stream, EndbBeg)
|
||||||
write(stream, "| Frame (")
|
write(stream, "| Frame (")
|
||||||
write(stream, f.len)
|
write(stream, f.len)
|
||||||
|
|
@ -126,7 +126,7 @@ proc ListFrame(stream: TFile, f: PFrame) =
|
||||||
writeln(stream, getLocal(f, i).name)
|
writeln(stream, getLocal(f, i).name)
|
||||||
write(stream, EndbEnd)
|
write(stream, EndbEnd)
|
||||||
|
|
||||||
proc ListLocals(stream: TFile, f: PFrame) =
|
proc listLocals(stream: TFile, f: PFrame) =
|
||||||
write(stream, EndbBeg)
|
write(stream, EndbBeg)
|
||||||
write(stream, "| Frame (")
|
write(stream, "| Frame (")
|
||||||
write(stream, f.len)
|
write(stream, f.len)
|
||||||
|
|
@ -135,7 +135,7 @@ proc ListLocals(stream: TFile, f: PFrame) =
|
||||||
writeVariable(stream, getLocal(f, i))
|
writeVariable(stream, getLocal(f, i))
|
||||||
write(stream, EndbEnd)
|
write(stream, EndbEnd)
|
||||||
|
|
||||||
proc ListGlobals(stream: TFile) =
|
proc listGlobals(stream: TFile) =
|
||||||
write(stream, EndbBeg)
|
write(stream, EndbBeg)
|
||||||
write(stream, "| Globals:\n")
|
write(stream, "| Globals:\n")
|
||||||
for i in 0 .. getGlobalLen()-1:
|
for i in 0 .. getGlobalLen()-1:
|
||||||
|
|
@ -240,7 +240,7 @@ g, globals display available global variables
|
||||||
maxdisplay <integer> set the display's recursion maximum
|
maxdisplay <integer> set the display's recursion maximum
|
||||||
""")
|
""")
|
||||||
|
|
||||||
proc InvalidCommand() =
|
proc invalidCommand() =
|
||||||
debugOut("[Warning] invalid command ignored (type 'h' for help) ")
|
debugOut("[Warning] invalid command ignored (type 'h' for help) ")
|
||||||
|
|
||||||
proc hasExt(s: cstring): bool =
|
proc hasExt(s: cstring): bool =
|
||||||
|
|
@ -272,7 +272,7 @@ proc createBreakPoint(s: cstring, start: int) =
|
||||||
if not addBreakpoint(br.filename, br.low, br.high):
|
if not addBreakpoint(br.filename, br.low, br.high):
|
||||||
debugOut("[Warning] no breakpoint could be set; out of breakpoint space ")
|
debugOut("[Warning] no breakpoint could be set; out of breakpoint space ")
|
||||||
|
|
||||||
proc BreakpointToggle(s: cstring, start: int) =
|
proc breakpointToggle(s: cstring, start: int) =
|
||||||
var a = parseBreakpoint(s, start)
|
var a = parseBreakpoint(s, start)
|
||||||
if not a.filename.isNil:
|
if not a.filename.isNil:
|
||||||
var b = checkBreakpoints(a.filename, a.low)
|
var b = checkBreakpoints(a.filename, a.low)
|
||||||
|
|
@ -316,13 +316,13 @@ proc dbgStackFrame(s: cstring, start: int, currFrame: PFrame) =
|
||||||
var i = scanFilename(s, dbgTemp, start)
|
var i = scanFilename(s, dbgTemp, start)
|
||||||
if dbgTemp.len == 0:
|
if dbgTemp.len == 0:
|
||||||
# just write it to stdout:
|
# just write it to stdout:
|
||||||
ListFrame(stdout, currFrame)
|
listFrame(stdout, currFrame)
|
||||||
else:
|
else:
|
||||||
var stream = openAppend(dbgTemp.data)
|
var stream = openAppend(dbgTemp.data)
|
||||||
if stream == nil:
|
if stream == nil:
|
||||||
debugOut("[Warning] could not open or create file ")
|
debugOut("[Warning] could not open or create file ")
|
||||||
return
|
return
|
||||||
ListFrame(stream, currFrame)
|
listFrame(stream, currFrame)
|
||||||
close(stream)
|
close(stream)
|
||||||
|
|
||||||
proc readLine(f: TFile, line: var TStaticStr): bool =
|
proc readLine(f: TFile, line: var TStaticStr): bool =
|
||||||
|
|
@ -339,7 +339,7 @@ proc readLine(f: TFile, line: var TStaticStr): bool =
|
||||||
add line, chr(int(c))
|
add line, chr(int(c))
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
proc ListFilenames() =
|
proc listFilenames() =
|
||||||
write(stdout, EndbBeg)
|
write(stdout, EndbBeg)
|
||||||
write(stdout, "| Files:\n")
|
write(stdout, "| Files:\n")
|
||||||
var i = 0
|
var i = 0
|
||||||
|
|
@ -352,7 +352,7 @@ proc ListFilenames() =
|
||||||
write(stdout, EndbEnd)
|
write(stdout, EndbEnd)
|
||||||
|
|
||||||
proc dbgWriteStackTrace(f: PFrame)
|
proc dbgWriteStackTrace(f: PFrame)
|
||||||
proc CommandPrompt() =
|
proc commandPrompt() =
|
||||||
# if we return from this routine, user code executes again
|
# if we return from this routine, user code executes again
|
||||||
var
|
var
|
||||||
again = True
|
again = True
|
||||||
|
|
@ -426,11 +426,11 @@ proc CommandPrompt() =
|
||||||
elif ?"b" or ?"break":
|
elif ?"b" or ?"break":
|
||||||
createBreakPoint(dbgUser.data, i)
|
createBreakPoint(dbgUser.data, i)
|
||||||
elif ?"breakpoints":
|
elif ?"breakpoints":
|
||||||
ListBreakPoints()
|
listBreakPoints()
|
||||||
elif ?"toggle":
|
elif ?"toggle":
|
||||||
BreakpointToggle(dbgUser.data, i)
|
breakpointToggle(dbgUser.data, i)
|
||||||
elif ?"filenames":
|
elif ?"filenames":
|
||||||
ListFilenames()
|
listFilenames()
|
||||||
elif ?"maxdisplay":
|
elif ?"maxdisplay":
|
||||||
var parsed: int
|
var parsed: int
|
||||||
i = scanNumber(dbgUser.data, parsed, i)
|
i = scanNumber(dbgUser.data, parsed, i)
|
||||||
|
|
@ -438,15 +438,15 @@ proc CommandPrompt() =
|
||||||
if parsed == 0: maxDisplayRecDepth = -1
|
if parsed == 0: maxDisplayRecDepth = -1
|
||||||
else: maxDisplayRecDepth = parsed
|
else: maxDisplayRecDepth = parsed
|
||||||
else:
|
else:
|
||||||
InvalidCommand()
|
invalidCommand()
|
||||||
else: InvalidCommand()
|
else: invalidCommand()
|
||||||
|
|
||||||
proc endbStep() =
|
proc endbStep() =
|
||||||
# we get into here if an unhandled exception has been raised
|
# we get into here if an unhandled exception has been raised
|
||||||
# XXX: do not allow the user to run the program any further?
|
# XXX: do not allow the user to run the program any further?
|
||||||
# XXX: BUG: the frame is lost here!
|
# XXX: BUG: the frame is lost here!
|
||||||
dbgShowExecutionPoint()
|
dbgShowExecutionPoint()
|
||||||
CommandPrompt()
|
commandPrompt()
|
||||||
|
|
||||||
proc dbgWriteStackTrace(f: PFrame) =
|
proc dbgWriteStackTrace(f: PFrame) =
|
||||||
const
|
const
|
||||||
|
|
@ -506,18 +506,18 @@ proc checkForBreakpoint =
|
||||||
write(stdout, ") ")
|
write(stdout, ") ")
|
||||||
write(stdout, framePtr.procname)
|
write(stdout, framePtr.procname)
|
||||||
write(stdout, " ***\n")
|
write(stdout, " ***\n")
|
||||||
CommandPrompt()
|
commandPrompt()
|
||||||
|
|
||||||
proc lineHookImpl() {.nimcall.} =
|
proc lineHookImpl() {.nimcall.} =
|
||||||
case dbgState
|
case dbgState
|
||||||
of dbStepInto:
|
of dbStepInto:
|
||||||
# we really want the command prompt here:
|
# we really want the command prompt here:
|
||||||
dbgShowExecutionPoint()
|
dbgShowExecutionPoint()
|
||||||
CommandPrompt()
|
commandPrompt()
|
||||||
of dbSkipCurrent, dbStepOver: # skip current routine
|
of dbSkipCurrent, dbStepOver: # skip current routine
|
||||||
if framePtr == dbgSkipToFrame:
|
if framePtr == dbgSkipToFrame:
|
||||||
dbgShowExecutionPoint()
|
dbgShowExecutionPoint()
|
||||||
CommandPrompt()
|
commandPrompt()
|
||||||
else:
|
else:
|
||||||
# breakpoints are wanted though (I guess)
|
# breakpoints are wanted though (I guess)
|
||||||
checkForBreakpoint()
|
checkForBreakpoint()
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,8 @@ type
|
||||||
# non-zero count table
|
# non-zero count table
|
||||||
stackBottom: pointer
|
stackBottom: pointer
|
||||||
cycleThreshold: int
|
cycleThreshold: int
|
||||||
|
when useCellIds:
|
||||||
|
idGenerator: int
|
||||||
zct: TCellSeq # the zero count table
|
zct: TCellSeq # the zero count table
|
||||||
decStack: TCellSeq # cells in the stack that are to decref again
|
decStack: TCellSeq # cells in the stack that are to decref again
|
||||||
cycleRoots: TCellSet
|
cycleRoots: TCellSet
|
||||||
|
|
@ -437,6 +439,9 @@ proc rawNewObj(typ: PNimType, size: int, gch: var TGcHeap): pointer =
|
||||||
when logGC: writeCell("new cell", res)
|
when logGC: writeCell("new cell", res)
|
||||||
gcTrace(res, csAllocated)
|
gcTrace(res, csAllocated)
|
||||||
release(gch)
|
release(gch)
|
||||||
|
when useCellIds:
|
||||||
|
inc gch.idGenerator
|
||||||
|
res.id = gch.idGenerator
|
||||||
result = cellToUsr(res)
|
result = cellToUsr(res)
|
||||||
sysAssert(allocInv(gch.region), "rawNewObj end")
|
sysAssert(allocInv(gch.region), "rawNewObj end")
|
||||||
|
|
||||||
|
|
@ -477,6 +482,9 @@ proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} =
|
||||||
when logGC: writeCell("new cell", res)
|
when logGC: writeCell("new cell", res)
|
||||||
gcTrace(res, csAllocated)
|
gcTrace(res, csAllocated)
|
||||||
release(gch)
|
release(gch)
|
||||||
|
when useCellIds:
|
||||||
|
inc gch.idGenerator
|
||||||
|
res.id = gch.idGenerator
|
||||||
result = cellToUsr(res)
|
result = cellToUsr(res)
|
||||||
zeroMem(result, size)
|
zeroMem(result, size)
|
||||||
sysAssert(allocInv(gch.region), "newObjRC1 end")
|
sysAssert(allocInv(gch.region), "newObjRC1 end")
|
||||||
|
|
@ -532,6 +540,9 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
|
||||||
sysAssert(ol.typ != nil, "growObj: 5")
|
sysAssert(ol.typ != nil, "growObj: 5")
|
||||||
zeroMem(ol, sizeof(TCell))
|
zeroMem(ol, sizeof(TCell))
|
||||||
release(gch)
|
release(gch)
|
||||||
|
when useCellIds:
|
||||||
|
inc gch.idGenerator
|
||||||
|
res.id = gch.idGenerator
|
||||||
result = cellToUsr(res)
|
result = cellToUsr(res)
|
||||||
sysAssert(allocInv(gch.region), "growObj end")
|
sysAssert(allocInv(gch.region), "growObj end")
|
||||||
when defined(memProfiler): nimProfile(newsize-oldsize)
|
when defined(memProfiler): nimProfile(newsize-oldsize)
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ const
|
||||||
coalescRight = true
|
coalescRight = true
|
||||||
coalescLeft = true
|
coalescLeft = true
|
||||||
logAlloc = false
|
logAlloc = false
|
||||||
|
useCellIds = defined(corruption)
|
||||||
|
|
||||||
type
|
type
|
||||||
PPointer = ptr pointer
|
PPointer = ptr pointer
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue