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()