From nobody Thu Dec 18 19:36:40 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1734036561; cv=none; d=zohomail.com; s=zohoarc; b=S94MHykmbEVaSN0GTeV8VjOj33eGMjASgo6xtK369V4g5FX7aQ0cagGit6VXxHfH1y5izdkcJeVO0pjqroazsz1amXFkedoNQdQvIOKBMhQTAwNa1uQGIIDdppTBIQhNhIh4H4sYLEBCh7Rf8j4pwo9Anr2AKpmxfaaxx88npvM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1734036561; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=DY6tmqvZV2o48lQYNCown9+e5sMuiAbH3ec0yr5iFFM=; b=nIzoL3LtRxa60nBmjcECdHNQI3r0/O3oWxXs3tqJzvU/lW7SwPWEdYFFU/uiUI+BHHLIlA7WJtK1aycoLG4a99fkchJqAu2HGR3NnCvsv5Ju/7H883qC9C+JegBzpjeVDZR/CrNcsy2JkMxrzu+qIViThiQJOk+3nFf9mOJPzqM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1734036561720684.7824173238009; Thu, 12 Dec 2024 12:49:21 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLq6h-0003bX-IK; Thu, 12 Dec 2024 15:48:23 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLq6g-0003b9-40 for qemu-devel@nongnu.org; Thu, 12 Dec 2024 15:48:22 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLq6X-0000u3-Vh for qemu-devel@nongnu.org; Thu, 12 Dec 2024 15:48:21 -0500 Received: from mail-io1-f72.google.com (mail-io1-f72.google.com [209.85.166.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-25-m_W9FNKqMwC6EClRrqpUQA-1; Thu, 12 Dec 2024 15:48:10 -0500 Received: by mail-io1-f72.google.com with SMTP id ca18e2360f4ac-844d38b44ebso81836039f.3 for ; Thu, 12 Dec 2024 12:48:10 -0800 (PST) Received: from x1n.redhat.com (pool-99-254-114-190.cpe.net.cable.rogers.com. [99.254.114.190]) by smtp.gmail.com with ESMTPSA id ca18e2360f4ac-844e57b48fcsm20807839f.35.2024.12.12.12.48.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 12 Dec 2024 12:48:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734036492; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=DY6tmqvZV2o48lQYNCown9+e5sMuiAbH3ec0yr5iFFM=; b=gGwndOLtltux7sPqBYWJ69wYJa9CfD6i8vY0ZwfNvTg5LZAduAN9UlBegJxxdKht16lVG1 OHij1icHacPTvCJ8Pni/Gf+motbWKL3ayHIawIvHPdlc6E27zkiP0N7HyR/4XAh46ryoNk lMuFj1q84yreM6oFHukoCqhxGk2ZJEE= X-MC-Unique: m_W9FNKqMwC6EClRrqpUQA-1 X-Mimecast-MFC-AGG-ID: m_W9FNKqMwC6EClRrqpUQA X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1734036490; x=1734641290; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=DY6tmqvZV2o48lQYNCown9+e5sMuiAbH3ec0yr5iFFM=; b=stMz/UfRf2HYk8Gkk0T/9y/G1HnXrHJh3p9iSobc13m/aJ3LFV9I13M3lqGB8q4Rag G6TECugYFOjkc++WxN/LaylnzJPTh1WvflhmXepvJpMFSCMLxRewzrX39C3YjHg8nxAH vpxz/LFLeIFEv3xnvOMlDNd9r6L9xzynTYY0nK2MFEARrZqkUWeFUE7W9Tj8YCzoQqcu zngk83iv0G8X75KqXz79giCrWwZZKmlVOutSOLimitY/xrWYIBP6wXxJNwuxnHA4SKYC AzcyhItepOY5EzGYlW+bD08MdGmDqyjirdB7DzSh8mOdeL+QH/2X9ZDqI6iyHXU8cTW/ aqsw== X-Gm-Message-State: AOJu0YxFwQoMtY1Zy++jMDgCRpDQWYk+qeWHk8UKZ/4AtUhk/aMjYUYq nJiR4kSCdLK2ISarQdz8/WY6pBtw749pPAbGNkQyJdaCntgwNbe47WjF6p8wr2aWpe8SZKsybtr YjF9b78jv5WbXNQ2TFQeleHIGLvpB/xtVPii+8+JwgZ+OjddT72DdI7DVhmZPcnINy7izmv2kil OaFMP94fMSN+CB8WsTrevYpkJZChjvXuXCUg== X-Gm-Gg: ASbGnctMPfvQU7lh5DPX/WZVdCNw5HItKhPFXb7e8/3g7FVG1lr43RoRbYIL7Cwimm7 pJpp6WvOQmtsg4ruzQiQzfX26jSxYaQZ3Mu6CUOWq56fuKl+TRfey2NW50Pfk5X1d8Rpo8ZePlb Dk89quIRz1ndztiTJfmLx9x1k65HxPtiPABM5roAQYHfB1UGwcU9HBtD1wy0GFu5l33SsxvJ2FJ IIWxrpTVIWBFK/J4oJMmm9uPN66JImwQl4u8NokQ8TmYVKEgFsdAMrBSusz9O7nX8++gi9ebo8Z 4OdqVCxKpuq406WCFJqOG0d5afPQDOhU X-Received: by 2002:a05:6602:3421:b0:82d:9b0:ecb7 with SMTP id ca18e2360f4ac-844e880ffd6mr42420439f.3.1734036489808; Thu, 12 Dec 2024 12:48:09 -0800 (PST) X-Google-Smtp-Source: AGHT+IHdbRUtARERr7o1+51xlIYpJsD97Mfv3iE/bx3I5qChrKAV3BhQsirs66CHlL2OuXOuhNzslw== X-Received: by 2002:a05:6602:3421:b0:82d:9b0:ecb7 with SMTP id ca18e2360f4ac-844e880ffd6mr42417639f.3.1734036489390; Thu, 12 Dec 2024 12:48:09 -0800 (PST) From: Peter Xu To: qemu-devel@nongnu.org Cc: Stefan Hajnoczi , Fabiano Rosas , Kevin Wolf , Paolo Bonzini , peterx@redhat.com, Peter Maydell , s_sourceforge@nedprod.com, Maxim Levitsky Subject: [PATCH v2 3/3] scripts/qemu-gdb: Support coroutine dumps in coredumps Date: Thu, 12 Dec 2024 15:48:01 -0500 Message-ID: <20241212204801.1420528-4-peterx@redhat.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241212204801.1420528-1-peterx@redhat.com> References: <20241212204801.1420528-1-peterx@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=peterx@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1734036562386116600 Content-Type: text/plain; charset="utf-8" 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 #0 process_incoming_migration_co (opaque=3D0x0) at ../migration/migratio= n.c:788 #1 0x000055ae6c0dc4d9 in coroutine_trampoline (i0=3D-1711718576, i1=3D21= 934) at ../util/coroutine-ucontext.c:175 #2 0x00007f9f59d72f40 in ??? () at /lib64/libc.so.6 #3 0x00007ffd549214a0 in ??? () #4 0x0000000000000000 in ??? () Coroutine at 0x7f9f4c57c748: #0 0x55ae6c0dc9a8 in qemu_coroutine_switch<+120> () at ../util/coroutine= -ucontext.c:321 #1 0x55ae6c0da2f8 in qemu_aio_coroutine_enter<+356> () at ../util/qemu-c= oroutine.c:293 #2 0x55ae6c0da3f1 in qemu_coroutine_enter<+34> () at ../util/qemu-corout= ine.c:316 #3 0x55ae6baf775e in migration_incoming_process<+43> () at ../migration/= migration.c:876 #4 0x55ae6baf7ab4 in migration_ioc_process_incoming<+490> () at ../migra= tion/migration.c:1008 #5 0x55ae6bae9ae7 in migration_channel_process_incoming<+145> () at ../m= igration/channel.c:45 #6 0x55ae6bb18e35 in socket_accept_incoming_migration<+118> () at ../mig= ration/socket.c:132 #7 0x55ae6be939ef in qio_net_listener_channel_func<+131> () at ../io/net= -listener.c:54 #8 0x55ae6be8ce1a in qio_channel_fd_source_dispatch<+78> () at ../io/cha= nnel-watch.c:84 #9 0x7f9f5b26728c in g_main_context_dispatch_unlocked.lto_priv<+315> () #10 0x7f9f5b267555 in g_main_context_dispatch<+36> () #11 0x55ae6c0d91a7 in glib_pollfds_poll<+90> () at ../util/main-loop.c:2= 87 #12 0x55ae6c0d9235 in os_host_main_loop_wait<+128> () at ../util/main-lo= op.c:310 #13 0x55ae6c0d9364 in main_loop_wait<+203> () at ../util/main-loop.c:589 #14 0x55ae6bac212a in qemu_main_loop<+41> () at ../system/runstate.c:835 #15 0x55ae6bfdf522 in qemu_default_main<+19> () at ../system/main.c:37 #16 0x55ae6bfdf55f in main<+40> () at ../system/main.c:48 #17 0x7f9f59d42248 in __libc_start_call_main<+119> () #18 0x7f9f59d4230b in __libc_start_main_impl<+138> () Signed-off-by: Peter Xu --- scripts/qemugdb/coroutine.py | 79 +++++++++++++++++++++++++++++++++--- 1 file changed, 73 insertions(+), 6 deletions(-) diff --git a/scripts/qemugdb/coroutine.py b/scripts/qemugdb/coroutine.py index 20f76ed37b..e98fc48a4b 100644 --- a/scripts/qemugdb/coroutine.py +++ b/scripts/qemugdb/coroutine.py @@ -46,9 +46,60 @@ def get_jmpbuf_regs(jmpbuf): 'r15': jmpbuf[JB_R15], 'rip': glibc_ptr_demangle(jmpbuf[JB_PC], pointer_guard) } =20 -def bt_jmpbuf(jmpbuf): - '''Backtrace a jmpbuf''' - regs =3D get_jmpbuf_regs(jmpbuf) +def symbol_lookup(addr): + # Example: "__clone3 + 44 in section .text of /lib64/libc.so.6" + result =3D gdb.execute(f"info symbol {hex(addr)}", to_string=3DTrue).s= trip() + try: + if "+" in result: + (func, result) =3D result.split(" + ") + (offset, result) =3D result.split(" in ") + else: + offset =3D "0" + (func, result) =3D result.split(" in ") + func_str =3D f"{func}<+{offset}> ()" + except: + return f"??? ({result})" + + # Example: Line 321 of "../util/coroutine-ucontext.c" starts at address + # 0x55cf3894d993 and ends at 0x55cf3894d9ab + # . + result =3D gdb.execute(f"info line *{hex(addr)}", to_string=3DTrue).st= rip() + if not result.startswith("Line "): + return func_str + result =3D result[5:] + + try: + result =3D result.split(" starts ")[0] + (line, path) =3D result.split(" of ") + path =3D path.replace("\"", "") + except: + return func_str + + return f"{func_str} at {path}:{line}" + +def dump_backtrace(regs): + ''' + Backtrace dump with raw registers, mimic GDB command 'bt'. + ''' + # Here only rbp and rip that matter.. + rbp =3D regs['rbp'] + rip =3D regs['rip'] + i =3D 0 + + while rbp: + # For all return addresses on stack, we want to look up symbol/line + # on the CALL command, because the return address is the next + # instruction instead of the CALL. Here -1 would work for any + # sized CALL instruction. + print(f"#{i} {hex(rip)} in {symbol_lookup(rip if i =3D=3D 0 else = rip-1)}") + rip =3D gdb.parse_and_eval(f"*(uint64_t *)(uint64_t)({hex(rbp)} + = 8)") + rbp =3D gdb.parse_and_eval(f"*(uint64_t *)(uint64_t)({hex(rbp)})") + i +=3D 1 + +def dump_backtrace_live(regs): + ''' + Backtrace dump with gdb's 'bt' command, only usable in a live session. + ''' old =3D dict() =20 # remember current stack frame and select the topmost @@ -69,6 +120,17 @@ def bt_jmpbuf(jmpbuf): =20 selected_frame.select() =20 +def bt_jmpbuf(jmpbuf): + '''Backtrace a jmpbuf''' + regs =3D 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()) =20 @@ -101,10 +163,15 @@ def invoke(self, arg, from_tty): =20 gdb.execute("bt") =20 - if gdb.parse_and_eval("qemu_in_coroutine()") =3D=3D False: - return + try: + # This only works with a live session + co_ptr =3D gdb.parse_and_eval("qemu_coroutine_self()") + except: + # Fallback to use hard-coded ucontext vars if it's coredump + co_ptr =3D gdb.parse_and_eval("co_tls_current") =20 - co_ptr =3D gdb.parse_and_eval("qemu_coroutine_self()") + if co_ptr =3D=3D False: + return =20 while True: co =3D co_cast(co_ptr) --=20 2.47.0