[PATCH 2/9] scripts/qemugdb: coroutine: Get rid of fallback pattern when dumping backtrace

Andrey Drobyshev <[email protected]> Tue, 4 Aug 2026 18:17:36 +0300
Newsgroups gmane.comp.emulators.qemu
Message-ID <[email protected]>
Currently upon invocation of 'qemu bt' / 'qemu coroutine' we try live
process backtrace dump first, and if it fails - fallback to coredump.
That causes us needless work and catching an exception.  In my previous
commit 42f3c143c3a0 ("scripts/qemugdb: coroutine: Add option for obtaining
detailed trace in coredump") class Coredump was introduced, and each
invocation already calls init_coredump().  Let's just pass the result of
this call further as a bool param and make a decision based upon it.
Apply the same pattern to obtaining coroutine pointer.

Note that we deliberately lose a safety net here: the bare except used to
swallow any failure of the live dump, not just the absence of a live
process, and silently fall back to the raw unwind.  Such a failure is now
reported to the user instead.

Signed-off-by: Andrey Drobyshev <[email protected]>
---
 scripts/qemugdb/coroutine.py | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/scripts/qemugdb/coroutine.py b/scripts/qemugdb/coroutine.py
index d1e6722d14d..d3f31bab9fe 100644
--- a/scripts/qemugdb/coroutine.py
+++ b/scripts/qemugdb/coroutine.py
@@ -281,20 +281,19 @@ def dump_backtrace_live(regs):
             # restore previously selected frame in any case
             selected_frame.select()
 
-def bt_jmpbuf(jmpbuf, detailed=False):
+def bt_jmpbuf(jmpbuf, is_coredump, detailed=False):
     '''Backtrace a jmpbuf'''
     regs = get_jmpbuf_regs(jmpbuf)
-    try:
+    if not is_coredump:
         # This reuses gdb's "bt" command, which can be slightly prettier
         # but only works with live sessions.
         dump_backtrace_live(regs)
-    except:
-        if detailed:
-            # Obtain detailed trace by patching regs in copied coredump
-            dump_backtrace_patched(regs)
-        else:
-            # If above doesn't work, fallback to poor man's unwind
-            dump_backtrace(regs)
+    elif detailed:
+        # Obtain detailed trace by patching regs in copied coredump
+        dump_backtrace_patched(regs)
+    else:
+        # Obtain a non-detailed trace by poor man's unwind
+        dump_backtrace(regs)
 
 def co_cast(co):
     return co.cast(gdb.lookup_type('CoroutineUContext').pointer())
@@ -353,7 +352,7 @@ def invoke(self, arg, from_tty):
 
         try:
             bt_jmpbuf(coroutine_to_jmpbuf(gdb.parse_and_eval(argv[0])),
-                      detailed=detailed)
+                      is_coredump, detailed=detailed)
         finally:
             coredump.restore_regs()
 
@@ -390,10 +389,10 @@ def invoke(self, arg, from_tty):
 
         gdb.execute("bt")
 
-        try:
+        if not is_coredump:
             # This only works with a live session
             co_ptr = gdb.parse_and_eval("qemu_coroutine_self()")
-        except:
+        else:
             # Fallback to use hard-coded ucontext vars if it's coredump
             co_ptr = gdb.parse_and_eval("co_tls_current")
 
@@ -407,7 +406,8 @@ def invoke(self, arg, from_tty):
                 if co_ptr == 0:
                     break
                 gdb.write("\nCoroutine at " + str(co_ptr) + ":\n")
-                bt_jmpbuf(coroutine_to_jmpbuf(co_ptr), detailed=detailed)
+                bt_jmpbuf(coroutine_to_jmpbuf(co_ptr), is_coredump,
+                          detailed=detailed)
         finally:
             coredump.restore_regs()
 
-- 
2.47.1