summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ccgstmts.nim26
-rw-r--r--compiler/cgen.nim45
-rw-r--r--compiler/cgendata.nim2
-rw-r--r--compiler/commands.nim24
-rw-r--r--compiler/jsgen.nim6
-rw-r--r--compiler/options.nim1
-rw-r--r--compiler/pragmas.nim15
-rw-r--r--compiler/wordrecg.nim8
-rw-r--r--doc/endb.rst203
-rw-r--r--lib/system.nim7
-rw-r--r--lib/system/debugger.nim303
-rw-r--r--lib/system/endb.nim579
-rw-r--r--lib/system/excpt.nim12
-rw-r--r--tests/gc/gcleak4.nim2
-rw-r--r--tests/misc/thallo.nim1
-rw-r--r--tests/objects/tobjects_various.nim1
16 files changed, 19 insertions, 1216 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index bfd053f2d..ffeeb0db9 100644
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -1161,36 +1161,10 @@ proc genEmit(p: BProc, t: PNode) =
     genLineDir(p, t)
     line(p, cpsStmts, s)
 
-proc genBreakPoint(p: BProc, t: PNode) =
-  var name: string
-  if optEndb in p.options:
-    if t.kind == nkExprColonExpr:
-      assert(t.sons[1].kind in {nkStrLit..nkTripleStrLit})
-      name = normalize(t.sons[1].strVal)
-    else:
-      inc(p.module.g.breakPointId)
-      name = "bp" & $p.module.g.breakPointId
-    genLineDir(p, t)          # BUGFIX
-    appcg(p.module, p.module.g.breakpoints,
-         "#dbgRegisterBreakpoint($1, (NCSTRING)$2, (NCSTRING)$3);$n", [
-        toLinenumber(t.info), makeCString(toFilename(p.config, t.info)),
-        makeCString(name)])
-
-proc genWatchpoint(p: BProc, n: PNode) =
-  if optEndb notin p.options: return
-  var a: TLoc
-  initLocExpr(p, n.sons[1], a)
-  let typ = skipTypes(n.sons[1].typ, abstractVarRange)
-  lineCg(p, cpsStmts, "#dbgRegisterWatchpoint($1, (NCSTRING)$2, $3);$n",
-        [addrLoc(p.config, a), makeCString(renderTree(n.sons[1])),
-        genTypeInfo(p.module, typ, n.info)])
-
 proc genPragma(p: BProc, n: PNode) =
   for it in n.sons:
     case whichPragma(it)
     of wEmit: genEmit(p, it)
-    of wBreakpoint: genBreakPoint(p, it)
-    of wWatchPoint: genWatchpoint(p, it)
     of wInjectStmt:
       var p = newProc(nil, p.module)
       p.options = p.options - {optLineTrace, optStackTrace}
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 033003485..6e79b2d7b 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -264,13 +264,7 @@ proc genLineDir(p: BProc, t: PNode) =
   if optEmbedOrigSrc in p.config.globalOptions:
     add(p.s(cpsStmts), ~"//" & sourceLine(p.config, t.info) & "\L")
   genCLineDir(p.s(cpsStmts), toFullPath(p.config, t.info), line, p.config)
-  if ({optStackTrace, optEndb} * p.options == {optStackTrace, optEndb}) and
-      (p.prc == nil or sfPure notin p.prc.flags):
-    if freshLineInfo(p, t.info):
-      linefmt(p, cpsStmts, "#endb($1, $2);$N",
-              [line, makeCString(toFilename(p.config, t.info))])
-  elif ({optLineTrace, optStackTrace} * p.options ==
-      {optLineTrace, optStackTrace}) and
+  if ({optLineTrace, optStackTrace} * p.options == {optLineTrace, optStackTrace}) and
       (p.prc == nil or sfPure notin p.prc.flags) and t.info.fileIndex != InvalidFileIdx:
     if freshLineInfo(p, t.info):
       linefmt(p, cpsStmts, "nimln_($1, $2);$n",
@@ -479,19 +473,6 @@ proc deinitGCFrame(p: BProc): Rope =
     result = ropecg(p.module,
                     "if (((NU)&GCFRAME_) < 4096) #nimGCFrame(&GCFRAME_);$n", [])
 
-proc localDebugInfo(p: BProc, s: PSym, retType: PType) =
-  if {optStackTrace, optEndb} * p.options != {optStackTrace, optEndb}: return
-  # XXX work around a bug: No type information for open arrays possible:
-  if skipTypes(s.typ, abstractVar).kind in {tyOpenArray, tyVarargs}: return
-  var a = "&" & s.loc.r
-  if s.kind == skParam and ccgIntroducedPtr(p.config, s, retType): a = s.loc.r
-  lineF(p, cpsInit,
-       "FR_.s[$1].address = (void*)$3; FR_.s[$1].typ = $4; FR_.s[$1].name = $2;$n",
-       [p.maxFrameLen.rope, makeCString(normalize(s.name.s)), a,
-        genTypeInfo(p.module, s.loc.t, s.info)])
-  inc(p.maxFrameLen)
-  inc p.blocks[p.blocks.len-1].frameLen
-
 proc localVarDecl(p: BProc; n: PNode): Rope =
   let s = n.sym
   if s.loc.k == locNone:
@@ -515,7 +496,6 @@ proc assignLocalVar(p: BProc, n: PNode) =
   let nl = if optLineDir in p.config.options: "" else: "\L"
   let decl = localVarDecl(p, n) & ";" & nl
   line(p, cpsLocals, decl)
-  localDebugInfo(p, n.sym, nil)
 
 include ccgthreadvars
 
@@ -562,17 +542,10 @@ proc assignGlobalVar(p: BProc, n: PNode) =
   if p.withinLoop > 0:
     # fixes tests/run/tzeroarray:
     resetLoc(p, s.loc)
-  if p.module.module.options * {optStackTrace, optEndb} ==
-                               {optStackTrace, optEndb}:
-    appcg(p.module, p.module.s[cfsDebugInit],
-          "#dbgRegisterGlobal($1, &$2, $3);$n",
-         [makeCString(normalize(s.owner.name.s & '.' & s.name.s)),
-          s.loc.r, genTypeInfo(p.module, s.typ, n.info)])
 
 proc assignParam(p: BProc, s: PSym, retType: PType) =
   assert(s.loc.r != nil)
   scopeMangledParam(p, s)
-  localDebugInfo(p, s, retType)
 
 proc fillProcLoc(m: BModule; n: PNode) =
   let sym = n.sym
@@ -689,7 +662,7 @@ proc loadDynamicLib(m: BModule, lib: PLib) =
             [loadlib, genStringLiteral(m, lib.path)])
     else:
       var p = newProc(nil, m)
-      p.options = p.options - {optStackTrace, optEndb}
+      p.options = p.options - {optStackTrace}
       var dest: TLoc
       initLoc(dest, locTemp, lib.path, OnStack)
       dest.r = getTempName(m)
@@ -1318,7 +1291,6 @@ proc genMainProc(m: BModule) =
     PreMainBody = "$N" &
       "void PreMainInner(void) {$N" &
       "$2" &
-      "$3" &
       "}$N$N" &
       PosixCmdLine &
       "void PreMain(void) {$N" &
@@ -1408,17 +1380,11 @@ proc genMainProc(m: BModule) =
   elif m.config.target.targetOS == osGenode:
     m.includeHeader("<libc/component.h>")
 
-  if optEndb in m.config.options:
-    for i in 0..<m.config.m.fileInfos.len:
-      m.g.breakpoints.addf("dbgRegisterFilename($1);$N",
-        [m.config.m.fileInfos[i].projPath.string.makeCString])
-
   let initStackBottomCall =
     if m.config.target.targetOS == osStandalone or m.config.selectedGC == gcNone: "".rope
     else: ropecg(m, "\t#initStackBottomWith((void *)&inner);$N", [])
   inc(m.labels)
