Commit 774de38b0b for qemu.org

commit 774de38b0b773339b3869231a76ae62c776a6f5c
Author: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Date:   Tue Aug 4 18:17:36 2026 +0300

    scripts/qemugdb: coroutine: Get rid of fallback pattern when dumping backtrace

    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 <andrey.drobyshev@virtuozzo.com>
    Message-ID: <20260804151743.937694-3-andrey.drobyshev@virtuozzo.com>
    Tested-by: Fabiano Rosas <farosas@suse.de>
    Reviewed-by: Kevin Wolf <kwolf@redhat.com>
    Signed-off-by: Kevin Wolf <kwolf@redhat.com>

diff --git a/scripts/qemugdb/coroutine.py b/scripts/qemugdb/coroutine.py
index d1e6722d14..d3f31bab9f 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()