summary refs log tree commit diff stats
path: root/tests/untestable/gdb
diff options
context:
space:
mode:
Diffstat (limited to 'tests/untestable/gdb')
-rw-r--r--tests/untestable/gdb/gdb_pretty_printer_test.py64
-rw-r--r--tests/untestable/gdb/gdb_pretty_printer_test_program.nim89
-rwxr-xr-xtests/untestable/gdb/gdb_pretty_printer_test_run.sh13
3 files changed, 166 insertions, 0 deletions
diff --git a/tests/untestable/gdb/gdb_pretty_printer_test.py b/tests/untestable/gdb/gdb_pretty_printer_test.py
new file mode 100644
index 000000000..aed0cfeb0
--- /dev/null
+++ b/tests/untestable/gdb/gdb_pretty_printer_test.py
@@ -0,0 +1,64 @@
+import gdb
+import re
+import sys
+# this test should test the gdb pretty printers of the nim
+# library. But be aware this test is not complete. It only tests the
+# command line version of gdb. It does not test anything for the
+# machine interface of gdb. This means if if this test passes gdb
+# frontends might still be broken.
+
+gdb.execute("set python print-stack full")
+gdb.execute("source ../../../tools/debug/nim-gdb.py")
+# debug all instances of the generic function `myDebug`, should be 14
+gdb.execute("rbreak myDebug")
+gdb.execute("run")
+
+outputs = [
+  'meTwo',
+  '""',
+  '"meTwo"',
+  '{meOne, meThree}',
+  'MyOtherEnum(1)',
+  '{MyOtherEnum(0), MyOtherEnum(2)}',
+  'array = {1, 2, 3, 4, 5}',
+  'seq(0, 0)',
+  'seq(0, 10)',
+  'array = {"one", "two"}',
+  'seq(3, 3) = {1, 2, 3}',
+  'seq(3, 3) = {"one", "two", "three"}',
+  'Table(3, 64) = {[4] = "four", [5] = "five", [6] = "six"}',
+  'Table(3, 8) = {["two"] = 2, ["three"] = 3, ["one"] = 1}',
+  '{a = 1, b = "some string"}',
+  '("hello", 42)'
+]
+
+argRegex = re.compile("^.* = (?:No suitable Nim \$ operator found for type: \w+\s*)*(.*)$")
+# Remove this error message which can pop up
+noSuitableRegex = re.compile("(No suitable Nim \$ operator found for type: \w+\s*)")
+
+for i, expected in enumerate(outputs):
+  gdb.write(f"\x1b[38;5;105m{i+1}) expecting: {expected}: \x1b[0m", gdb.STDLOG)
+  gdb.flush()
+  currFrame = gdb.selected_frame()
+  functionSymbol = currFrame.block().function
+  assert functionSymbol.line == 24, str(functionSymbol.line)
+  raw = ""
+  if i == 6:
+    # myArray is passed as pointer to int to myDebug. I look up myArray up in the stack
+    gdb.execute("up")
+    raw = gdb.parse_and_eval("myArray")    
+  elif i == 9:
+    # myOtherArray is passed as pointer to int to myDebug. I look up myOtherArray up in the stack
+    gdb.execute("up")
+    raw = gdb.parse_and_eval("myOtherArray")
+  else:
+    rawArg = re.sub(noSuitableRegex, "", gdb.execute("info args", to_string = True))
+    raw = rawArg.split("=", 1)[-1].strip()
+  output = str(raw)
+
+  if output != expected:
+    gdb.write(f"\x1b[38;5;196m ({output}) != expected: ({expected})\x1b[0m\n", gdb.STDERR)
+    gdb.execute("quit 1")
+  else:
+    gdb.write("\x1b[38;5;34mpassed\x1b[0m\n", gdb.STDLOG)
+  gdb.execute("continue")
diff --git a/tests/untestable/gdb/gdb_pretty_printer_test_program.nim b/tests/untestable/gdb/gdb_pretty_printer_test_program.nim
new file mode 100644
index 000000000..163c99860
--- /dev/null
+++ b/tests/untestable/gdb/gdb_pretty_printer_test_program.nim
@@ -0,0 +1,89 @@
+
+
+import tables
+
+type
+  MyEnum = enum
+    meOne,
+    meTwo,
+    meThree,
+    meFour,
+
+  MyOtherEnum = enum
+    moOne,
+    moTwo,
+    moThree,
+    moFoure,
+  
+  MyObj = object
+    a*: int
+    b*: string
+
+var counter = 0
+
+proc myDebug[T](arg: T): void =
+  counter += 1
+
+proc testProc(): void =
+  var myEnum = meTwo
+  myDebug(myEnum) #1
+  
+  # create a string, but don't allocate it
+  var myString: string
+  myDebug(myString) #2
+
+  # create a string object but also make the NTI for MyEnum is generated
+  myString = $myEnum
+  myDebug(myString) #3
+  
+  var mySet = {meOne,meThree}
+  myDebug(mySet) #4
+
+  # for MyOtherEnum there is no NTI. This tests the fallback for the pretty printer.
+  var moEnum = moTwo
+  myDebug(moEnum) #5
+
+  var moSet = {moOne,moThree}
+  myDebug(moSet) #6
+
+  let myArray = [1,2,3,4,5]
+  myDebug(myArray) #7
+
+  # implicitly initialized seq test
+  var mySeq: seq[string]
+  myDebug(mySeq) #8
+
+  # len not equal to capacity
+  let myOtherSeq = newSeqOfCap[string](10)
+  myDebug(myOtherSeq) #9
+
+  let myOtherArray = ["one","two"]
+  myDebug(myOtherArray) #10
+
+  # numeric sec
+  var mySeq3 = @[1,2,3]
+  myDebug(mySeq3) #11
+
+  # seq had to grow
+  var mySeq4 = @["one","two","three"]
+  myDebug(mySeq4) #12
+
+  var myTable = initTable[int, string]()
+  myTable[4] = "four"
+  myTable[5] = "five"
+  myTable[6] = "six"
+  myDebug(myTable) #13
+
+  var myOtherTable = {"one": 1, "two": 2, "three": 3}.toTable
+  myDebug(myOtherTable) #14
+
+  var obj = MyObj(a: 1, b: "some string")
+  myDebug(obj) #15
+
+  var tup = ("hello", 42)
+  myDebug(tup) # 16
+
+  assert counter == 16
+
+
+testProc()
diff --git a/tests/untestable/gdb/gdb_pretty_printer_test_run.sh b/tests/untestable/gdb/gdb_pretty_printer_test_run.sh
new file mode 100755
index 000000000..411c68435
--- /dev/null
+++ b/tests/untestable/gdb/gdb_pretty_printer_test_run.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+set -e
+# Compile the test project with fresh debug information.
+nim c --debugger:native --mm:orc --out:gdbNew gdb_pretty_printer_test_program.nim
+echo "Running new runtime tests..."
+# 2>&1 redirects stderr to stdout (all output in stdout)
+gdb -x gdb_pretty_printer_test.py --batch-silent --args gdbNew 2>&1
+
+
+# Do it all again, but with old runtime
+nim c --debugger:native --mm:refc --out:gdbOld gdb_pretty_printer_test_program.nim &> /dev/null
+echo "Running old runtime tests"
+gdb -x gdb_pretty_printer_test.py --batch-silent --args gdbOld 2>&1