-  appcg(m, m.s[cfsProcs], PreMainBody, [
-    m.g.mainDatInit, m.g.breakpoints, m.g.otherModsInit])
+  appcg(m, m.s[cfsProcs], PreMainBody, [m.g.mainDatInit, m.g.otherModsInit])
 
   if m.config.target.targetOS == osWindows and
       m.config.globalOptions * {optGenGuiApp, optGenDynLib} != {}:
@@ -2024,11 +1990,6 @@ proc myClose(graph: ModuleGraph; b: PPassContext, n: PNode): PNode =
       if emulatedThreadVars(m.config) and m.config.target.targetOS != osStandalone:
         discard cgsym(m, "initThreadVarsEmulation")
 
-      if m.g.breakpoints != nil:
-        discard cgsym(m, "dbgRegisterBreakpoint")
-      if optEndb in m.config.options:
-        discard cgsym(m, "dbgRegisterFilename")
-
       if m.g.forwardedProcs.len == 0:
         incl m.flags, objHasKidsValid
       let disp = generateMethodDispatchers(graph)
diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim
index 47b0f23ec..0035931f0 100644
--- a/compiler/cgendata.nim
+++ b/compiler/cgendata.nim
@@ -117,8 +117,6 @@ type
     modulesClosed*: seq[BModule] # list of the same compiled modules, but in the order they were closed
     forwardedProcs*: seq[PSym] # proc:s that did not yet have a body
     generatedHeader*: BModule
-    breakPointId*: int
-    breakpoints*: Rope # later the breakpoints are inserted into the main proc
     typeInfoMarker*: TypeCacheWithOwner
     config*: ConfigRef
     graph*: ModuleGraph
diff --git a/compiler/commands.nim b/compiler/commands.nim
index 662df9c84..5b6f3ac0f 100644
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -266,7 +266,7 @@ proc testCompileOption*(conf: ConfigRef; switch: string, info: TLineInfo): bool
   of "threadanalysis": result = contains(conf.globalOptions, optThreadAnalysis)
   of "stacktrace": result = contains(conf.options, optStackTrace)
   of "linetrace": result = contains(conf.options, optLineTrace)
-  of "debugger": result = contains(conf.options, optEndb)
+  of "debugger": result = contains(conf.globalOptions, optCDebug)
   of "profiler": result = contains(conf.options, optProfiler)
   of "memtracker": result = contains(conf.options, optMemTracker)
   of "checks", "x": result = conf.options * ChecksOptions == ChecksOptions
@@ -473,24 +473,18 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
   of "linetrace": processOnOffSwitch(conf, {optLineTrace}, arg, pass, info)
   of "debugger":
     case arg.normalize
-    of "on", "endb":
-      conf.options.incl optEndb
-      defineSymbol(conf.symbols, "endb")
-    of "off":
-      conf.options.excl optEndb
-      undefSymbol(conf.symbols, "endb")
-    of "native", "gdb":
-      incl(conf.globalOptions, optCDebug)
-      conf.options = conf.options + {optLineDir} - {optEndb}
+    of "on", "native", "gdb":
+      conf.globalOptions.incl optCDebug
+      conf.options.incl optLineDir
       #defineSymbol(conf.symbols, "nimTypeNames") # type names are used in gdb pretty printing
-      undefSymbol(conf.symbols, "endb")
+    of "off":
+      conf.globalOptions.excl optCDebug
     else:
-      localError(conf, info, "expected endb|gdb but found " & arg)
+      localError(conf, info, "expected native|gdb|on|off but found " & arg)
   of "g": # alias for --debugger:native
-    incl(conf.globalOptions, optCDebug)
-    conf.options = conf.options + {optLineDir} - {optEndb}
+    conf.globalOptions.incl optCDebug
+    conf.options.incl optLineDir
     #defineSymbol(conf.symbols, "nimTypeNames") # type names are used in gdb pretty printing
-    undefSymbol(conf.symbols, "endb")
   of "profiler":
     processOnOffSwitch(conf, {optProfiler}, arg, pass, info)
     if optProfiler in conf.options: defineSymbol(conf.symbols, "profiler")
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim
index 5391a451b..107fa2b28 100644
--- a/compiler/jsgen.nim
+++ b/compiler/jsgen.nim
@@ -658,11 +658,7 @@ proc genLineDir(p: PProc, n: PNode) =
   if optLineDir in p.options:
     lineF(p, "// line $2 \"$1\"$n",
          [rope(toFilename(p.config, n.info)), rope(line)])
-  if {optStackTrace, optEndb} * p.options == {optStackTrace, optEndb} and
-      ((p.prc == nil) or sfPure notin p.prc.flags):
-    useMagic(p, "endb")
-    lineF(p, "endb($1);$n", [rope(line)])
-  elif hasFrameInfo(p):
+  if hasFrameInfo(p):
     lineF(p, "F.line = $1;$n", [rope(line)])
 
 proc genWhileStmt(p: PProc, n: PNode) =
diff --git a/compiler/options.nim b/compiler/options.nim
index 8b5ade727..1b9bbb38f 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -30,7 +30,6 @@ type                          # please make sure we have under 32 options
     optAssert, optLineDir, optWarns, optHints,
     optOptimizeSpeed, optOptimizeSize, optStackTrace, # stack tracing support
     optLineTrace,             # line tracing support (includes stack tracing)
-    optEndb,                  # embedded debugger
     optByRef,                 # use pass by ref for objects
                               # (for interfacing with C)
     optProfiler,              # profiler turned on
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index 000066b8e..3de12cfa9 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -44,7 +44,7 @@ const
     wWarnings, wHints,
     wLineDir, wStackTrace, wLineTrace, wOptimization, wHint, wWarning, wError,
     wFatal, wDefine, wUndef, wCompile, wLink, wLinksys, wPure, wPush, wPop,
-    wBreakpoint, wWatchPoint, wPassl, wPassc,
+    wPassl, wPassc,
     wDeadCodeElimUnused,  # deprecated, always on
     wDeprecated,
     wFloatChecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll,
@@ -345,7 +345,7 @@ proc pragmaToOptions(w: TSpecialWord): TOptions {.inline.} =
   of wLineDir: {optLineDir}
   of wStackTrace: {optStackTrace}
   of wLineTrace: {optLineTrace}
-  of wDebugger: {optEndb}
+  of wDebugger: {optNone}
   of wProfiler: {optProfiler, optMemTracker}
   of wMemTracker: {optMemTracker}
   of wByRef: {optByRef}
@@ -513,15 +513,6 @@ proc processLink(c: PContext, n: PNode) =
   extccomp.addExternalFileToLink(c.config, found)
   recordPragma(c, n, "link", found.string)
 
-proc pragmaBreakpoint(c: PContext, n: PNode) =
-  discard getOptionalStr(c, n, "")
-
-proc pragmaWatchpoint(c: PContext, n: PNode) =
-  if n.kind in nkPragmaCallKinds and n.len == 2:
-    n.sons[1] = c.semExpr(c, n.sons[1])
-  else:
-    invalidPragma(c, n)
-
 proc semAsmOrEmit*(con: PContext, n: PNode, marker: char): PNode =
   case n.sons[1].kind
   of nkStrLit, nkRStrLit, nkTripleStrLit:
@@ -996,8 +987,6 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
         let s = expectStrLit(c, it)
         extccomp.addCompileOption(c.config, s)
         recordPragma(c, it, "passc", s)
-      of wBreakpoint: pragmaBreakpoint(c, it)
-      of wWatchPoint: pragmaWatchpoint(c, it)
       of wPush:
         processPush(c, n, i + 1)
         result = true
diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim
index 837ce4268..62b26adf3 100644
--- a/compiler/wordrecg.nim
+++ b/compiler/wordrecg.nim
@@ -48,7 +48,7 @@ type
     wCompilerProc, wCore, wProcVar, wBase, wUsed,
     wFatal, wError, wWarning, wHint, wLine, wPush, wPop, wDefine, wUndef,
     wLineDir, wStackTrace, wLineTrace, wLink, wCompile,
-    wLinksys, wDeprecated, wVarargs, wCallconv, wBreakpoint, wDebugger,
+    wLinksys, wDeprecated, wVarargs, wCallconv, wDebugger,
     wNimcall, wStdcall, wCdecl, wSafecall, wSyscall, wInline, wNoInline,
     wFastcall, wClosure, wNoconv, wOn, wOff, wChecks, wRangeChecks,
     wBoundChecks, wOverflowChecks, wNilChecks,
@@ -62,8 +62,7 @@ type
     wCompileTime, wNoInit,
     wPassc, wPassl, wBorrow, wDiscardable,
     wFieldChecks,
-    wWatchPoint, wSubsChar,
-    wAcyclic, wShallow, wUnroll, wLinearScanEnd, wComputedGoto,
+    wSubsChar, wAcyclic, wShallow, wUnroll, wLinearScanEnd, wComputedGoto,
     wInjectStmt, wExperimental,
     wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit,
     wAsmNoStackFrame,
@@ -138,7 +137,7 @@ const
     "fatal", "error", "warning", "hint", "line",
     "push", "pop", "define", "undef", "linedir", "stacktrace", "linetrace",
     "link", "compile", "linksys", "deprecated", "varargs",
-    "callconv", "breakpoint", "debugger", "nimcall", "stdcall",
+    "callconv", "debugger", "nimcall", "stdcall",
     "cdecl", "safecall", "syscall", "inline", "noinline", "fastcall", "closure",
     "noconv", "on", "off", "checks", "rangechecks", "boundchecks",
     "overflowchecks", "nilchecks",
@@ -152,7 +151,6 @@ const
     "pragma",
     "compiletime", "noinit",
     "passc", "passl", "borrow", "discardable", "fieldchecks",
-    "watchpoint",
     "subschar", "acyclic", "shallow", "unroll", "linearscanend",
     "computedgoto", "injectstmt", "experimental",
     "write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit",
diff --git a/doc/endb.rst b/doc/endb.rst
deleted file mode 100644
index 90bb964ba..000000000
--- a/doc/endb.rst
+++ /dev/null
@@ -1,203 +0,0 @@
-==============================================
-  Embedded Nim Debugger (ENDB) User Guide
-==============================================
-
-:Author: Andreas Rumpf
-:Version: |nimversion|
-
-.. contents::
-
-**WARNING**: ENDB is not maintained anymore! Please help if you're interested
-in this tool.
-
-Nim comes with a platform independent debugger -
-the Embedded Nim Debugger (ENDB). The debugger is
-*embedded* into your executable if it has been
-compiled with the ``--debugger:on`` command line option.
-This also defines the conditional symbol ``ENDB`` for you.
-
-Note: You must not compile your program with the ``--app:gui``
-command line option because then there would be no console
-available for the debugger.
-
-If you start your program the debugger will immediately show
-a prompt on the console. You can now enter a command. The next sections
-deal with the possible commands. As usual in Nim in all commands
-underscores and case do not matter. Optional components of a command
-are listed in brackets ``[...]`` here.
-
-
-General Commands
-================
-
-``h``, ``help``
-    Display a quick reference of the possible commands.
-
-``q``, ``quit``
-    Quit the debugger and the program.
-
-<ENTER>
-    (Without any typed command) repeat the previous debugger command.
-    If there is no previous command, ``step_into`` is assumed.
-
-Executing Commands
-==================
-
-``s``, ``step_into``
-    Single step, stepping into routine calls.
-
-``n``, ``step_over``
-    Single step, without stepping into routine calls.
-
-``f``, ``skip_current``
-    Continue execution until the current routine finishes.
-
-``c``, ``continue``
-    Continue execution until the next breakpoint.
-
-``i``, ``ignore``
-    Continue execution, ignore all breakpoints. This effectively quits
-    the debugger and runs the program until it finishes.
-
-
-Breakpoint Commands
-===================
-
-``b``, ``setbreak`` [fromline [toline]] [file]
-    Set a new breakpoint for the given file
-    and line numbers. If no file is given, the current execution point's
-    filename is used. If the filename has no extension, ``.nim`` is
-    appended for your convenience.
-    If no line numbers are given, the current execution point's
-    line is used. If both ``fromline`` and ``toline`` are given the
-    breakpoint contains a line number range. Some examples if it is still
-    unclear:
-
-    * ``b 12 15 thallo`` creates a breakpoint that
-      will be triggered if the instruction pointer reaches one of the
-      lines 12-15 in the file ``thallo.nim``.
-    * ``b 12 thallo`` creates a breakpoint that
-      will be triggered if the instruction pointer reaches the
-      line 12 in the file ``thallo.nim``.
-    * ``b 12`` creates a breakpoint that
-      will be triggered if the instruction pointer reaches the
-      line 12 in the current file.
-    * ``b`` creates a breakpoint that
-      will be triggered if the instruction pointer reaches the
-      current line in the current file again.
-
-``breakpoints``
-    Display the entire breakpoint list.
-
-``disable`` <identifier>
-    Disable a breakpoint. It remains disabled until you turn it on again
-    with the ``enable`` command.
-
-``enable`` <identifier>
-    Enable a breakpoint.
-
-Often it happens when debugging that you keep retyping the breakpoints again
-and again because they are lost when you restart your program. This is not
-necessary: A special pragma has been defined for this:
-
-
-The ``breakpoint`` pragma
--------------------------
-
-The ``breakpoint`` pragma is syntactically a statement. It can be used
-to mark the *following line* as a breakpoint:
-
-.. code-block:: Nim
-  write("1")
-  {.breakpoint: "before_write_2".}
-  write("2")
-
-The name of the breakpoint here is ``before_write_2``. Of course the
-breakpoint's name is optional - the compiler will generate one for you
-if you leave it out.
-
-Code for the ``breakpoint`` pragma is only generated if the debugger
-is turned on, so you don't need to remove it from your source code after
-debugging.
-
-
-The ``watchpoint`` pragma
--------------------------
-
-The ``watchpoint`` pragma is syntactically a statement. It can be used
-to mark a location as a watchpoint:
-
-.. code-block:: Nim
-  var a: array[0..20, int]
-
-  {.watchpoint: a[3].}
-  for i in 0 .. 20: a[i] = i
-
-ENDB then writes a stack trace whenever the content of the location ``a[3]``
-changes. The current implementation only tracks a hash value of the location's
-contents and so locations that are not word sized may encounter false
-negatives in very rare cases.
-
-Code for the ``watchpoint`` pragma is only generated if the debugger
-is turned on, so you don't need to remove it from your source code after
-debugging.
-
-Due to the primitive implementation watchpoints are even slower than
-breakpoints: After *every* executed Nim code line it is checked whether the
-location changed.
-
-
-Data Display Commands
-=====================
-
-``e``, ``eval`` <exp>
-    Evaluate the expression <exp>. Note that ENDB has no full-blown expression
-    evaluator built-in. So expressions are limited:
-
-    * To display global variables prefix their names with their
-      owning module: ``nim1.globalVar``
-    * To display local variables or parameters just type in
-      their name: ``localVar``. If you want to inspect variables that are not
-      in the current stack frame, use the ``up`` or ``down`` command.
-
-    Unfortunately, only inspecting variables is possible at the moment. Maybe
-    a future version will implement a full-blown Nim expression evaluator,
-    but this is not easy to do and would bloat the debugger's code.
-
-    Since displaying the whole data structures is often not needed and
-    painfully slow, the debugger uses a *maximal display depth* concept for
-    displaying.
-
-    You can alter the maximal display depth with the ``maxdisplay``
-    command.
-
-``maxdisplay`` <natural>
-    Sets the maximal display depth to the given integer value. A value of 0
-    means there is no maximal display depth. Default is 3.
-
-``o``, ``out`` <filename> <exp>
-    Evaluate the expression <exp> and store its string representation into a
-    file named <filename>. If the file does not exist, it will be created,
-    otherwise it will be opened for appending.
-
-``w``, ``where``
-    Display the current execution point.
-
-``u``, ``up``
-    Go up in the call stack.
-
-``d``, ``down``
-    Go down in the call stack.
-
-``stackframe`` [file]
-    Displays the content of the current stack frame in ``stdout`` or
-    appends it to the file, depending on whether a file is given.
-
-``callstack``
-    Display the entire call stack (but not its content).
-
-``l``, ``locals``
-    Display the available local variables in the current stack frame.
-
-``g``, ``globals``
-    Display all the global variables that are available for inspection.
diff --git a/lib/system.nim b/lib/system.nim
index 6d43d672a..16a5e03fe 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -3639,10 +3639,6 @@ when not defined(JS): #and not defined(nimscript):
         if result == 0:
           result = x.len - y.len
 
