summary refs log tree commit diff stats
path: root/compiler/debugutils.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/debugutils.nim')
-rw-r--r--compiler/debugutils.nim72
1 files changed, 72 insertions, 0 deletions
diff --git a/compiler/debugutils.nim b/compiler/debugutils.nim
new file mode 100644
index 000000000..adbb0517f
--- /dev/null
+++ b/compiler/debugutils.nim
@@ -0,0 +1,72 @@
+##[
+Utilities to help with debugging nim compiler.
+
+Experimental API, subject to change.
+]##
+
+#[
+## example
+useful debugging flags:
+--stacktrace -d:debug -d:nimDebugUtils
+ nim c -o:bin/nim_temp --stacktrace -d:debug -d:nimDebugUtils compiler/nim
+
+## future work
+* expose and improve astalgo.debug, replacing it by std/prettyprints,
+  refs https://github.com/nim-lang/RFCs/issues/385
+]#
+
+import options
+import std/wrapnils
+export wrapnils
+  # allows using things like: `?.n.sym.typ.len`
+
+import std/stackframes
+export stackframes
+  # allows using things like: `setFrameMsg c.config$n.info & " " & $n.kind`
+  # which doesn't log, but augments stacktrace with side channel information
+
+var conf0: ConfigRef
+
+proc onNewConfigRef*(conf: ConfigRef) {.inline.} =
+  ## Caches `conf`, which can be retrieved with `getConfigRef`.
+  ## This avoids having to forward `conf` all the way down the call chain to
+  ## procs that need it during a debugging session.
+  conf0 = conf
+
+proc getConfigRef*(): ConfigRef =
+  ## nil, if -d:nimDebugUtils wasn't specified
+  result = conf0
+
+proc isCompilerDebug*(): bool =
+  ##[
+  Provides a simple way for user code to enable/disable logging in the compiler
+  in a granular way. This can then be used in the compiler as follows:
+  ```nim
+  if isCompilerDebug():
+    echo ?.n.sym.typ.len
+  ```
+  ]##
+  runnableExamples:
+    proc main =
+      echo 2
+      {.define(nimCompilerDebug).}
+      echo 3.5 # code section in which `isCompilerDebug` will be true
+      {.undef(nimCompilerDebug).}
+      echo 'x'
+  conf0.isDefined("nimCompilerDebug")
+
+proc enteringDebugSection*() {.exportc, dynlib.} =
+  ## Provides a way for native debuggers to enable breakpoints, watchpoints, etc
+  ## when code of interest is being compiled.
+  ## 
+  ## Set your debugger to break on entering `nimCompilerIsEnteringDebugSection`
+  ## and then execute a desired command.
+  discard
+
+proc exitingDebugSection*() {.exportc, dynlib.} =
+  ## Provides a way for native debuggers to disable breakpoints, watchpoints, etc
+  ## when code of interest is no longer being compiled.
+  ## 
+  ## Set your debugger to break on entering `exitingDebugSection`
+  ## and then execute a desired command.
+  discard