[v2,1/4] gdb/dap: check for breakpoint source before unpacking

Message ID 20230901210422.58003-2-greg@gpanders.com
State New
Headers
Series DAP fixups |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Testing passed

Commit Message

Gregory Anders Sept. 1, 2023, 9:02 p.m. UTC
  Not all breakpoints have a source location. For example, a breakpoint
set on a raw address will have only the "address" field populated, but
"source" will be None, which leads to a RuntimeError when attempting to
unpack the filename and line number.

Before attempting to unpack the filename and line number from the
breakpoint, ensure that the source information is not None. Also
populate the source and line information separately from the
"instructionReference" field, so that breakpoints that include only an
address are still included.
---
 gdb/python/lib/gdb/dap/breakpoint.py | 20 ++++++++++++--------
 gdb/testsuite/gdb.dap/bt-nodebug.exp |  7 +++++++
 2 files changed, 19 insertions(+), 8 deletions(-)
  

Patch

diff --git a/gdb/python/lib/gdb/dap/breakpoint.py b/gdb/python/lib/gdb/dap/breakpoint.py
index 76ff129d..0ebb9597 100644
--- a/gdb/python/lib/gdb/dap/breakpoint.py
+++ b/gdb/python/lib/gdb/dap/breakpoint.py
@@ -106,14 +106,18 @@  def _breakpoint_descriptor(bp):
         # multiple locations.  See
         # https://github.com/microsoft/debug-adapter-protocol/issues/13
         loc = bp.locations[0]
-        (filename, line) = loc.source
-        result.update(
-            {
-                "source": make_source(filename, os.path.basename(filename)),
-                "line": line,
-                "instructionReference": hex(loc.address),
-            }
-        )
+        if loc.source:
+            (filename, line) = loc.source
+            result.update(
+                {
+                    "source": make_source(filename, os.path.basename(filename)),
+                    "line": line,
+                }
+            )
+
+        if loc.address:
+            result["instructionReference"] = hex(loc.address),
+
         path = loc.fullname
         if path is not None:
             result["source"]["path"] = path
diff --git a/gdb/testsuite/gdb.dap/bt-nodebug.exp b/gdb/testsuite/gdb.dap/bt-nodebug.exp
index e9726d2e..abd394ad 100644
--- a/gdb/testsuite/gdb.dap/bt-nodebug.exp
+++ b/gdb/testsuite/gdb.dap/bt-nodebug.exp
@@ -53,4 +53,11 @@  gdb_assert {[llength $frames] == 3} "three frames"
 gdb_assert {[dict get [lindex $frames 1] name] == "no_debug_info"} \
     "name of no-debug frame"
 
+# Breakpoint can be set without source file information
+set obj [dap_check_request_and_response "set breakpoint on no_debug_info" \
+	    setFunctionBreakpoints \
+	    {o breakpoints [a [o name [s no_debug_info]]]}]
+set breakpoints [dict get [lindex $obj 0] body breakpoints]
+gdb_assert {[dict exists [lindex $breakpoints 0] instructionReference]} "breakpoint has instructionReference"
+
 dap_shutdown