From: Andrey Drobyshev <[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]> Message-ID: <[email protected]> Tested-by: Fabiano Rosas <[email protected]> Reviewed-by: Kevin Wolf <[email protected]> Signed-off-by: Kevin Wolf <[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.56.0