-  when not defined(nimscript) and hostOS != "standalone":
-    when defined(endb):
-      proc endbStep()
-
   when declared(newSeq):
     proc cstringArrayToSeq*(a: cstringArray, len: Natural): seq[string] =
       ## Converts a ``cstringArray`` to a ``seq[string]``. `a` is supposed to be
@@ -3816,9 +3812,6 @@ when not defined(JS): #and not defined(nimscript):
       currException = exc
 
   {.push stack_trace: off, profiler:off.}
-  when defined(endb) and not defined(nimscript):
-    include "system/debugger"
-
   when (defined(profiler) or defined(memProfiler)) and not defined(nimscript):
     include "system/profiler"
   {.pop.} # stacktrace
diff --git a/lib/system/debugger.nim b/lib/system/debugger.nim
deleted file mode 100644
index fd0ae2399..000000000
--- a/lib/system/debugger.nim
+++ /dev/null
@@ -1,303 +0,0 @@
-#
-#
-#            Nim's Runtime Library
-#        (c) Copyright 2013 Andreas Rumpf
-#
-#    See the file "copying.txt", included in this
-#    distribution, for details about the copyright.
-#
-
-## This file implements basic features for any debugger.
-
-type
-  VarSlot* {.compilerproc, final.} = object ## a slot in a frame
-    address*: pointer ## the variable's address
-    typ*: PNimType    ## the variable's type
-    name*: cstring    ## the variable's name; for globals this is "module.name"
-
-  PExtendedFrame = ptr ExtendedFrame
-  ExtendedFrame = object  # If the debugger is enabled the compiler
-                           # provides an extended frame. Of course
-                           # only slots that are
-                           # needed are allocated and not 10_000,
-                           # except for the global data description.
-    f: TFrame
-    slots: array[0..10_000, VarSlot]
-
-var
-  dbgGlobalData: ExtendedFrame  # this reserves much space, but
-                                # for now it is the most practical way
-
-proc dbgRegisterGlobal(name: cstring, address: pointer,
-                       typ: PNimType) {.compilerproc.} =
-  let i = dbgGlobalData.f.len
-  if i >= high(dbgGlobalData.slots):
-    #debugOut("[Warning] cannot register global ")
-    return
-  dbgGlobalData.slots[i].name = name
-  dbgGlobalData.slots[i].typ = typ
-  dbgGlobalData.slots[i].address = address
-  inc(dbgGlobalData.f.len)
-
-proc getLocal*(frame: PFrame; slot: int): VarSlot {.inline.} =
-  ## retrieves the meta data for the local variable at `slot`. CAUTION: An
-  ## invalid `slot` value causes a corruption!
-  result = cast[PExtendedFrame](frame).slots[slot]
-
-proc getGlobalLen*(): int {.inline.} =
-  ## gets the number of registered globals.
-  result = dbgGlobalData.f.len
-
-proc getGlobal*(slot: int): VarSlot {.inline.} =
-  ## retrieves the meta data for the global variable at `slot`. CAUTION: An
-  ## invalid `slot` value causes a corruption!
-  result = dbgGlobalData.slots[slot]
-
-# ------------------- breakpoint support ------------------------------------
-
-type
-  Breakpoint* = object   ## represents a break point
-    low*, high*: int     ## range from low to high; if disabled
-                         ## both low and high are set to their negative values
-    filename*: cstring   ## the filename of the breakpoint
-
-var
-  dbgBP: array[0..127, Breakpoint] # breakpoints
-  dbgBPlen: int
-  dbgBPbloom: int64  # we use a bloom filter to speed up breakpoint checking
-
-  dbgFilenames*: array[0..300, cstring] ## registered filenames;
-                                        ## 'nil' terminated
-  dbgFilenameLen: int
-
-proc dbgRegisterFilename(filename: cstring) {.compilerproc.} =
-  # XXX we could check for duplicates here for DLL support
-  dbgFilenames[dbgFilenameLen] = filename
-  inc dbgFilenameLen
-
-proc dbgRegisterBreakpoint(line: int,
-                           filename, name: cstring) {.compilerproc.} =
-  let x = dbgBPlen
-  if x >= high(dbgBP):
-    #debugOut("[Warning] cannot register breakpoint")
-    return
-  inc(dbgBPlen)
-  dbgBP[x].filename = filename
-  dbgBP[x].low = line
-  dbgBP[x].high = line
-  dbgBPbloom = dbgBPbloom or line
-
-proc addBreakpoint*(filename: cstring, lo, hi: int): bool =
-  let x = dbgBPlen
-  if x >= high(dbgBP): return false
-  inc(dbgBPlen)
-  result = true
-  dbgBP[x].filename = filename
-  dbgBP[x].low = lo
-  dbgBP[x].high = hi
-  for line in lo..hi: dbgBPbloom = dbgBPbloom or line
-
-const
-  FileSystemCaseInsensitive = defined(windows) or defined(dos) or defined(os2)
-
-proc fileMatches(c, bp: cstring): bool =
-  # bp = breakpoint filename
-  # c = current filename
-  # we consider it a match if bp is a suffix of c
-  # and the character for the suffix does not exist or
-  # is one of: \  /  :
-  # depending on the OS case does not matter!
-  var blen: int = bp.len
-  var clen: int = c.len
-  if blen > clen: return false
-  # check for \ /  :
-  if clen-blen-1 >= 0 and c[clen-blen-1] notin {'\\', '/', ':'}:
-    return false
-  var i = 0
-  while i < blen:
-    var x = bp[i]
-    var y = c[i+clen-blen]
-    when FileSystemCaseInsensitive:
-      if x >= 'A' and x <= 'Z': x = chr(ord(x) - ord('A') + ord('a'))
-      if y >= 'A' and y <= 'Z': y = chr(ord(y) - ord('A') + ord('a'))
-    if x != y: return false
-    inc(i)
-  return true
-
-proc canonFilename*(filename: cstring): cstring =
-  ## returns 'nil' if the filename cannot be found.
-  for i in 0 .. dbgFilenameLen-1:
-    result = dbgFilenames[i]
-    if fileMatches(result, filename): return result
-  result = nil
-
-iterator listBreakpoints*(): ptr Breakpoint =
-  ## lists all breakpoints.
-  for i in 0..dbgBPlen-1: yield addr(dbgBP[i])
-
-proc isActive*(b: ptr Breakpoint): bool = b.low > 0
-proc flip*(b: ptr Breakpoint) =
-  ## enables or disables 'b' depending on its current state.
-  b.low = -b.low; b.high = -b.high
-
-proc checkBreakpoints*(filename: cstring, line: int): ptr Breakpoint =
-  ## in which breakpoint (if any) we are.
-  if (dbgBPbloom and line) != line: return nil
-  for b in listBreakpoints():
-    if line >= b.low and line <= b.high and filename == b.filename: return b
-
-# ------------------- watchpoint support ------------------------------------
-
-type
-  Hash = int
-  Watchpoint {.pure, final.} = object
-    name: cstring
-    address: pointer
-    typ: PNimType
-    oldValue: Hash
-
-var
-  watchpoints: array[0..99, Watchpoint]
-  watchpointsLen: int
-
-proc `!&`(h: Hash, val: int): Hash {.inline.} =
-  result = h +% val
-  result = result +% result shl 10
-  result = result xor (result shr 6)
-
-proc `!$`(h: Hash): Hash {.inline.} =
-  result = h +% h shl 3
-  result = result xor (result shr 11)
-  result = result +% result shl 15
-
-proc hash(data: pointer, size: int): Hash =
-  var h: Hash = 0
-  var p = cast[cstring](data)
-  var i = 0
-  var s = size
-  while s > 0:
-    h = h !& ord(p[i])
-    inc(i)
-    dec(s)
-  result = !$h
-
-proc hashGcHeader(data: pointer): Hash =
-  const headerSize = sizeof(int)*2
-  result = hash(cast[pointer](cast[int](data) -% headerSize), headerSize)
-
-proc genericHashAux(dest: pointer, mt: PNimType, shallow: bool,
-                    h: Hash): Hash
-proc genericHashAux(dest: pointer, n: ptr TNimNode, shallow: bool,
-                    h: Hash): Hash =
-  var d = cast[ByteAddress](dest)
-  case n.kind
-  of nkSlot:
-    result = genericHashAux(cast[pointer](d +% n.offset), n.typ, shallow, h)
-  of nkList:
-    result = h
-    for i in 0..n.len-1:
-      result = result !& genericHashAux(dest, n.sons[i], shallow, result)
-  of nkCase:
-    result = h !& hash(cast[pointer](d +% n.offset), n.typ.size)
-    var m = selectBranch(dest, n)
-    if m != nil: result = genericHashAux(dest, m, shallow, result)
-  of nkNone: sysAssert(false, "genericHashAux")
-
-proc genericHashAux(dest: pointer, mt: PNimType, shallow: bool,
-                    h: Hash): Hash =
-  sysAssert(mt != nil, "genericHashAux 2")
-  case mt.kind
-  of tyString:
-    var x = cast[PPointer](dest)[]
-    result = h
-    if x != nil:
-      let s = cast[NimString](x)
-      when defined(trackGcHeaders):
-        result = result !& hashGcHeader(x)
-      else:
-        result = result !& hash(x, s.len)
-  of tySequence:
-    var x = cast[PPointer](dest)
-    var dst = cast[ByteAddress](cast[PPointer](dest)[])
-    result = h
-    if dst != 0:
-      when defined(trackGcHeaders):
-        result = result !& hashGcHeader(cast[PPointer](dest)[])
-      else:
-        for i in 0..cast[PGenericSeq](dst).len-1:
-          result = result !& genericHashAux(
-            cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize),
-            mt.base, shallow, result)
-  of tyObject, tyTuple:
-    # we don't need to copy m_type field for tyObject, as they are equal anyway
-    result = genericHashAux(dest, mt.node, shallow, h)
-  of tyArray, tyArrayConstr:
-    let d = cast[ByteAddress](dest)
-    result = h
-    for i in 0..(mt.size div mt.base.size)-1:
-      result = result !& genericHashAux(cast[pointer](d +% i*% mt.base.size),
-                                        mt.base, shallow, result)
-  of tyRef:
-    when defined(trackGcHeaders):
-      var s = cast[PPointer](dest)[]
-      if s != nil:
-        result = result !& hashGcHeader(s)
-    else:
-      if shallow:
-        result = h !& hash(dest, mt.size)
-      else:
-        result = h
-        var s = cast[PPointer](dest)[]
-        if s != nil:
-          result = result !& genericHashAux(s, mt.base, shallow, result)
-  else:
-    result = h !& hash(dest, mt.size) # hash raw bits
-
-proc genericHash(dest: pointer, mt: PNimType): int =
-  result = genericHashAux(dest, mt, false, 0)
-
-proc dbgRegisterWatchpoint(address: pointer, name: cstring,
-                           typ: PNimType) {.compilerproc.} =
-  let L = watchPointsLen
-  for i in 0 .. pred(L):
-    if watchPoints[i].name == name:
-      # address may have changed:
-      watchPoints[i].address = address
-      return
-  if L >= watchPoints.high:
-    #debugOut("[Warning] cannot register watchpoint")
-    return
-  watchPoints[L].name = name
-  watchPoints[L].address = address
-  watchPoints[L].typ = typ
-  watchPoints[L].oldValue = genericHash(address, typ)
-  inc watchPointsLen
-
-proc dbgUnregisterWatchpoints*() =
-  watchPointsLen = 0
-
-var
-  dbgLineHook*: proc () {.nimcall.}
-    ## set this variable to provide a procedure that should be called before
-    ## each executed instruction. This should only be used by debuggers!
-    ## Only code compiled with the ``debugger:on`` switch calls this hook.
-
-  dbgWatchpointHook*: proc (watchpointName: cstring) {.nimcall.}
-
-proc checkWatchpoints =
-  let L = watchPointsLen
-  for i in 0 .. pred(L):
-    let newHash = genericHash(watchPoints[i].address, watchPoints[i].typ)
-    if newHash != watchPoints[i].oldValue:
-      dbgWatchpointHook(watchPoints[i].name)
-      watchPoints[i].oldValue = newHash
-
-proc endb(line: int, file: cstring) {.compilerproc, noinline.} =
-  # This proc is called before every Nim code line!
-  if framePtr == nil: return
-  if dbgWatchpointHook != nil: checkWatchpoints()
-  framePtr.line = line # this is done here for smaller code size!
-  framePtr.filename = file
-  if dbgLineHook != nil: dbgLineHook()
-
-include "system/endb"
diff --git a/lib/system/endb.nim b/lib/system/endb.nim
deleted file mode 100644
index 6c99f8d12..000000000
--- a/lib/system/endb.nim
+++ /dev/null
@@ -1,579 +0,0 @@
-#
-#
-#            Nim's Runtime Library
-#        (c) Copyright 2013 Andreas Rumpf
-#
-#    See the file "copying.txt", included in this
-#    distribution, for details about the copyright.
-#
-
-# This file implements the embedded debugger that can be linked
-# with the application. Mostly we do not use dynamic memory here as that
-# would interfere with the GC and trigger ON/OFF errors if the
-# user program corrupts memory. Unfortunately, for dispaying
-# variables we use the ``system.repr()`` proc which uses Nim
-# strings and thus allocates memory from the heap. Pity, but
-# I do not want to implement ``repr()`` twice.
-
-const
-  EndbBeg = "*** endb"
-  EndbEnd = "***\n"
-
-type
-  StaticStr = object
-    len: int
-    data: array[0..100, char]
-
-  BreakpointFilename = object
-    b: ptr Breakpoint
-    filename: StaticStr
-
-  DbgState = enum
-    dbOff,        # debugger is turned off
-    dbStepInto,   # debugger is in tracing mode
-    dbStepOver,
-    dbSkipCurrent,
-    dbQuiting,    # debugger wants to quit
-    dbBreakpoints # debugger is only interested in breakpoints
-
-var
-  dbgUser: StaticStr    # buffer for user input; first command is ``step_into``
-                        # needs to be global cause we store the last command
-                        # in it
-  dbgState: DbgState    # state of debugger
-  dbgSkipToFrame: PFrame # frame to be skipped to
-
-  maxDisplayRecDepth: int = 5 # do not display too much data!
-
-  brkPoints: array[0..127, BreakpointFilename]
-
-proc setLen(s: var StaticStr, newLen=0) =
-  s.len = newLen
-  s.data[newLen] = '\0'
-
-proc add(s: var StaticStr, c: char) =
-  if s.len < high(s.data)-1:
-    s.data[s.len] = c
-    s.data[s.len+1] = '\0'
-    inc s.len
-
-proc add(s: var StaticStr, c: cstring) =
-  var i = 0
-  while c[i] != '\0':
-    add s, c[i]
-    inc i
-
-proc assign(s: var StaticStr, c: cstring) =
-  setLen(s)
-  add s, c
-
-proc `==`(a, b: StaticStr): bool =
-  if a.len == b.len:
-    for i in 0 .. a.len-1:
-      if a.data[i] != b.data[i]: return false
-    return true
-
-proc `==`(a: StaticStr, b: cstring): bool =
-  result = c_strcmp(unsafeAddr a.data, b) == 0
-
-proc write(f: CFilePtr, s: cstring) = c_fputs(s, f)
-proc writeLine(f: CFilePtr, s: cstring) =
-  c_fputs(s, f)
-  c_fputs("\n", f)
-
-proc write(f: CFilePtr, s: StaticStr) =
-  write(f, cstring(unsafeAddr s.data))
-
-proc write(f: CFilePtr, i: int) =
-  when sizeof(int) == 8:
-    discard c_fprintf(f, "%lld", i)
-  else:
-    discard c_fprintf(f, "%ld", i)
-
-proc close(f: CFilePtr): cint {.
-  importc: "fclose", header: "<stdio.h>", discardable.}
-
-proc c_fgetc(stream: CFilePtr): cint {.
-  importc: "fgetc", header: "<stdio.h>".}
-proc c_ungetc(c: cint, f: CFilePtr): cint {.
-  importc: "ungetc", header: "<stdio.h>", discardable.}
-
-var
-  cstdin* {.importc: "stdin", header: "<stdio.h>".}: CFilePtr
-
-proc listBreakPoints() =
-  write(cstdout, EndbBeg)
-  write(cstdout, "| Breakpoints:\n")
-  for b in listBreakpoints():
-    write(cstdout, abs(b.low))
-    if b.high != b.low:
-      write(cstdout, "..")
-      write(cstdout, abs(b.high))
-    write(cstdout, " ")
-    write(cstdout, b.filename)
-    if b.isActive:
-      write(cstdout, " [disabled]\n")
-    else:
-      write(cstdout, "\n")
-  write(cstdout, EndbEnd)
-
-proc openAppend(filename: cstring): CFilePtr =
-  proc fopen(filename, mode: cstring): CFilePtr {.importc: "fopen", header: "<stdio.h>".}
-
-  result = fopen(filename, "ab")
-  if result != nil:
-    write(result, "----------------------------------------\n")
-
-proc dbgRepr(p: pointer, typ: PNimType): string =
-  var cl: ReprClosure
-  initReprClosure(cl)
-  cl.recDepth = maxDisplayRecDepth
-  # locks for the GC turned out to be a bad idea...
-  # inc(recGcLock)
-  result = ""
-  reprAux(result, p, typ, cl)
-  # dec(recGcLock)
-  deinitReprClosure(cl)
-
-proc writeVariable(stream: CFilePtr, slot: VarSlot) =
-  write(stream, slot.name)
-  write(stream, " = ")
-  writeLine(stream, dbgRepr(slot.address, slot.typ))
-
-proc listFrame(stream: CFilePtr, f: PFrame) =
-  write(stream, EndbBeg)
-  write(stream, "| Frame (")
-  write(stream, f.len)
-  write(stream, " slots):\n")
-  for i in 0 .. f.len-1:
-    writeLine(stream, getLocal(f, i).name)
-  write(stream, EndbEnd)
-
-proc listLocals(stream: CFilePtr, f: PFrame) =
-  write(stream, EndbBeg)
-  write(stream, "| Frame (")
-  write(stream, f.len)
-  write(stream, " slots):\n")
-  for i in 0 .. f.len-1:
-    writeVariable(stream, getLocal(f, i))
-  write(stream, EndbEnd)
-
-proc listGlobals(stream: CFilePtr) =
-  write(stream, EndbBeg)
-  write(stream, "| Globals:\n")
-  for i in 0 .. getGlobalLen()-1:
-    writeLine(stream, getGlobal(i).name)
-  write(stream, EndbEnd)
-
-proc debugOut(msg: cstring) =
-  # the *** *** markers are for easy recognition of debugger
-  # output for external frontends.
-  write(cstdout, EndbBeg)
-  write(cstdout, "| ")
-  write(cstdout, msg)
-  write(cstdout, EndbEnd)
-
-proc dbgFatal(msg: cstring) =
-  debugOut(msg)
-  dbgAborting = true # the debugger wants to abort
-  quit(1)
-
-proc dbgShowCurrentProc(dbgFramePointer: PFrame) =
-  if dbgFramePointer != nil:
-    write(cstdout, "*** endb| now in proc: ")
-    write(cstdout, dbgFramePointer.procname)
-    write(cstdout, " ***\n")
-  else:
-    write(cstdout, "*** endb| (proc name not available) ***\n")
-
-proc dbgShowExecutionPoint() =
-  write(cstdout, "*** endb| ")
-  write(cstdout, framePtr.filename)
-  write(cstdout, "(")
-  write(cstdout, framePtr.line)
-  write(cstdout, ") ")
-  write(cstdout, framePtr.procname)
-  write(cstdout, " ***\n")
-
-proc scanAndAppendWord(src: cstring, a: var StaticStr, start: int): int =
-  result = start
-  # skip whitespace:
-  while src[result] in {'\t', ' '}: inc(result)
-  while true:
-    case src[result]
-    of 'a'..'z', '0'..'9': add(a, src[result])
-    of '_': discard # just skip it
-    of 'A'..'Z': add(a, chr(ord(src[result]) - ord('A') + ord('a')))
-    else: break
-    inc(result)
-
-proc scanWord(src: cstring, a: var StaticStr, start: int): int =
-  setlen(a)
-  result = scanAndAppendWord(src, a, start)
-
-proc scanFilename(src: cstring, a: var StaticStr, start: int): int =
-  result = start
-  setLen a
-  while src[result] in {'\t', ' '}: inc(result)
-  while src[result] notin {'\t', ' ', '\0'}:
-    add(a, src[result])
-    inc(result)
-
-proc scanNumber(src: cstring, a: var int, start: int): int =
-  result = start
-  a = 0
-  while src[result] in {'\t', ' '}: inc(result)
-  while true:
-    case src[result]
-    of '0'..'9': a = a * 10 + ord(src[result]) - ord('0')
-    of '_': discard # skip underscores (nice for long line numbers)
-    else: break
-    inc(result)
-
-proc dbgHelp() =
-  debugOut("""
-list of commands (see the manual for further help):
-              GENERAL
-h, help                 display this help message
-q, quit                 quit the debugger and the program
-<ENTER>                 repeat the previous debugger command
-              EXECUTING
-s, step                 single step, stepping into routine calls
-n, next                 single step, without stepping into routine calls
-f, skipcurrent          continue execution until the current routine finishes
-c, continue, r, run     continue execution until the next breakpoint
-i, ignore               continue execution, ignore all breakpoints
-              BREAKPOINTS
-b, break [fromline [toline]] [file]
-                        set a new breakpoint for line and file
-                        if line or file are omitted the current one is used
-breakpoints             display the entire breakpoint list
-toggle fromline [file]  enable or disable a breakpoint
-filenames               list all valid filenames
-              DATA DISPLAY
-e, eval <expr>          evaluate the expression <expr>
-o, out <file> <expr>    evaluate <expr> and write it to <file>
-w, where                display the current execution point
-stackframe [file]       display current stack frame [and write it to file]
-u, up                   go up in the call stack
-d, down                 go down in the call stack
-bt, backtrace           display the entire call stack
-l, locals               display available local variables
-g, globals              display available global variables
-maxdisplay <integer>    set the display's recursion maximum
-""")
-
-proc invalidCommand() =
-  debugOut("[Warning] invalid command ignored (type 'h' for help) ")
-
-proc hasExt(s: cstring): bool =
-  # returns true if s has a filename extension
-  var i = 0
-  while s[i] != '\0':
-    if s[i] == '.': return true
-    inc i
-
-proc parseBreakpoint(s: cstring, start: int): Breakpoint =
-  var dbgTemp: StaticStr
-  var i = scanNumber(s, result.low, start)
-  if result.low == 0: result.low = framePtr.line
-  i = scanNumber(s, result.high, i)
-  if result.high == 0: result.high = result.low
-  i = scanFilename(s, dbgTemp, i)
-  if dbgTemp.len != 0:
-    if not hasExt(addr dbgTemp.data): add(dbgTemp, ".nim")
-    result.filename = canonFilename(addr dbgTemp.data)
-    if result.filename.isNil:
-      debugOut("[Warning] no breakpoint could be set; unknown filename ")
-      return
-  else:
-    result.filename = framePtr.filename
-
-proc createBreakPoint(s: cstring, start: int) =
-  let br = parseBreakpoint(s, start)
-  if not br.filename.isNil:
-    if not addBreakpoint(br.filename, br.low, br.high):
-      debugOut("[Warning] no breakpoint could be set; out of breakpoint space ")
-
-proc breakpointToggle(s: cstring, start: int) =
-  var a = parseBreakpoint(s, start)
-  if not a.filename.isNil:
-    var b = checkBreakpoints(a.filename, a.low)
-    if not b.isNil: b.flip
-    else: debugOut("[Warning] unknown breakpoint ")
-
-proc dbgEvaluate(stream: CFilePtr, s: cstring, start: int, f: PFrame) =
-  var dbgTemp: StaticStr
-  var i = scanWord(s, dbgTemp, start)
-  while s[i] in {' ', '\t'}: inc(i)
-  var v: VarSlot
-  if s[i] == '.':
-    inc(i)
-    add(dbgTemp, '.')
-    i = scanAndAppendWord(s, dbgTemp, i)
-    for i in 0 .. getGlobalLen()-1:
-      let v = getGlobal(i)
-      if c_strcmp(v.name, addr dbgTemp.data) == 0:
-        writeVariable(stream, v)
-  else:
-    for i in 0 .. f.len-1:
-      let v = getLocal(f, i)
-      if c_strcmp(v.name, addr dbgTemp.data) == 0:
-        writeVariable(stream, v)
-
-proc dbgOut(s: cstring, start: int, currFrame: PFrame) =
-  var dbgTemp: StaticStr
-  var i = scanFilename(s, dbgTemp, start)
-  if dbgTemp.len == 0:
-    invalidCommand()
-    return
-  var stream = openAppend(addr dbgTemp.data)
-  if stream == nil:
-    debugOut("[Warning] could not open or create file ")
-    return
-  dbgEvaluate(stream, s, i, currFrame)
-  close(stream)
-
-proc dbgStackFrame(s: cstring, start: int, currFrame: PFrame) =
-  var dbgTemp: StaticStr
-  var i = scanFilename(s, dbgTemp, start)
-  if dbgTemp.len == 0:
-    # just write it to cstdout:
-    listFrame(cstdout, currFrame)
-  else:
-    var stream = openAppend(addr dbgTemp.data)
-    if stream == nil:
-      debugOut("[Warning] could not open or create file ")
-      return
-    listFrame(stream, currFrame)
-    close(stream)
-
-proc readLine(f: CFilePtr, line: var StaticStr): bool =
-  while true:
-    var c = c_fgetc(f)
-    if c < 0'i32:
-      if line.len > 0: break
-      else: return false
-    if c == 10'i32: break # LF
-    if c == 13'i32:  # CR
-      c = c_fgetc(f) # is the next char LF?
-      if c != 10'i32: discard c_ungetc(c, f) # no, put the character back
-      break
-    add line, chr(int(c))
-  result = true
-
-proc listFilenames() =
-  write(cstdout, EndbBeg)
-  write(cstdout, "| Files:\n")
-  var i = 0
-  while true:
-    let x = dbgFilenames[i]
-    if x.isNil: break
-    write(cstdout, x)
-    write(cstdout, "\n")
-    inc i
-  write(cstdout, EndbEnd)
-
-proc dbgWriteStackTrace(f: PFrame)
-proc commandPrompt() =
-  # if we return from this routine, user code executes again
-  var
-    again = true
-    dbgFramePtr = framePtr # for going down and up the stack
-    dbgDown = 0 # how often we did go down
-    dbgTemp: StaticStr
-
-  while again:
-    write(cstdout, "*** endb| >>")
-    let oldLen = dbgUser.len
-    dbgUser.len = 0
-    if not readLine(cstdin, dbgUser): break
-    if dbgUser.len == 0: dbgUser.len = oldLen
-    # now look what we have to do:
-    var i = scanWord(addr dbgUser.data, dbgTemp, 0)
-    template `?`(x: untyped): untyped = dbgTemp == cstring(x)
-    if ?"s" or ?"step":
-      dbgState = dbStepInto
-      again = false
-    elif ?"n" or ?"next":
-      dbgState = dbStepOver
-      dbgSkipToFrame = framePtr
-      again = false
-    elif ?"f" or ?"skipcurrent":
-      dbgState = dbSkipCurrent
-      dbgSkipToFrame = framePtr.prev
-      again = false
-    elif ?"c" or ?"continue" or ?"r" or ?"run":
-      dbgState = dbBreakpoints
-      again = false
-    elif ?"i" or ?"ignore":
-      dbgState = dbOff
-      again = false
-    elif ?"h" or ?"help":
-      dbgHelp()
-    elif ?"q" or ?"quit":
-      dbgState = dbQuiting
-      dbgAborting = true
-      again = false
-      quit(1) # BUGFIX: quit with error code > 0
-    elif ?"e" or ?"eval":
-      var
-        prevState = dbgState
-        prevSkipFrame = dbgSkipToFrame
-      dbgState = dbSkipCurrent
-      dbgEvaluate(cstdout, addr dbgUser.data, i, dbgFramePtr)
-      dbgState = prevState
-      dbgSkipToFrame = prevSkipFrame
-    elif ?"o" or ?"out":
-      dbgOut(addr dbgUser.data, i, dbgFramePtr)
-    elif ?"stackframe":
-      dbgStackFrame(addr dbgUser.data, i, dbgFramePtr)
-    elif ?"w" or ?"where":
-      dbgShowExecutionPoint()
-    elif ?"l" or ?"locals":
-      var
-        prevState = dbgState
-        prevSkipFrame = dbgSkipToFrame
-      dbgState = dbSkipCurrent
-      listLocals(cstdout, dbgFramePtr)
-      dbgState = prevState
-      dbgSkipToFrame = prevSkipFrame
-    elif ?"g" or ?"globals":
-      var
-        prevState = dbgState
-        prevSkipFrame = dbgSkipToFrame
-      dbgState = dbSkipCurrent
-      listGlobals(cstdout)
-      dbgState = prevState
-      dbgSkipToFrame = prevSkipFrame
-    elif ?"u" or ?"up":
-      if dbgDown <= 0:
-        debugOut("[Warning] cannot go up any further ")
-      else:
-        dbgFramePtr = framePtr
-        for j in 0 .. dbgDown-2: # BUGFIX
-          dbgFramePtr = dbgFramePtr.prev
-        dec(dbgDown)
-      dbgShowCurrentProc(dbgFramePtr)
-    elif ?"d" or ?"down":
-      if dbgFramePtr != nil:
-        inc(dbgDown)
-        dbgFramePtr = dbgFramePtr.prev
-        dbgShowCurrentProc(dbgFramePtr)
-      else:
-        debugOut("[Warning] cannot go down any further ")
-    elif ?"bt" or ?"backtrace":
-      dbgWriteStackTrace(framePtr)
-    elif ?"b" or ?"break":
-      createBreakPoint(addr dbgUser.data, i)
-    elif ?"breakpoints":
-      listBreakPoints()
-    elif ?"toggle":
-      breakpointToggle(addr dbgUser.data, i)
-    elif ?"filenames":
-      listFilenames()
-    elif ?"maxdisplay":
-      var parsed: int
-      i = scanNumber(addr dbgUser.data, parsed, i)
-      if dbgUser.data[i-1] in {'0'..'9'}:
-        if parsed == 0: maxDisplayRecDepth = -1
-        else: maxDisplayRecDepth = parsed
-      else:
-        invalidCommand()
-    else: invalidCommand()
-
-proc endbStep() =
-  # we get into here if an unhandled exception has been raised
-  # XXX: do not allow the user to run the program any further?
-  # XXX: BUG: the frame is lost here!
-  dbgShowExecutionPoint()
-  commandPrompt()
-
-proc dbgWriteStackTrace(f: PFrame) =
-  const
-    firstCalls = 32
-  var
-    it = f
-    i = 0
-    total = 0
-    tempFrames: array[0..127, PFrame]
-  # setup long head:
-  while it != nil and i <= high(tempFrames)-firstCalls:
-    tempFrames[i] = it
-    inc(i)
-    inc(total)
-    it = it.prev
-  # go up the stack to count 'total':
-  var b = it
-  while it != nil:
-    inc(total)
-    it = it.prev
-  var skipped = 0
-  if total > len(tempFrames):
-    # skip N
-    skipped = total-i-firstCalls+1
-    for j in 1..skipped:
-      if b != nil: b = b.prev
-    # create '...' entry:
-    tempFrames[i] = nil
-    inc(i)
-  # setup short tail:
-  while b != nil and i <= high(tempFrames):
-    tempFrames[i] = b
-    inc(i)
-    b = b.prev
-  for j in countdown(i-1, 0):
-    if tempFrames[j] == nil:
-      write(cstdout, "(")
-      write(cstdout, skipped)
-      write(cstdout, " calls omitted) ...")
-    else:
-      write(cstdout, tempFrames[j].filename)
-      if tempFrames[j].line > 0:
-        write(cstdout, "(")
-        write(cstdout, tempFrames[j].line)
-        write(cstdout, ")")
-      write(cstdout, " ")
-      write(cstdout, tempFrames[j].procname)
-    write(cstdout, "\n")
-
-proc checkForBreakpoint =
-  let b = checkBreakpoints(framePtr.filename, framePtr.line)
-  if b != nil:
-    write(cstdout, "*** endb| reached ")
-    write(cstdout, framePtr.filename)
-    write(cstdout, "(")
-    write(cstdout, framePtr.line)
-    write(cstdout, ") ")
-    write(cstdout, framePtr.procname)
-    write(cstdout, " ***\n")
-    commandPrompt()
-
-proc lineHookImpl() {.nimcall.} =
-  case dbgState
-  of dbStepInto:
-    # we really want the command prompt here:
-    dbgShowExecutionPoint()
-    commandPrompt()
-  of dbSkipCurrent, dbStepOver: # skip current routine
-    if framePtr == dbgSkipToFrame:
-      dbgShowExecutionPoint()
-      commandPrompt()
-    else:
-      # breakpoints are wanted though (I guess)
-      checkForBreakpoint()
-  of dbBreakpoints:
-    # debugger is only interested in breakpoints
-    checkForBreakpoint()
-  else: discard
-
-proc watchpointHookImpl(name: cstring) {.nimcall.} =
-  dbgWriteStackTrace(framePtr)
-  debugOut(name)
-
-proc initDebugger {.inline.} =
-  dbgState = dbStepInto
-  dbgUser.len = 1
-  dbgUser.data[0] = 's'
-  dbgWatchpointHook = watchpointHookImpl
-  dbgLineHook = lineHookImpl
diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim
index 0898ad0fd..1eb4cedc8 100644
--- a/lib/system/excpt.nim
+++ b/lib/system/excpt.nim
@@ -38,10 +38,7 @@ proc showErrorMessage(data: cstring) {.gcsafe.} =
       writeToStdErr(data)
 
 proc quitOrDebug() {.inline.} =
