All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Xu <peterx@redhat.com>
To: qemu-devel@nongnu.org
Cc: Stefan Hajnoczi <stefanha@redhat.com>,
	Kevin Wolf <kwolf@redhat.com>,
	Peter Maydell <peter.maydell@linaro.org>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Maxim Levitsky <mlevitsk@redhat.com>,
	Fabiano Rosas <farosas@suse.de>
Subject: Re: [PATCH 3/3] scripts/qemu-gdb: Support coroutine dumps in coredumps
Date: Wed, 11 Dec 2024 15:21:12 -0500	[thread overview]
Message-ID: <Z1n0OHYbaTW34m3y@x1n> (raw)
In-Reply-To: <20241211201739.1380222-4-peterx@redhat.com>

On Wed, Dec 11, 2024 at 03:17:39PM -0500, Peter Xu wrote:
> Dumping coroutines don't yet work with coredumps.  Let's make it work.
> 
> We still kept most of the old code because they can be either more
> flexible, or prettier.  Only add the fallbacks when they stop working.
> 
> Currently the raw unwind is pretty ugly, but it works, like this:
> 
> (gdb) qemu bt
> Coroutine at 0x7fc474728748:

It didn't get commited.. I forgot to indent.  It looks like this:

  (gdb) qemu bt
  #0  process_incoming_migration_co (opaque=0x0) at ../migration/migration.c:788
  #1  0x000055cf3894d4d9 in coroutine_trampoline (i0=1565638480, i1=21967) at ../util/coroutine-ucontext.c:175
  #2  0x00007fc481f72f40 in ??? () at /lib64/libc.so.6
  #3  0x00007ffc0c74a520 in ??? ()
  #4  0x0000000000000000 in ??? ()
  Coroutine at 0x7fc474728748:
  #0      qemu_coroutine_switch + 120
  #1      qemu_aio_coroutine_enter + 357
  #2      qemu_coroutine_enter + 35
  #3      migration_incoming_process + 44
  #4      migration_ioc_process_incoming + 491
  #5      migration_channel_process_incoming + 146
  #6      socket_accept_incoming_migration + 119
  #7      qio_net_listener_channel_func + 132
  #8      qio_channel_fd_source_dispatch + 79
  #9      g_main_context_dispatch_unlocked.lto_priv + 316
  #10     g_main_context_dispatch + 37
  #11     glib_pollfds_poll + 91
  #12     os_host_main_loop_wait + 129
  #13     main_loop_wait + 204
  #14     qemu_main_loop + 42
  #15     qemu_default_main + 20
  #16     main + 41
  #17     __libc_start_call_main + 120
  #18     __libc_start_main_impl + 139

> 
> Signed-off-by: Peter Xu <peterx@redhat.com>
> ---
>  scripts/qemugdb/coroutine.py | 50 +++++++++++++++++++++++++++++++-----
>  1 file changed, 43 insertions(+), 7 deletions(-)
> 
> diff --git a/scripts/qemugdb/coroutine.py b/scripts/qemugdb/coroutine.py
> index 20f76ed37b..b29ee16205 100644
> --- a/scripts/qemugdb/coroutine.py
> +++ b/scripts/qemugdb/coroutine.py
> @@ -46,9 +46,30 @@ def get_jmpbuf_regs(jmpbuf):
>          'r15': jmpbuf[JB_R15],
>          'rip': glibc_ptr_demangle(jmpbuf[JB_PC], pointer_guard) }
>  
> -def bt_jmpbuf(jmpbuf):
> -    '''Backtrace a jmpbuf'''
> -    regs = get_jmpbuf_regs(jmpbuf)
> +def symbol_lookup(addr):
> +    # Example: "__clone3 + 44 in section .text of /lib64/libc.so.6"
> +    result = gdb.execute(f"info symbol {hex(addr)}", to_string=True).strip()
> +    return result.split(" in ")[0]
> +
> +def dump_backtrace(regs):
> +    '''
> +    Backtrace dump with raw registers, mimic GDB command 'bt'.
> +    '''
> +    # Here only rbp and rip that matter..
> +    rbp = regs['rbp']
> +    rip = regs['rip']
> +    i = 0
> +
> +    while rbp:
> +        print(f"#{i}\t{symbol_lookup(rip)}")
> +        rip = gdb.parse_and_eval(f"*(uint64_t *)(uint64_t)({hex(rbp)} + 8)")
> +        rbp = gdb.parse_and_eval(f"*(uint64_t *)(uint64_t)({hex(rbp)})")
> +        i += 1
> +
> +def dump_backtrace_live(regs):
> +    '''
> +    Backtrace dump with gdb's 'bt' command, only usable in a live session.
> +    '''
>      old = dict()
>  
>      # remember current stack frame and select the topmost
> @@ -69,6 +90,17 @@ def bt_jmpbuf(jmpbuf):
>  
>      selected_frame.select()
>  
> +def bt_jmpbuf(jmpbuf):
> +    '''Backtrace a jmpbuf'''
> +    regs = get_jmpbuf_regs(jmpbuf)
> +    try:
> +        # This reuses gdb's "bt" command, which can be slightly prettier
> +        # but only works with live sessions.
> +        dump_backtrace_live(regs)
> +    except:
> +        # If above doesn't work, fallback to poor man's unwind
> +        dump_backtrace(regs)
> +
>  def co_cast(co):
>      return co.cast(gdb.lookup_type('CoroutineUContext').pointer())
>  
> @@ -101,10 +133,14 @@ def invoke(self, arg, from_tty):
>  
>          gdb.execute("bt")
>  
> -        if gdb.parse_and_eval("qemu_in_coroutine()") == False:
> -            return
> -
> -        co_ptr = gdb.parse_and_eval("qemu_coroutine_self()")
> +        try:
> +            # This only works with a live session
> +            co_ptr = gdb.parse_and_eval("qemu_coroutine_self()")
> +            if co_ptr == False:
> +                return
> +        except:
> +            # Fallback to use hard-coded ucontext vars if it's coredump
> +            co_ptr = gdb.parse_and_eval("co_tls_current")
>  
>          while True:
>              co = co_cast(co_ptr)
> -- 
> 2.47.0
> 

-- 
Peter Xu



  reply	other threads:[~2024-12-11 20:22 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-11 20:17 [PATCH 0/3] scripts/qemu-gdb: Make coroutine dumps to work with coredumps Peter Xu
2024-12-11 20:17 ` [PATCH 1/3] scripts/qemu-gdb: Always do full stack dump for python errors Peter Xu
2024-12-11 20:17 ` [PATCH 2/3] scripts/qemu-gdb: Simplify fs_base fetching for coroutines Peter Xu
2024-12-11 20:17 ` [PATCH 3/3] scripts/qemu-gdb: Support coroutine dumps in coredumps Peter Xu
2024-12-11 20:21   ` Peter Xu [this message]
2024-12-11 20:25 ` [PATCH 0/3] scripts/qemu-gdb: Make coroutine dumps to work with coredumps Fabiano Rosas
2024-12-11 21:39   ` Peter Xu
2024-12-12 10:28     ` Kevin Wolf
2024-12-12 14:45       ` Peter Xu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Z1n0OHYbaTW34m3y@x1n \
    --to=peterx@redhat.com \
    --cc=farosas@suse.de \
    --cc=kwolf@redhat.com \
    --cc=mlevitsk@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.