From patchwork Fri Aug 1 13:59:53 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joel Brobecker X-Patchwork-Id: 2282 Received: (qmail 17890 invoked by alias); 1 Aug 2014 13:59:59 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 17741 invoked by uid 89); 1 Aug 2014 13:59:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 X-HELO: rock.gnat.com Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Fri, 01 Aug 2014 13:59:57 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 8D4A0116390 for ; Fri, 1 Aug 2014 09:59:55 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id afrrgwXjOoTm for ; Fri, 1 Aug 2014 09:59:55 -0400 (EDT) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 59F0D11638E for ; Fri, 1 Aug 2014 09:59:55 -0400 (EDT) Received: by joel.gnat.com (Postfix, from userid 1000) id 40FEA491C1; Fri, 1 Aug 2014 06:59:56 -0700 (PDT) From: Joel Brobecker To: gdb-patches@sourceware.org Subject: [PATCH 1/2] x64-windows: Fix extraction of chained UNWIND_INFO Date: Fri, 1 Aug 2014 06:59:53 -0700 Message-Id: <1406901594-17642-2-git-send-email-brobecker@adacore.com> In-Reply-To: <1406901594-17642-1-git-send-email-brobecker@adacore.com> References: <1406901594-17642-1-git-send-email-brobecker@adacore.com> On x86_64-windows, GDB is unable to unwind past some code in mswsock.dll. For instance: (gdb) bt #0 0x00000000778712fa in ntdll!ZwWaitForSingleObject () from C:\Windows\SYSTEM32\ntdll.dll #1 0x000007fefcfb0f75 in WSPStartup () from C:\Windows\system32\mswsock.dll Backtrace stopped: previous frame inner to this frame (corrupt stack?) The UNWIND_INFO record for frame #1's PC has a UNW_FLAG_CHAININFO flag, and so after having decoded this unwind record, GDB's decoder next tries to locate the next unwind record on the chain. Unfortunately, the location of that unwind info appears to be miscomputed. This is the expression used: chain_vma = cache->image_base + unwind_info + sizeof (ex_ui) + ((codes_count + 1) & ~1) * 2 + 8; The chain-info is expected to be right after the "Unwind codes array" which is itself after all the fields of ex_ui's struct. So the "+ 8" offset at the end should not be there. Because of that extra offset, we were reading no longer processing correct unwind info, leading the unwinder computing the wrong frame size, computing the wrong return address, etc. gdb/ChangeLog: * amd64-windows-tdep.c (amd64_windows_frame_decode_insns): Remove "+ 8" offset in computation of CHAIN_VMA. --- gdb/ChangeLog | 5 +++++ gdb/amd64-windows-tdep.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e494a2a..939fd20 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2014-08-01 Joel Brobecker + + * amd64-windows-tdep.c (amd64_windows_frame_decode_insns): + Remove "+ 8" offset in computation of CHAIN_VMA. + 2014-07-31 Doug Evans * inflow.c (child_terminal_inferior): Add comment. diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c index 331ce77..cb1bac7 100644 --- a/gdb/amd64-windows-tdep.c +++ b/gdb/amd64-windows-tdep.c @@ -826,7 +826,7 @@ amd64_windows_frame_decode_insns (struct frame_info *this_frame, CORE_ADDR chain_vma; chain_vma = cache->image_base + unwind_info - + sizeof (ex_ui) + ((codes_count + 1) & ~1) * 2 + 8; + + sizeof (ex_ui) + ((codes_count + 1) & ~1) * 2; if (target_read_memory (chain_vma, (gdb_byte *) &d, sizeof (d)) != 0) return;