-  when defined(endb):
-    endbStep() # call the debugger
-  else:
-    quit(1)
+  quit(1)
 
 proc chckIndx(i, a, b: int): int {.inline, compilerproc, benign.}
 proc chckRange(i, a, b: int): int {.inline, compilerproc, benign.}
@@ -469,10 +466,6 @@ proc nimFrame(s: PFrame) {.compilerRtl, inl.} =
   framePtr = s
   if s.calldepth == nimCallDepthLimit: callDepthLimitReached()
 
-when defined(endb):
-  var
-    dbgAborting: bool # whether the debugger wants to abort
-
 when defined(cpp) and appType != "lib" and
     not defined(js) and not defined(nimscript) and
     hostOS != "standalone" and not defined(noCppExceptions):
@@ -515,8 +508,6 @@ when not defined(noSignalHandler) and not defined(useNimRtl):
       elif s == SIGSEGV:
         action("SIGSEGV: Illegal storage access. (Attempt to read from nil?)\n")
       elif s == SIGABRT:
-        when defined(endb):
-          if dbgAborting: return # the debugger wants to abort
         action("SIGABRT: Abnormal termination.\n")
       elif s == SIGFPE: action("SIGFPE: Arithmetic error.\n")
       elif s == SIGILL: action("SIGILL: Illegal operation.\n")
