[PATCH 7/9] scripts/qemugdb: coroutine: Handle target absence gracefully

Andrey Drobyshev <[email protected]> Tue, 4 Aug 2026 18:17:41 +0300
Newsgroups gmane.comp.emulators.qemu
Message-ID <[email protected]>
init_coredump() picks the core dump and the executable out of fixed lines
of 'info files' output.  With no target loaded that output is empty, and
'qemu bt' dies with:

    IndexError: list index out of range

Search the whole output for the core dump file instead, and take the
executable from gdb.current_progspace(), which doesn't need parsing at
all.  Neither can raise if the pattern isn't there, so an unexpected
output format now just means "not a coredump" rather than a traceback.

That alone only moves the problem to gdb.execute("bt"), whose gdb.error
escapes invoke() and still gets reported as a python traceback.  At the
same time plain 'bt' just prints 'No stack.'.  Let's mimick this
behaviour and simply report an error if there's no selected thread.

Fixes: 42f3c143c3a0 ("scripts/qemugdb: coroutine: Add option for obtaining detailed trace in coredump")
Signed-off-by: Andrey Drobyshev <[email protected]>
---
 scripts/qemugdb/coroutine.py | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/scripts/qemugdb/coroutine.py b/scripts/qemugdb/coroutine.py
index 9148264de3c..3e0b37b73ea 100644
--- a/scripts/qemugdb/coroutine.py
+++ b/scripts/qemugdb/coroutine.py
@@ -322,16 +322,14 @@ def coroutine_to_jmpbuf(co):
 def init_coredump():
     global coredump
 
-    files = gdb.execute('info files', False, True).split('\n')
+    files = gdb.execute('info files', False, True)
 
-    if not 'core dump' in files[1]:
+    match = re.search(r"core dump file:\s*`([^']+)'", files)
+    if match is None:
         return False
 
-    core_path = re.search("`(.*)'", files[2]).group(1)
-    exec_path = re.match('^Symbols from "(.*)".$', files[0]).group(1)
-
     if coredump is None:
-        coredump = Coredump(core_path, exec_path)
+        coredump = Coredump(match.group(1), gdb.current_progspace().filename)
 
     return True
 
@@ -362,6 +360,9 @@ def invoke(self, arg, from_tty):
             return self._usage()
         detailed = True if argc == 2 else False
 
+        if gdb.selected_thread() is None:
+            raise gdb.GdbError('No stack.')
+
         is_coredump = init_coredump()
         if detailed and not is_coredump:
             gdb.write('--detailed is only valid when debugging core dumps\n')
@@ -400,6 +401,9 @@ def invoke(self, arg, from_tty):
             return self._usage()
         detailed = True if argc == 1 else False
 
+        if gdb.selected_thread() is None:
+            raise gdb.GdbError('No stack.')
+
         is_coredump = init_coredump()
         if detailed and not is_coredump:
             gdb.write('--detailed is only valid when debugging core dumps\n')
-- 
2.47.1