From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29010 invoked by alias); 13 Apr 2010 18:40:41 -0000 Received: (qmail 29002 invoked by uid 22791); 13 Apr 2010 18:40:40 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=BAYES_00,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from sibelius.xs4all.nl (HELO glazunov.sibelius.xs4all.nl) (83.163.83.176) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 13 Apr 2010 18:40:35 +0000 Received: from glazunov.sibelius.xs4all.nl (kettenis@localhost [127.0.0.1]) by glazunov.sibelius.xs4all.nl (8.14.3/8.14.3) with ESMTP id o3DIeGNP021030; Tue, 13 Apr 2010 20:40:16 +0200 (CEST) Received: (from kettenis@localhost) by glazunov.sibelius.xs4all.nl (8.14.3/8.14.3/Submit) id o3DIeDo9001302; Tue, 13 Apr 2010 20:40:13 +0200 (CEST) Date: Tue, 13 Apr 2010 18:40:00 -0000 Message-Id: <201004131840.o3DIeDo9001302@glazunov.sibelius.xs4all.nl> From: Mark Kettenis To: hjl.tools@gmail.com CC: gdb-patches@sourceware.org, jan.kratochvil@redhat.com In-reply-to: (hjl.tools@gmail.com) Subject: Re: PATCH: PR corefiles/11467: amd64 gdb generates corrupted 32bit core file References: <20100410221943.GA9675@intel.com> <20100410222742.GA9901@intel.com> <20100411000053.GA12675@intel.com> <20100411205250.GA24158@intel.com> <20100412132225.GA5932@intel.com> <201004121823.o3CINtrD023513@glazunov.sibelius.xs4all.nl> Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-04/txt/msg00419.txt.bz2 > Date: Mon, 12 Apr 2010 11:50:47 -0700 > From: "H.J. Lu" > > On Mon, Apr 12, 2010 at 11:23 AM, Mark Kettenis wrote: > >> Date: Mon, 12 Apr 2010 06:22:25 -0700 > >> From: "H.J. Lu" > >> > >> On Sun, Apr 11, 2010 at 01:52:50PM -0700, H.J. Lu wrote: > >> > Hi, > >> > > >> > Thanks for Mark's pointer. Solution is very simple. We just need to > >> > make sure that we call the right fill_gregset for 32bit executable > >> > on both Linux/x86-64 and Linux/i386.  OK to install? > >> > > >> > Thanks. > >> > > >> > > >> > >> Small update to use tdep->gregset_reg_offset instead of > >> i386_linux_gregset_reg_offset.  OK to install? > > > > No.  Like I explained in an earlier mail, we're not supposed to end up > > in fetch_gregset() in the first place. > > > > fetch_gregset is always defined and used to fill .reg section in > coredump on Linux/x86. i386-tdep.c has No, that's not how it's supposed to be. And unless there is a bug somewhere, this is not what happens for the 64x64 and 32x32 cases. > const struct regset * > i386_regset_from_core_section (struct gdbarch *gdbarch, > const char *sect_name, size_t sect_size) > { > struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); > > if (strcmp (sect_name, ".reg") == 0 && sect_size == tdep->sizeof_gregset) > { > if (tdep->gregset == NULL) > tdep->gregset = regset_alloc (gdbarch, i386_supply_gregset, > i386_collect_gregset); > return tdep->gregset; > } > > For Linux, tdep->sizeof_gregset != the size of .reg section. Then there is your bug. > In fact, they have nothing to do with each other. sizeof_gregset > includes SSE and AVX registers, which have offset == -1 since they > aren't general-purpose registers. I don't believe we should set > tdep->gregset since general-purpose registers is a special case for > Linux/x86. They are handled differently. I don't want to change it. You're wrong here. This code used to work just fine. And I believe it still works fine for the 32x32 and 64x64 cases. I see that in i386-linux-tdep.c:i386_linux_regset_sections[] specifies the size of the regset as 144 and sets tdep->sizeof_gregset to 17 * 4 = 68. That can't be right. Given that amd64-linux-tdep.c:amd64_linux_regset_sections[] specifies the size as 144 as well, I'm betting 68 is the right valaue for i386. I think somebody got confused here, since the size of the NT_PRSTATUS note in 32-bit core dumps happens to be 144, but the actual size of the space reserved for storing the registers in there is smaller. Anyway, there is a somewhat fundamental flaw in linux-nat.c:linux_nat_do_thread_registers() in that it always passes the size of 64-bit version of gregset_t in the gdbarch_regset_from_core_section() call. That's wrong, and probably the ultimate reason why the 64x32 gcore case isn't working properly.