@@ -546,7 +537,6 @@ when not defined(noSignalHandler) and not defined(useNimRtl):
         msg = y
       processSignal(sign, asgn)
       showErrorMessage(msg)
-    when defined(endb): dbgAborting = true
     quit(1) # always quit when SIGABRT
 
   proc registerSignalHandler() =
diff --git a/tests/gc/gcleak4.nim b/tests/gc/gcleak4.nim
index e9b17e557..35b8ce112 100644
--- a/tests/gc/gcleak4.nim
+++ b/tests/gc/gcleak4.nim
@@ -27,13 +27,11 @@ method eval(e: ref TPlusExpr): int =
 
 proc newLit(x: int): ref TLiteral =
   new(result)
-  {.watchpoint: result.}
   result.x = x
   result.op1 = $getOccupiedMem()
 
 proc newPlus(a, b: ref TExpr): ref TPlusExpr =
   new(result)
-  {.watchpoint: result.}
   result.a = a
   result.b = b
   result.op2 = $getOccupiedMem()
diff --git a/tests/misc/thallo.nim b/tests/misc/thallo.nim
index f61ce2ef2..8dac56023 100644
--- a/tests/misc/thallo.nim
+++ b/tests/misc/thallo.nim
@@ -48,7 +48,6 @@ echo(["a", "b", "c", "d"].len)
 for x in items(["What's", "your", "name", "?", ]):
   echo(x)
 var `name` = readLine(stdin)
-{.breakpoint.}
 echo("Hi " & thallo.name & "!\n")
 debug(name)
 
diff --git a/tests/objects/tobjects_various.nim b/tests/objects/tobjects_various.nim
index a6c4628af..315193de9 100644
--- a/tests/objects/tobjects_various.nim
+++ b/tests/objects/tobjects_various.nim
@@ -17,7 +17,6 @@ block tobject2:
       z: int # added a field
 
   proc getPoint( p: var TPoint2d) =
-    {.breakpoint.}
     writeLine(stdout, p.x)
 
   var p: TPoint3d