From MAILER-DAEMON Tue Mar 06 01:25:04 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1S4npY-0004aZ-Mr for mharc-libunwind-devel@gnu.org; Tue, 06 Mar 2012 01:25:04 -0500 Received: from eggs.gnu.org ([208.118.235.92]:51986) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S4npW-0004Yt-G2 for libunwind-devel@nongnu.org; Tue, 06 Mar 2012 01:25:03 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1S4npU-0007yF-9r for libunwind-devel@nongnu.org; Tue, 06 Mar 2012 01:25:02 -0500 Received: from mail-qy0-f173.google.com ([209.85.216.173]:35194) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S4npU-0007y7-0U for libunwind-devel@nongnu.org; Tue, 06 Mar 2012 01:25:00 -0500 Received: by qcsc20 with SMTP id c20so2266299qcs.4 for ; Mon, 05 Mar 2012 22:24:57 -0800 (PST) Received-SPF: pass (google.com: domain of arun.sharma@gmail.com designates 10.224.174.200 as permitted sender) client-ip=10.224.174.200; Authentication-Results: mr.google.com; spf=pass (google.com: domain of arun.sharma@gmail.com designates 10.224.174.200 as permitted sender) smtp.mail=arun.sharma@gmail.com; dkim=pass header.i=arun.sharma@gmail.com Received: from mr.google.com ([10.224.174.200]) by 10.224.174.200 with SMTP id u8mr10914028qaz.57.1331015097487 (num_hops = 1); Mon, 05 Mar 2012 22:24:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type :content-transfer-encoding; bh=C+KtSytmF3nF/NRa2I6i6dNKUlMwQp0Tvkh0rk1VEFM=; b=JOnkv9kPcdYLelrFJd2IftC50vySJsVv7vkZMg9NNervKOt1bpfssw23FsZrbbsj+R 8xN0fgwwY2JhA9XY0vm7vySDoL29+XL5iNQzX+O5zPcebijkwPx2V3RwHd7zQtLLOOME 2vF1q/x0fijSCmJUqnBzxgqOecCKioGAWXlZSo6t7pQeAIuGFqBT3g9hoSyL66VxpT6j QZNmqJFcYoZeNFWP/rQdYiDJVS458dL2mPOhWE0Zf0JL3PAnt8P2QAQ9mNcByoHeAGOV 5pFZMFy2/hrE4QToFV+pV31Fmn3ntBTlMXHdk1TVmmEUxH/zRpb5A2YiSc8zpaPOVfXk QMtg== MIME-Version: 1.0 Received: by 10.224.174.200 with SMTP id u8mr9277034qaz.57.1331015097441; Mon, 05 Mar 2012 22:24:57 -0800 (PST) Sender: arun.sharma@gmail.com Received: by 10.229.94.141 with HTTP; Mon, 5 Mar 2012 22:24:57 -0800 (PST) In-Reply-To: <4F4BA743.4030405@redhat.com> References: <4F4BA6FD.6000503@redhat.com> <4F4BA743.4030405@redhat.com> Date: Mon, 5 Mar 2012 22:24:57 -0800 X-Google-Sender-Auth: Q3RdU_aZpWcculG3BNkp2Z5NPfQ Message-ID: From: Arun Sharma To: Denys Vlasenko Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.216.173 Cc: Karel Klic , Jiri Moskovcak , mtoman@redhat.com, Petr Machata , libunwind-devel@nongnu.org, Jan Kratochvil Subject: Re: [Libunwind-devel] [PATCHv3 1/4] Add core dump unwinding support to libunwind X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 06 Mar 2012 06:25:04 -0000 On Mon, Feb 27, 2012 at 7:54 AM, Denys Vlasenko wrote= : > On 02/27/2012 04:53 PM, Denys Vlasenko wrote: >> >> Patch 1: >> Introduce struct elf_dyn_info: a common part of struct UPT_info >> and struct UCD_info (to be introduced later). >> Make _UPTi_find_unwind_table function operate only on this part >> of struct UPT_info. This patch doesn't apply cleanly to HEAD (commit 3d08506). Specifically, I have problems with this hunk: > > > diff -d -urpN libunwind.0/include/libunwind_i.h > libunwind.1/include/libunwind_i.h > --- libunwind.0/include/libunwind_i.h =C2=A0 2012-02-13 18:43:50.00000000= 0 +0100 > +++ libunwind.1/include/libunwind_i.h =C2=A0 2012-02-21 17:56:59.57853668= 2 +0100 > @@ -303,6 +303,32 @@ struct elf_image > =C2=A0 =C2=A0 size_t size; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 /* (file-) size of the image */ > =C2=A0 }; > > +struct elf_dyn_info > + =C2=A0{ > + =C2=A0 =C2=A0struct elf_image ei; > + =C2=A0 =C2=A0unw_dyn_info_t di_cache; > + =C2=A0 =C2=A0unw_dyn_info_t di_debug; =C2=A0 =C2=A0/* additional table = info for .debug_frame > */ > +#if UNW_TARGET_IA64 > + =C2=A0 =C2=A0unw_dyn_info_t ktab; > +#endif > +#if UNW_TARGET_ARM > + =C2=A0 =C2=A0unw_dyn_info_t di_arm; =C2=A0 =C2=A0 =C2=A0/* additional t= able info for .ARM.exidx */ > +#endif > + =C2=A0}; > + > +static void inline invalidate_edi (struct elf_dyn_info *edi) > +{ > + =C2=A0if (edi->ei.image) > + =C2=A0 =C2=A0munmap (edi->ei.image, edi->ei.size); > + =C2=A0memset (edi, 0, sizeof (*edi)); > + =C2=A0edi->di_cache.format =3D -1; > + =C2=A0edi->di_debug.format =3D -1; > +#if UNW_TARGET_ARM > + =C2=A0edi->di_arm.format =3D -1; > +#endif > +} > + > + > =C2=A0/* Provide a place holder for architecture to override for fast acc= ess > =C2=A0 =C2=A0to memory when known not to need to validate and know the ac= cess > =C2=A0 =C2=A0will be local to the process. A suitable override will impro= ve Could you please test that the patches apply to HEAD or even better point me to a git repo I can pull from. Prefer example-core-unwind.c to be moved to the tests directory like I had in this branch: https://github.com/adsharma/libunwind/tree/coredump Other than that, nothing jumped out at me. Another round of regression testing on x86 and ARM and we should be done. -Arun From MAILER-DAEMON Wed Mar 07 07:43:06 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1S5GCw-0001jx-9e for mharc-libunwind-devel@gnu.org; Wed, 07 Mar 2012 07:43:06 -0500 Received: from eggs.gnu.org ([208.118.235.92]:59591) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S5GCL-0001fs-TT for libunwind-devel@nongnu.org; Wed, 07 Mar 2012 07:43:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1S5GC6-0001l2-5P for libunwind-devel@nongnu.org; Wed, 07 Mar 2012 07:42:29 -0500 Received: from mx1.redhat.com ([209.132.183.28]:33507) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S5GC5-0001kd-JC for libunwind-devel@nongnu.org; Wed, 07 Mar 2012 07:42:14 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q27Cg9tM021407 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Mar 2012 07:42:10 -0500 Received: from [10.34.25.62] (dhcp-25-62.brq.redhat.com [10.34.25.62]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q27Cg4IE027816; Wed, 7 Mar 2012 07:42:06 -0500 Message-ID: <4F57579B.5060003@redhat.com> Date: Wed, 07 Mar 2012 13:42:03 +0100 From: Denys Vlasenko User-Agent: Mozilla/5.0 (X11; Linux i686; rv:10.0) Gecko/20120131 Thunderbird/10.0 MIME-Version: 1.0 To: Arun Sharma References: <4F4BA6FD.6000503@redhat.com> <4F4BA743.4030405@redhat.com> In-Reply-To: Content-Type: multipart/mixed; boundary="------------060801080503000600010903" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: Karel Klic , Jiri Moskovcak , mtoman@redhat.com, Petr Machata , libunwind-devel@nongnu.org, Jan Kratochvil Subject: Re: [Libunwind-devel] [PATCHv3 1/4] Add core dump unwinding support to libunwind X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 07 Mar 2012 12:43:04 -0000 This is a multi-part message in MIME format. --------------060801080503000600010903 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit On 03/06/2012 07:24 AM, Arun Sharma wrote: > On Mon, Feb 27, 2012 at 7:54 AM, Denys Vlasenko wrote: >> On 02/27/2012 04:53 PM, Denys Vlasenko wrote: >>> >>> Patch 1: >>> Introduce struct elf_dyn_info: a common part of struct UPT_info >>> and struct UCD_info (to be introduced later). >>> Make _UPTi_find_unwind_table function operate only on this part >>> of struct UPT_info. > > This patch doesn't apply cleanly to HEAD (commit 3d08506). Looks like Thunderbird inserts an extra space to every line which already has a space. And it does NOT show this space in the email when viewed in Thunderbird, but it is there (I see it when I use "View message source", or save the message as a file). The corruption originated on my end - I examined the messages in 'sent' folder. :( I am resending the very same patches as attachments. I verified that they apply cleanly to current git (git://git.sv.gnu.org/libunwind.git). Sorry. -- vda --------------060801080503000600010903 Content-Type: text/x-patch; name="1.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="1.patch" diff -d -urpN libunwind.0/include/libunwind_i.h libunwind.1/include/libunwind_i.h --- libunwind.0/include/libunwind_i.h 2012-02-13 18:43:50.000000000 +0100 +++ libunwind.1/include/libunwind_i.h 2012-02-21 17:56:59.578536682 +0100 @@ -303,6 +303,32 @@ struct elf_image size_t size; /* (file-) size of the image */ }; +struct elf_dyn_info + { + struct elf_image ei; + unw_dyn_info_t di_cache; + unw_dyn_info_t di_debug; /* additional table info for .debug_frame */ +#if UNW_TARGET_IA64 + unw_dyn_info_t ktab; +#endif +#if UNW_TARGET_ARM + unw_dyn_info_t di_arm; /* additional table info for .ARM.exidx */ +#endif + }; + +static void inline invalidate_edi (struct elf_dyn_info *edi) +{ + if (edi->ei.image) + munmap (edi->ei.image, edi->ei.size); + memset (edi, 0, sizeof (*edi)); + edi->di_cache.format = -1; + edi->di_debug.format = -1; +#if UNW_TARGET_ARM + edi->di_arm.format = -1; +#endif +} + + /* Provide a place holder for architecture to override for fast access to memory when known not to need to validate and know the access will be local to the process. A suitable override will improve diff -d -urpN libunwind.0/src/ptrace/_UPT_create.c libunwind.1/src/ptrace/_UPT_create.c --- libunwind.0/src/ptrace/_UPT_create.c 2012-02-13 18:43:50.000000000 +0100 +++ libunwind.1/src/ptrace/_UPT_create.c 2012-02-21 17:56:38.459568435 +0100 @@ -37,10 +37,10 @@ _UPT_create (pid_t pid) memset (ui, 0, sizeof (*ui)); ui->pid = pid; - ui->di_cache.format = -1; - ui->di_debug.format = -1; + ui->edi.di_cache.format = -1; + ui->edi.di_debug.format = -1; #if UNW_TARGET_IA64 - ui->ktab.format = -1;; + ui->edi.ktab.format = -1; #endif return ui; } diff -d -urpN libunwind.0/src/ptrace/_UPT_destroy.c libunwind.1/src/ptrace/_UPT_destroy.c --- libunwind.0/src/ptrace/_UPT_destroy.c 2012-02-13 18:43:50.000000000 +0100 +++ libunwind.1/src/ptrace/_UPT_destroy.c 2012-02-21 17:56:38.460568434 +0100 @@ -29,10 +29,6 @@ void _UPT_destroy (void *ptr) { struct UPT_info *ui = (struct UPT_info *) ptr; - if (ui->ei.image) - { - munmap(ui->ei.image, ui->ei.size); - } - + invalidate_edi (&ui->edi); free (ptr); } diff -d -urpN libunwind.0/src/ptrace/_UPT_find_proc_info.c libunwind.1/src/ptrace/_UPT_find_proc_info.c --- libunwind.0/src/ptrace/_UPT_find_proc_info.c 2012-02-13 18:43:50.000000000 +0100 +++ libunwind.1/src/ptrace/_UPT_find_proc_info.c 2012-02-21 17:56:38.460568434 +0100 @@ -37,10 +37,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DE #include "elf64.h" static unw_word_t -find_gp (struct UPT_info *ui, Elf64_Phdr *pdyn, Elf64_Addr load_base) +find_gp (struct elf_dyn_info *edi, Elf64_Phdr *pdyn, Elf64_Addr load_base) { Elf64_Off soff, str_soff; - Elf64_Ehdr *ehdr = ui->ei.image; + Elf64_Ehdr *ehdr = edi->ei.image; Elf64_Shdr *shdr; Elf64_Shdr *str_shdr; Elf64_Addr gp = 0; @@ -51,7 +51,7 @@ find_gp (struct UPT_info *ui, Elf64_Phdr { /* If we have a PT_DYNAMIC program header, fetch the gp-value from the DT_PLTGOT entry. */ - Elf64_Dyn *dyn = (Elf64_Dyn *) (pdyn->p_offset + (char *) ui->ei.image); + Elf64_Dyn *dyn = (Elf64_Dyn *) (pdyn->p_offset + (char *) edi->ei.image); for (; dyn->d_tag != DT_NULL; ++dyn) if (dyn->d_tag == DT_PLTGOT) { @@ -68,35 +68,35 @@ find_gp (struct UPT_info *ui, Elf64_Phdr soff = ehdr->e_shoff; str_soff = soff + (ehdr->e_shstrndx * ehdr->e_shentsize); - if (soff + ehdr->e_shnum * ehdr->e_shentsize > ui->ei.size) + if (soff + ehdr->e_shnum * ehdr->e_shentsize > edi->ei.size) { Debug (1, "section table outside of image? (%lu > %lu)", soff + ehdr->e_shnum * ehdr->e_shentsize, - ui->ei.size); + edi->ei.size); goto done; } - shdr = (Elf64_Shdr *) ((char *) ui->ei.image + soff); - str_shdr = (Elf64_Shdr *) ((char *) ui->ei.image + str_soff); - strtab = (char *) ui->ei.image + str_shdr->sh_offset; + shdr = (Elf64_Shdr *) ((char *) edi->ei.image + soff); + str_shdr = (Elf64_Shdr *) ((char *) edi->ei.image + str_soff); + strtab = (char *) edi->ei.image + str_shdr->sh_offset; for (i = 0; i < ehdr->e_shnum; ++i) { if (strcmp (strtab + shdr->sh_name, ".opd") == 0 && shdr->sh_size >= 16) { - gp = ((Elf64_Addr *) ((char *) ui->ei.image + shdr->sh_offset))[1]; + gp = ((Elf64_Addr *) ((char *) edi->ei.image + shdr->sh_offset))[1]; goto done; } shdr = (Elf64_Shdr *) (((char *) shdr) + ehdr->e_shentsize); } done: - Debug (16, "image at %p, gp = %lx\n", ui->ei.image, gp); + Debug (16, "image at %p, gp = %lx\n", edi->ei.image, gp); return gp; } HIDDEN int -_UPTi_find_unwind_table (struct UPT_info *ui, unw_addr_space_t as, +_UPTi_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, char *path, unw_word_t segbase, unw_word_t mapoff, unw_word_t ip) { @@ -104,11 +104,11 @@ _UPTi_find_unwind_table (struct UPT_info Elf64_Ehdr *ehdr; int i; - if (!_Uelf64_valid_object (&ui->ei)) + if (!_Uelf64_valid_object (&edi->ei)) return -UNW_ENOINFO; - ehdr = ui->ei.image; - phdr = (Elf64_Phdr *) ((char *) ui->ei.image + ehdr->e_phoff); + ehdr = edi->ei.image; + phdr = (Elf64_Phdr *) ((char *) edi->ei.image + ehdr->e_phoff); for (i = 0; i < ehdr->e_phnum; ++i) { @@ -134,15 +134,15 @@ _UPTi_find_unwind_table (struct UPT_info if (!ptxt || !punw) return 0; - ui->di_cache.start_ip = segbase; - ui->di_cache.end_ip = ui->di_cache.start_ip + ptxt->p_memsz; - ui->di_cache.gp = find_gp (ui, pdyn, segbase - ptxt->p_vaddr); - ui->di_cache.format = UNW_INFO_FORMAT_TABLE; - ui->di_cache.u.ti.name_ptr = 0; - ui->di_cache.u.ti.segbase = segbase; - ui->di_cache.u.ti.table_len = punw->p_memsz / sizeof (unw_word_t); - ui->di_cache.u.ti.table_data = (unw_word_t *) - ((char *) ui->ei.image + (punw->p_vaddr - ptxt->p_vaddr)); + edi->di_cache.start_ip = segbase; + edi->di_cache.end_ip = edi->di_cache.start_ip + ptxt->p_memsz; + edi->di_cache.gp = find_gp (edi, pdyn, segbase - ptxt->p_vaddr); + edi->di_cache.format = UNW_INFO_FORMAT_TABLE; + edi->di_cache.u.ti.name_ptr = 0; + edi->di_cache.u.ti.segbase = segbase; + edi->di_cache.u.ti.table_len = punw->p_memsz / sizeof (unw_word_t); + edi->di_cache.u.ti.table_data = (unw_word_t *) + ((char *) edi->ei.image + (punw->p_vaddr - ptxt->p_vaddr)); return 1; } @@ -165,7 +165,7 @@ dwarf_read_encoded_pointer (unw_addr_spa } HIDDEN int -_UPTi_find_unwind_table (struct UPT_info *ui, unw_addr_space_t as, +_UPTi_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, char *path, unw_word_t segbase, unw_word_t mapoff, unw_word_t ip) { @@ -185,11 +185,11 @@ _UPTi_find_unwind_table (struct UPT_info /* XXX: Much of this code is Linux/LSB-specific. */ - if (!elf_w(valid_object) (&ui->ei)) + if (!elf_w(valid_object) (&edi->ei)) return -UNW_ENOINFO; - ehdr = ui->ei.image; - phdr = (Elf_W(Phdr) *) ((char *) ui->ei.image + ehdr->e_phoff); + ehdr = edi->ei.image; + phdr = (Elf_W(Phdr) *) ((char *) edi->ei.image + ehdr->e_phoff); for (i = 0; i < ehdr->e_phnum; ++i) { @@ -204,8 +204,8 @@ _UPTi_find_unwind_table (struct UPT_info if (phdr[i].p_offset == mapoff) ptxt = phdr + i; - if ((uintptr_t) ui->ei.image + phdr->p_filesz > max_load_addr) - max_load_addr = (uintptr_t) ui->ei.image + phdr->p_filesz; + if ((uintptr_t) edi->ei.image + phdr->p_filesz > max_load_addr) + max_load_addr = (uintptr_t) edi->ei.image + phdr->p_filesz; break; case PT_GNU_EH_FRAME: @@ -242,13 +242,13 @@ _UPTi_find_unwind_table (struct UPT_info DT_PLTGOT is the value that data-relative addresses are relative to for that object. We call this the "gp". */ Elf_W(Dyn) *dyn = (Elf_W(Dyn) *)(pdyn->p_offset - + (char *) ui->ei.image); + + (char *) edi->ei.image); for (; dyn->d_tag != DT_NULL; ++dyn) if (dyn->d_tag == DT_PLTGOT) { /* Assume that _DYNAMIC is writable and GLIBC has relocated it (true for x86 at least). */ - ui->di_cache.gp = dyn->d_un.d_ptr; + edi->di_cache.gp = dyn->d_un.d_ptr; break; } } @@ -256,10 +256,10 @@ _UPTi_find_unwind_table (struct UPT_info /* Otherwise this is a static executable with no _DYNAMIC. Assume that data-relative addresses are relative to 0, i.e., absolute. */ - ui->di_cache.gp = 0; + edi->di_cache.gp = 0; hdr = (struct dwarf_eh_frame_hdr *) (peh_hdr->p_offset - + (char *) ui->ei.image); + + (char *) edi->ei.image); if (hdr->version != DW_EH_VERSION) { Debug (1, "table `%s' has unexpected version %d\n", @@ -275,7 +275,7 @@ _UPTi_find_unwind_table (struct UPT_info job. Since we don't have a procedure-context at this point, all we have to do is fill in the global-pointer. */ memset (&pi, 0, sizeof (pi)); - pi.gp = ui->di_cache.gp; + pi.gp = edi->di_cache.gp; /* (Optionally) read eh_frame_ptr: */ if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, @@ -317,20 +317,20 @@ _UPTi_find_unwind_table (struct UPT_info #endif } - ui->di_cache.start_ip = start_ip; - ui->di_cache.end_ip = end_ip; - ui->di_cache.format = UNW_INFO_FORMAT_REMOTE_TABLE; - ui->di_cache.u.rti.name_ptr = 0; + edi->di_cache.start_ip = start_ip; + edi->di_cache.end_ip = end_ip; + edi->di_cache.format = UNW_INFO_FORMAT_REMOTE_TABLE; + edi->di_cache.u.rti.name_ptr = 0; /* two 32-bit values (ip_offset/fde_offset) per table-entry: */ - ui->di_cache.u.rti.table_len = (fde_count * 8) / sizeof (unw_word_t); - ui->di_cache.u.rti.table_data = ((load_base + peh_hdr->p_vaddr) - + (addr - (unw_word_t) ui->ei.image + edi->di_cache.u.rti.table_len = (fde_count * 8) / sizeof (unw_word_t); + edi->di_cache.u.rti.table_data = ((load_base + peh_hdr->p_vaddr) + + (addr - (unw_word_t) edi->ei.image - peh_hdr->p_offset)); /* For the binary-search table in the eh_frame_hdr, data-relative means relative to the start of that section... */ - ui->di_cache.u.rti.segbase = ((load_base + peh_hdr->p_vaddr) - + ((unw_word_t) hdr - (unw_word_t) ui->ei.image + edi->di_cache.u.rti.segbase = ((load_base + peh_hdr->p_vaddr) + + ((unw_word_t) hdr - (unw_word_t) edi->ei.image - peh_hdr->p_offset)); found = 1; } @@ -338,19 +338,19 @@ _UPTi_find_unwind_table (struct UPT_info #if UNW_TARGET_ARM if (parm_exidx) { - ui->di_arm.format = UNW_INFO_FORMAT_ARM_EXIDX; - ui->di_arm.start_ip = start_ip; - ui->di_arm.end_ip = end_ip; - ui->di_arm.u.rti.name_ptr = (unw_word_t) path; - ui->di_arm.u.rti.table_data = load_base + parm_exidx->p_vaddr; - ui->di_arm.u.rti.table_len = parm_exidx->p_memsz; + edi->di_arm.format = UNW_INFO_FORMAT_ARM_EXIDX; + edi->di_arm.start_ip = start_ip; + edi->di_arm.end_ip = end_ip; + edi->di_arm.u.rti.name_ptr = (unw_word_t) path; + edi->di_arm.u.rti.table_data = load_base + parm_exidx->p_vaddr; + edi->di_arm.u.rti.table_len = parm_exidx->p_memsz; found = 1; } #endif #ifdef CONFIG_DEBUG_FRAME /* Try .debug_frame. */ - found = dwarf_find_debug_frame (found, &ui->di_debug, ip, segbase, path, + found = dwarf_find_debug_frame (found, &edi->edi.di_debug, ip, segbase, path, start_ip, end_ip); #endif @@ -360,72 +360,57 @@ _UPTi_find_unwind_table (struct UPT_info #endif /* UNW_TARGET_X86 || UNW_TARGET_X86_64 || UNW_TARGET_HPPA*/ static int -get_unwind_info (struct UPT_info *ui, unw_addr_space_t as, unw_word_t ip) +get_unwind_info (struct elf_dyn_info *edi, pid_t pid, unw_addr_space_t as, unw_word_t ip) { unsigned long segbase, mapoff; char path[PATH_MAX]; #if UNW_TARGET_IA64 && defined(__linux) - if (!ui->ktab.start_ip && _Uia64_get_kernel_table (&ui->ktab) < 0) + if (!edi->ktab.start_ip && _Uia64_get_kernel_table (&edi->ktab) < 0) return -UNW_ENOINFO; - if (ui->ktab.format != -1 && ip >= ui->ktab.start_ip && ip < ui->ktab.end_ip) + if (edi->ktab.format != -1 && ip >= edi->ktab.start_ip && ip < edi->ktab.end_ip) return 0; #endif - if ((ui->di_cache.format != -1 - && ip >= ui->di_cache.start_ip && ip < ui->di_cache.end_ip) + if ((edi->di_cache.format != -1 + && ip >= edi->di_cache.start_ip && ip < edi->di_cache.end_ip) #if UNW_TARGET_ARM - || (ui->di_debug.format != -1 - && ip >= ui->di_arm.start_ip && ip < ui->di_arm.end_ip) + || (edi->di_debug.format != -1 + && ip >= edi->di_arm.start_ip && ip < edi->di_arm.end_ip) #endif - || (ui->di_debug.format != -1 - && ip >= ui->di_debug.start_ip && ip < ui->di_debug.end_ip)) + || (edi->di_debug.format != -1 + && ip >= edi->di_debug.start_ip && ip < edi->di_debug.end_ip)) return 0; - if (ui->ei.image) - { - munmap (ui->ei.image, ui->ei.size); - ui->ei.image = NULL; - ui->ei.size = 0; - - /* invalidate the cache: */ - ui->di_cache.start_ip = ui->di_cache.end_ip = 0; - ui->di_debug.start_ip = ui->di_debug.end_ip = 0; - ui->di_cache.format = -1; - ui->di_debug.format = -1; -#if UNW_TARGET_ARM - ui->di_arm.start_ip = ui->di_arm.end_ip = 0; - ui->di_arm.format = -1; -#endif - } + invalidate_edi(edi); - if (tdep_get_elf_image (&ui->ei, ui->pid, ip, &segbase, &mapoff, path, + if (tdep_get_elf_image (&edi->ei, pid, ip, &segbase, &mapoff, path, sizeof(path)) < 0) return -UNW_ENOINFO; /* Here, SEGBASE is the starting-address of the (mmap'ped) segment which covers the IP we're looking for. */ - if (_UPTi_find_unwind_table (ui, as, path, segbase, mapoff, ip) < 0) + if (_UPTi_find_unwind_table (edi, as, path, segbase, mapoff, ip) < 0) return -UNW_ENOINFO; /* This can happen in corner cases where dynamically generated code falls into the same page that contains the data-segment and the page-offset of the code is within the first page of the executable. */ - if (ui->di_cache.format != -1 - && (ip < ui->di_cache.start_ip || ip >= ui->di_cache.end_ip)) - ui->di_cache.format = -1; + if (edi->di_cache.format != -1 + && (ip < edi->di_cache.start_ip || ip >= edi->di_cache.end_ip)) + edi->di_cache.format = -1; - if (ui->di_debug.format != -1 - && (ip < ui->di_debug.start_ip || ip >= ui->di_debug.end_ip)) - ui->di_debug.format = -1; + if (edi->di_debug.format != -1 + && (ip < edi->di_debug.start_ip || ip >= edi->di_debug.end_ip)) + edi->di_debug.format = -1; - if (ui->di_cache.format == -1 + if (edi->di_cache.format == -1 #if UNW_TARGET_ARM - && ui->di_arm.format == -1 + && edi->di_arm.format == -1 #endif - && ui->di_debug.format == -1) + && edi->di_debug.format == -1) return -UNW_ENOINFO; return 0; @@ -438,11 +423,11 @@ _UPT_find_proc_info (unw_addr_space_t as struct UPT_info *ui = arg; int ret = -UNW_ENOINFO; - if (get_unwind_info (ui, as, ip) < 0) + if (get_unwind_info (&ui->edi, ui->pid, as, ip) < 0) return -UNW_ENOINFO; #if UNW_TARGET_IA64 - if (ui->ktab.format != -1) + if (ui->edi.ktab.format != -1) { /* The kernel unwind table resides in local memory, so we have to use the local address space to search it. Since @@ -450,7 +435,7 @@ _UPT_find_proc_info (unw_addr_space_t as case, we simply make a copy of the unwind-info, so _UPT_put_unwind_info() can always free() the unwind-info without ill effects. */ - ret = tdep_search_unwind_table (unw_local_addr_space, ip, &ui->ktab, pi, + ret = tdep_search_unwind_table (unw_local_addr_space, ip, &ui->edi.ktab, pi, need_unwind_info, arg); if (ret >= 0) { @@ -469,18 +454,18 @@ _UPT_find_proc_info (unw_addr_space_t as } #endif - if (ret == -UNW_ENOINFO && ui->di_cache.format != -1) - ret = tdep_search_unwind_table (as, ip, &ui->di_cache, + if (ret == -UNW_ENOINFO && ui->edi.di_cache.format != -1) + ret = tdep_search_unwind_table (as, ip, &ui->edi.di_cache, pi, need_unwind_info, arg); #if UNW_TARGET_ARM - if (ret == -UNW_ENOINFO && ui->di_arm.format != -1) - ret = tdep_search_unwind_table (as, ip, &ui->di_arm, pi, + if (ret == -UNW_ENOINFO && ui->edi.di_arm.format != -1) + ret = tdep_search_unwind_table (as, ip, &ui->edi.di_arm, pi, need_unwind_info, arg); #endif - if (ret == -UNW_ENOINFO && ui->di_debug.format != -1) - ret = tdep_search_unwind_table (as, ip, &ui->di_debug, pi, + if (ret == -UNW_ENOINFO && ui->edi.di_debug.format != -1) + ret = tdep_search_unwind_table (as, ip, &ui->edi.di_debug, pi, need_unwind_info, arg); return ret; diff -d -urpN libunwind.0/src/ptrace/_UPT_get_dyn_info_list_addr.c libunwind.1/src/ptrace/_UPT_get_dyn_info_list_addr.c --- libunwind.0/src/ptrace/_UPT_get_dyn_info_list_addr.c 2012-02-13 18:43:50.000000000 +0100 +++ libunwind.1/src/ptrace/_UPT_get_dyn_info_list_addr.c 2012-02-21 17:56:38.461568435 +0100 @@ -46,24 +46,17 @@ get_list_addr (unw_addr_space_t as, unw_ if (off) continue; - if (ui->ei.image) - { - munmap (ui->ei.image, ui->ei.size); - ui->ei.image = NULL; - ui->ei.size = 0; - /* invalidate the cache: */ - ui->di_cache.start_ip = ui->di_cache.end_ip = 0; - } + invalidate_edi(&ui->edi); - if (elf_map_image (&ui->ei, path) < 0) + if (elf_map_image (&ui->edi.ei, path) < 0) /* ignore unmappable stuff like "/SYSV00001b58 (deleted)" */ continue; Debug (16, "checking object %s\n", path); - if (_UPTi_find_unwind_table (ui, as, path, lo, off, 0) > 0) + if (_UPTi_find_unwind_table (&ui->edi, as, path, lo, off, 0) > 0) { - res = _Uia64_find_dyn_list (as, &ui->di_cache, arg); + res = _Uia64_find_dyn_list (as, &ui->edi.di_cache, arg); if (res && count++ == 0) { Debug (12, "dyn_info_list_addr = 0x%lx\n", (long) res); diff -d -urpN libunwind.0/src/ptrace/_UPT_internal.h libunwind.1/src/ptrace/_UPT_internal.h --- libunwind.0/src/ptrace/_UPT_internal.h 2012-02-13 18:43:50.000000000 +0100 +++ libunwind.1/src/ptrace/_UPT_internal.h 2012-02-21 17:56:38.461568435 +0100 @@ -51,20 +51,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DE struct UPT_info { pid_t pid; /* the process-id of the child we're unwinding */ - struct elf_image ei; - unw_dyn_info_t di_cache; - unw_dyn_info_t di_debug; /* additional table info for .debug_frame */ -#if UNW_TARGET_IA64 - unw_dyn_info_t ktab; -#endif -#if UNW_TARGET_ARM - unw_dyn_info_t di_arm; /* additional table info for .ARM.exidx */ -#endif + struct elf_dyn_info edi; }; extern int _UPT_reg_offset[UNW_REG_LAST + 1]; -extern int _UPTi_find_unwind_table (struct UPT_info *ui, +extern int _UPTi_find_unwind_table (struct elf_dyn_info *ui, unw_addr_space_t as, char *path, unw_word_t segbase, --------------060801080503000600010903 Content-Type: text/x-patch; name="2.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="2.patch" diff -d -urpN libunwind.1/include/dwarf.h libunwind.2/include/dwarf.h --- libunwind.1/include/dwarf.h 2012-02-13 18:43:50.000000000 +0100 +++ libunwind.2/include/dwarf.h 2012-02-27 16:14:57.335963966 +0100 @@ -37,6 +37,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DE #include struct dwarf_cursor; /* forward-declaration */ +struct elf_dyn_info; #include "dwarf-config.h" #ifndef UNW_REMOTE_ONLY @@ -368,6 +369,7 @@ struct dwarf_callback_data #define dwarf_find_proc_info UNW_OBJ (dwarf_find_proc_info) #define dwarf_find_debug_frame UNW_OBJ (dwarf_find_debug_frame) #define dwarf_search_unwind_table UNW_OBJ (dwarf_search_unwind_table) +#define dwarf_find_unwind_table UNW_OBJ (dwarf_find_unwind_table) #define dwarf_put_unwind_info UNW_OBJ (dwarf_put_unwind_info) #define dwarf_put_unwind_info UNW_OBJ (dwarf_put_unwind_info) #define dwarf_eval_expr UNW_OBJ (dwarf_eval_expr) @@ -395,6 +397,9 @@ extern int dwarf_search_unwind_table (un unw_dyn_info_t *di, unw_proc_info_t *pi, int need_unwind_info, void *arg); +extern int dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, + char *path, unw_word_t segbase, unw_word_t mapoff, + unw_word_t ip); extern void dwarf_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg); extern int dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr, diff -d -urpN libunwind.1/src/dwarf/Gfind_unwind_table.c libunwind.2/src/dwarf/Gfind_unwind_table.c --- libunwind.1/src/dwarf/Gfind_unwind_table.c 1970-01-01 01:00:00.000000000 +0100 +++ libunwind.2/src/dwarf/Gfind_unwind_table.c 2012-02-27 16:14:06.984901200 +0100 @@ -0,0 +1,348 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include +#include + +#include + +#include "libunwind_i.h" + +#if UNW_TARGET_IA64 + +#include "elf64.h" + +static unw_word_t +find_gp (struct elf_dyn_info *edi, Elf64_Phdr *pdyn, Elf64_Addr load_base) +{ + Elf64_Off soff, str_soff; + Elf64_Ehdr *ehdr = edi->ei.image; + Elf64_Shdr *shdr; + Elf64_Shdr *str_shdr; + Elf64_Addr gp = 0; + char *strtab; + int i; + + if (pdyn) + { + /* If we have a PT_DYNAMIC program header, fetch the gp-value + from the DT_PLTGOT entry. */ + Elf64_Dyn *dyn = (Elf64_Dyn *) (pdyn->p_offset + (char *) edi->ei.image); + for (; dyn->d_tag != DT_NULL; ++dyn) + if (dyn->d_tag == DT_PLTGOT) + { + gp = (Elf64_Addr) dyn->d_un.d_ptr + load_base; + goto done; + } + } + + /* Without a PT_DYAMIC header, lets try to look for a non-empty .opd + section. If there is such a section, we know it's full of + function descriptors, and we can simply pick up the gp from the + second word of the first entry in this table. */ + + soff = ehdr->e_shoff; + str_soff = soff + (ehdr->e_shstrndx * ehdr->e_shentsize); + + if (soff + ehdr->e_shnum * ehdr->e_shentsize > edi->ei.size) + { + Debug (1, "section table outside of image? (%lu > %lu)", + soff + ehdr->e_shnum * ehdr->e_shentsize, + edi->ei.size); + goto done; + } + + shdr = (Elf64_Shdr *) ((char *) edi->ei.image + soff); + str_shdr = (Elf64_Shdr *) ((char *) edi->ei.image + str_soff); + strtab = (char *) edi->ei.image + str_shdr->sh_offset; + for (i = 0; i < ehdr->e_shnum; ++i) + { + if (strcmp (strtab + shdr->sh_name, ".opd") == 0 + && shdr->sh_size >= 16) + { + gp = ((Elf64_Addr *) ((char *) edi->ei.image + shdr->sh_offset))[1]; + goto done; + } + shdr = (Elf64_Shdr *) (((char *) shdr) + ehdr->e_shentsize); + } + + done: + Debug (16, "image at %p, gp = %lx\n", edi->ei.image, gp); + return gp; +} + +int +dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, + char *path, unw_word_t segbase, unw_word_t mapoff, + unw_word_t ip) +{ + Elf64_Phdr *phdr, *ptxt = NULL, *punw = NULL, *pdyn = NULL; + Elf64_Ehdr *ehdr; + int i; + + if (!_Uelf64_valid_object (&edi->ei)) + return -UNW_ENOINFO; + + ehdr = edi->ei.image; + phdr = (Elf64_Phdr *) ((char *) edi->ei.image + ehdr->e_phoff); + + for (i = 0; i < ehdr->e_phnum; ++i) + { + switch (phdr[i].p_type) + { + case PT_LOAD: + if (phdr[i].p_offset == mapoff) + ptxt = phdr + i; + break; + + case PT_IA_64_UNWIND: + punw = phdr + i; + break; + + case PT_DYNAMIC: + pdyn = phdr + i; + break; + + default: + break; + } + } + if (!ptxt || !punw) + return 0; + + edi->di_cache.start_ip = segbase; + edi->di_cache.end_ip = edi->di_cache.start_ip + ptxt->p_memsz; + edi->di_cache.gp = find_gp (edi, pdyn, segbase - ptxt->p_vaddr); + edi->di_cache.format = UNW_INFO_FORMAT_TABLE; + edi->di_cache.u.ti.name_ptr = 0; + edi->di_cache.u.ti.segbase = segbase; + edi->di_cache.u.ti.table_len = punw->p_memsz / sizeof (unw_word_t); + edi->di_cache.u.ti.table_data = (unw_word_t *) + ((char *) edi->ei.image + (punw->p_vaddr - ptxt->p_vaddr)); + return 1; +} + +#elif UNW_TARGET_X86 || UNW_TARGET_X86_64 || UNW_TARGET_HPPA \ +|| UNW_TARGET_PPC32 || UNW_TARGET_PPC64 || UNW_TARGET_ARM + +#include "dwarf-eh.h" +#include "dwarf_i.h" + +int +dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, + char *path, unw_word_t segbase, unw_word_t mapoff, + unw_word_t ip) +{ + Elf_W(Phdr) *phdr, *ptxt = NULL, *peh_hdr = NULL, *pdyn = NULL; + unw_word_t addr, eh_frame_start, fde_count, load_base; + unw_word_t max_load_addr = 0; + unw_word_t start_ip = (unw_word_t) -1; + unw_word_t end_ip = 0; + struct dwarf_eh_frame_hdr *hdr; + unw_proc_info_t pi; + unw_accessors_t *a; + Elf_W(Ehdr) *ehdr; +#if UNW_TARGET_ARM + const Elf_W(Phdr) *parm_exidx = NULL; +#endif + int i, ret, found = 0; + + /* XXX: Much of this code is Linux/LSB-specific. */ + + if (!elf_w(valid_object) (&edi->ei)) + return -UNW_ENOINFO; + + ehdr = edi->ei.image; + phdr = (Elf_W(Phdr) *) ((char *) edi->ei.image + ehdr->e_phoff); + + for (i = 0; i < ehdr->e_phnum; ++i) + { + switch (phdr[i].p_type) + { + case PT_LOAD: + if (phdr[i].p_vaddr < start_ip) + start_ip = phdr[i].p_vaddr; + + if (phdr[i].p_vaddr + phdr[i].p_memsz > end_ip) + end_ip = phdr[i].p_vaddr + phdr[i].p_memsz; + + if (phdr[i].p_offset == mapoff) + ptxt = phdr + i; + if ((uintptr_t) edi->ei.image + phdr->p_filesz > max_load_addr) + max_load_addr = (uintptr_t) edi->ei.image + phdr->p_filesz; + break; + + case PT_GNU_EH_FRAME: + peh_hdr = phdr + i; + break; + + case PT_DYNAMIC: + pdyn = phdr + i; + break; + +#if UNW_TARGET_ARM + case PT_ARM_EXIDX: + parm_exidx = phdr + i; + break; +#endif + + default: + break; + } + } + + if (!ptxt) + return 0; + + load_base = segbase - ptxt->p_vaddr; + start_ip += load_base; + end_ip += load_base; + + if (peh_hdr) + { + if (pdyn) + { + /* For dynamicly linked executables and shared libraries, + DT_PLTGOT is the value that data-relative addresses are + relative to for that object. We call this the "gp". */ + Elf_W(Dyn) *dyn = (Elf_W(Dyn) *)(pdyn->p_offset + + (char *) edi->ei.image); + for (; dyn->d_tag != DT_NULL; ++dyn) + if (dyn->d_tag == DT_PLTGOT) + { + /* Assume that _DYNAMIC is writable and GLIBC has + relocated it (true for x86 at least). */ + edi->di_cache.gp = dyn->d_un.d_ptr; + break; + } + } + else + /* Otherwise this is a static executable with no _DYNAMIC. Assume + that data-relative addresses are relative to 0, i.e., + absolute. */ + edi->di_cache.gp = 0; + + hdr = (struct dwarf_eh_frame_hdr *) (peh_hdr->p_offset + + (char *) edi->ei.image); + if (hdr->version != DW_EH_VERSION) + { + Debug (1, "table `%s' has unexpected version %d\n", + path, hdr->version); + return -UNW_ENOINFO; + } + + a = unw_get_accessors (unw_local_addr_space); + addr = (unw_word_t) (hdr + 1); + + /* Fill in a dummy proc_info structure. We just need to fill in + enough to ensure that dwarf_read_encoded_pointer() can do it's + job. Since we don't have a procedure-context at this point, all + we have to do is fill in the global-pointer. */ + memset (&pi, 0, sizeof (pi)); + pi.gp = edi->di_cache.gp; + + /* (Optionally) read eh_frame_ptr: */ + if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, + &addr, hdr->eh_frame_ptr_enc, &pi, + &eh_frame_start, NULL)) < 0) + return -UNW_ENOINFO; + + /* (Optionally) read fde_count: */ + if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, + &addr, hdr->fde_count_enc, &pi, + &fde_count, NULL)) < 0) + return -UNW_ENOINFO; + + if (hdr->table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4)) + { + #if 1 + abort (); + #else + unw_word_t eh_frame_end; + + /* If there is no search table or it has an unsupported + encoding, fall back on linear search. */ + if (hdr->table_enc == DW_EH_PE_omit) + Debug (4, "EH lacks search table; doing linear search\n"); + else + Debug (4, "EH table has encoding 0x%x; doing linear search\n", + hdr->table_enc); + + eh_frame_end = max_load_addr; /* XXX can we do better? */ + + if (hdr->fde_count_enc == DW_EH_PE_omit) + fde_count = ~0UL; + if (hdr->eh_frame_ptr_enc == DW_EH_PE_omit) + abort (); + + return linear_search (unw_local_addr_space, ip, + eh_frame_start, eh_frame_end, fde_count, + pi, need_unwind_info, NULL); + #endif + } + + edi->di_cache.start_ip = start_ip; + edi->di_cache.end_ip = end_ip; + edi->di_cache.format = UNW_INFO_FORMAT_REMOTE_TABLE; + edi->di_cache.u.rti.name_ptr = 0; + /* two 32-bit values (ip_offset/fde_offset) per table-entry: */ + edi->di_cache.u.rti.table_len = (fde_count * 8) / sizeof (unw_word_t); + edi->di_cache.u.rti.table_data = ((load_base + peh_hdr->p_vaddr) + + (addr - (unw_word_t) edi->ei.image + - peh_hdr->p_offset)); + + /* For the binary-search table in the eh_frame_hdr, data-relative + means relative to the start of that section... */ + edi->di_cache.u.rti.segbase = ((load_base + peh_hdr->p_vaddr) + + ((unw_word_t) hdr - (unw_word_t) edi->ei.image + - peh_hdr->p_offset)); + found = 1; + } + +#if UNW_TARGET_ARM + if (parm_exidx) + { + edi->di_arm.format = UNW_INFO_FORMAT_ARM_EXIDX; + edi->di_arm.start_ip = start_ip; + edi->di_arm.end_ip = end_ip; + edi->di_arm.u.rti.name_ptr = (unw_word_t) path; + edi->di_arm.u.rti.table_data = load_base + parm_exidx->p_vaddr; + edi->di_arm.u.rti.table_len = parm_exidx->p_memsz; + found = 1; + } +#endif + +#ifdef CONFIG_DEBUG_FRAME + /* Try .debug_frame. */ + found = dwarf_find_debug_frame (found, &edi->edi.di_debug, ip, segbase, path, + start_ip, end_ip); +#endif + + return found; +} + +#endif /* UNW_TARGET_X86 || UNW_TARGET_X86_64 || UNW_TARGET_HPPA*/ diff -d -urpN libunwind.1/src/dwarf/Lfind_unwind_table.c libunwind.2/src/dwarf/Lfind_unwind_table.c --- libunwind.1/src/dwarf/Lfind_unwind_table.c 1970-01-01 01:00:00.000000000 +0100 +++ libunwind.2/src/dwarf/Lfind_unwind_table.c 2012-02-21 17:57:16.863510404 +0100 @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gfind_unwind_table.c" +#endif diff -d -urpN libunwind.1/src/Makefile.am libunwind.2/src/Makefile.am --- libunwind.1/src/Makefile.am 2012-02-13 18:43:50.000000000 +0100 +++ libunwind.2/src/Makefile.am 2012-02-21 17:57:16.863510404 +0100 @@ -109,12 +109,14 @@ libunwind_dwarf_common_la_SOURCES = dwar libunwind_dwarf_local_la_SOURCES = \ dwarf/Lexpr.c dwarf/Lfde.c dwarf/Lparser.c dwarf/Lpe.c dwarf/Lstep.c \ - dwarf/Lfind_proc_info-lsb.c + dwarf/Lfind_proc_info-lsb.c \ + dwarf/Lfind_unwind_table.c libunwind_dwarf_local_la_LIBADD = libunwind-dwarf-common.la libunwind_dwarf_generic_la_SOURCES = \ dwarf/Gexpr.c dwarf/Gfde.c dwarf/Gparser.c dwarf/Gpe.c dwarf/Gstep.c \ - dwarf/Gfind_proc_info-lsb.c + dwarf/Gfind_proc_info-lsb.c \ + dwarf/Gfind_unwind_table.c libunwind_dwarf_generic_la_LIBADD = libunwind-dwarf-common.la if USE_DWARF diff -d -urpN libunwind.1/src/ptrace/_UPT_find_proc_info.c libunwind.2/src/ptrace/_UPT_find_proc_info.c --- libunwind.1/src/ptrace/_UPT_find_proc_info.c 2012-02-21 17:56:38.460568434 +0100 +++ libunwind.2/src/ptrace/_UPT_find_proc_info.c 2012-02-27 16:17:51.478461288 +0100 @@ -32,332 +32,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DE #include "_UPT_internal.h" -#if UNW_TARGET_IA64 - -#include "elf64.h" - -static unw_word_t -find_gp (struct elf_dyn_info *edi, Elf64_Phdr *pdyn, Elf64_Addr load_base) -{ - Elf64_Off soff, str_soff; - Elf64_Ehdr *ehdr = edi->ei.image; - Elf64_Shdr *shdr; - Elf64_Shdr *str_shdr; - Elf64_Addr gp = 0; - char *strtab; - int i; - - if (pdyn) - { - /* If we have a PT_DYNAMIC program header, fetch the gp-value - from the DT_PLTGOT entry. */ - Elf64_Dyn *dyn = (Elf64_Dyn *) (pdyn->p_offset + (char *) edi->ei.image); - for (; dyn->d_tag != DT_NULL; ++dyn) - if (dyn->d_tag == DT_PLTGOT) - { - gp = (Elf64_Addr) dyn->d_un.d_ptr + load_base; - goto done; - } - } - - /* Without a PT_DYAMIC header, lets try to look for a non-empty .opd - section. If there is such a section, we know it's full of - function descriptors, and we can simply pick up the gp from the - second word of the first entry in this table. */ - - soff = ehdr->e_shoff; - str_soff = soff + (ehdr->e_shstrndx * ehdr->e_shentsize); - - if (soff + ehdr->e_shnum * ehdr->e_shentsize > edi->ei.size) - { - Debug (1, "section table outside of image? (%lu > %lu)", - soff + ehdr->e_shnum * ehdr->e_shentsize, - edi->ei.size); - goto done; - } - - shdr = (Elf64_Shdr *) ((char *) edi->ei.image + soff); - str_shdr = (Elf64_Shdr *) ((char *) edi->ei.image + str_soff); - strtab = (char *) edi->ei.image + str_shdr->sh_offset; - for (i = 0; i < ehdr->e_shnum; ++i) - { - if (strcmp (strtab + shdr->sh_name, ".opd") == 0 - && shdr->sh_size >= 16) - { - gp = ((Elf64_Addr *) ((char *) edi->ei.image + shdr->sh_offset))[1]; - goto done; - } - shdr = (Elf64_Shdr *) (((char *) shdr) + ehdr->e_shentsize); - } - - done: - Debug (16, "image at %p, gp = %lx\n", edi->ei.image, gp); - return gp; -} - -HIDDEN int -_UPTi_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, - char *path, unw_word_t segbase, unw_word_t mapoff, - unw_word_t ip) -{ - Elf64_Phdr *phdr, *ptxt = NULL, *punw = NULL, *pdyn = NULL; - Elf64_Ehdr *ehdr; - int i; - - if (!_Uelf64_valid_object (&edi->ei)) - return -UNW_ENOINFO; - - ehdr = edi->ei.image; - phdr = (Elf64_Phdr *) ((char *) edi->ei.image + ehdr->e_phoff); - - for (i = 0; i < ehdr->e_phnum; ++i) - { - switch (phdr[i].p_type) - { - case PT_LOAD: - if (phdr[i].p_offset == mapoff) - ptxt = phdr + i; - break; - - case PT_IA_64_UNWIND: - punw = phdr + i; - break; - - case PT_DYNAMIC: - pdyn = phdr + i; - break; - - default: - break; - } - } - if (!ptxt || !punw) - return 0; - - edi->di_cache.start_ip = segbase; - edi->di_cache.end_ip = edi->di_cache.start_ip + ptxt->p_memsz; - edi->di_cache.gp = find_gp (edi, pdyn, segbase - ptxt->p_vaddr); - edi->di_cache.format = UNW_INFO_FORMAT_TABLE; - edi->di_cache.u.ti.name_ptr = 0; - edi->di_cache.u.ti.segbase = segbase; - edi->di_cache.u.ti.table_len = punw->p_memsz / sizeof (unw_word_t); - edi->di_cache.u.ti.table_data = (unw_word_t *) - ((char *) edi->ei.image + (punw->p_vaddr - ptxt->p_vaddr)); - return 1; -} - -#elif UNW_TARGET_X86 || UNW_TARGET_X86_64 || UNW_TARGET_HPPA \ -|| UNW_TARGET_PPC32 || UNW_TARGET_PPC64 || UNW_TARGET_ARM - -#include "dwarf-eh.h" -#include "dwarf_i.h" - -/* We need our own instance of dwarf_read_encoded_pointer() here since - the one in dwarf/Gpe.c is not (and should not be) exported. */ -int -dwarf_read_encoded_pointer (unw_addr_space_t as, unw_accessors_t *a, - unw_word_t *addr, unsigned char encoding, - const unw_proc_info_t *pi, - unw_word_t *valp, void *arg) -{ - return dwarf_read_encoded_pointer_inlined (as, a, addr, encoding, - pi, valp, arg); -} - -HIDDEN int -_UPTi_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, - char *path, unw_word_t segbase, unw_word_t mapoff, - unw_word_t ip) -{ - Elf_W(Phdr) *phdr, *ptxt = NULL, *peh_hdr = NULL, *pdyn = NULL; - unw_word_t addr, eh_frame_start, fde_count, load_base; - unw_word_t max_load_addr = 0; - unw_word_t start_ip = (unw_word_t) -1; - unw_word_t end_ip = 0; - struct dwarf_eh_frame_hdr *hdr; - unw_proc_info_t pi; - unw_accessors_t *a; - Elf_W(Ehdr) *ehdr; -#if UNW_TARGET_ARM - const Elf_W(Phdr) *parm_exidx = NULL; -#endif - int i, ret, found = 0; - - /* XXX: Much of this code is Linux/LSB-specific. */ - - if (!elf_w(valid_object) (&edi->ei)) - return -UNW_ENOINFO; - - ehdr = edi->ei.image; - phdr = (Elf_W(Phdr) *) ((char *) edi->ei.image + ehdr->e_phoff); - - for (i = 0; i < ehdr->e_phnum; ++i) - { - switch (phdr[i].p_type) - { - case PT_LOAD: - if (phdr[i].p_vaddr < start_ip) - start_ip = phdr[i].p_vaddr; - - if (phdr[i].p_vaddr + phdr[i].p_memsz > end_ip) - end_ip = phdr[i].p_vaddr + phdr[i].p_memsz; - - if (phdr[i].p_offset == mapoff) - ptxt = phdr + i; - if ((uintptr_t) edi->ei.image + phdr->p_filesz > max_load_addr) - max_load_addr = (uintptr_t) edi->ei.image + phdr->p_filesz; - break; - - case PT_GNU_EH_FRAME: - peh_hdr = phdr + i; - break; - - case PT_DYNAMIC: - pdyn = phdr + i; - break; - -#if UNW_TARGET_ARM - case PT_ARM_EXIDX: - parm_exidx = phdr + i; - break; -#endif - - default: - break; - } - } - - if (!ptxt) - return 0; - - load_base = segbase - ptxt->p_vaddr; - start_ip += load_base; - end_ip += load_base; - - if (peh_hdr) - { - if (pdyn) - { - /* For dynamicly linked executables and shared libraries, - DT_PLTGOT is the value that data-relative addresses are - relative to for that object. We call this the "gp". */ - Elf_W(Dyn) *dyn = (Elf_W(Dyn) *)(pdyn->p_offset - + (char *) edi->ei.image); - for (; dyn->d_tag != DT_NULL; ++dyn) - if (dyn->d_tag == DT_PLTGOT) - { - /* Assume that _DYNAMIC is writable and GLIBC has - relocated it (true for x86 at least). */ - edi->di_cache.gp = dyn->d_un.d_ptr; - break; - } - } - else - /* Otherwise this is a static executable with no _DYNAMIC. Assume - that data-relative addresses are relative to 0, i.e., - absolute. */ - edi->di_cache.gp = 0; - - hdr = (struct dwarf_eh_frame_hdr *) (peh_hdr->p_offset - + (char *) edi->ei.image); - if (hdr->version != DW_EH_VERSION) - { - Debug (1, "table `%s' has unexpected version %d\n", - path, hdr->version); - return -UNW_ENOINFO; - } - - a = unw_get_accessors (unw_local_addr_space); - addr = (unw_word_t) (hdr + 1); - - /* Fill in a dummy proc_info structure. We just need to fill in - enough to ensure that dwarf_read_encoded_pointer() can do it's - job. Since we don't have a procedure-context at this point, all - we have to do is fill in the global-pointer. */ - memset (&pi, 0, sizeof (pi)); - pi.gp = edi->di_cache.gp; - - /* (Optionally) read eh_frame_ptr: */ - if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, - &addr, hdr->eh_frame_ptr_enc, &pi, - &eh_frame_start, NULL)) < 0) - return -UNW_ENOINFO; - - /* (Optionally) read fde_count: */ - if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, - &addr, hdr->fde_count_enc, &pi, - &fde_count, NULL)) < 0) - return -UNW_ENOINFO; - - if (hdr->table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4)) - { - #if 1 - abort (); - #else - unw_word_t eh_frame_end; - - /* If there is no search table or it has an unsupported - encoding, fall back on linear search. */ - if (hdr->table_enc == DW_EH_PE_omit) - Debug (4, "EH lacks search table; doing linear search\n"); - else - Debug (4, "EH table has encoding 0x%x; doing linear search\n", - hdr->table_enc); - - eh_frame_end = max_load_addr; /* XXX can we do better? */ - - if (hdr->fde_count_enc == DW_EH_PE_omit) - fde_count = ~0UL; - if (hdr->eh_frame_ptr_enc == DW_EH_PE_omit) - abort (); - - return linear_search (unw_local_addr_space, ip, - eh_frame_start, eh_frame_end, fde_count, - pi, need_unwind_info, NULL); - #endif - } - - edi->di_cache.start_ip = start_ip; - edi->di_cache.end_ip = end_ip; - edi->di_cache.format = UNW_INFO_FORMAT_REMOTE_TABLE; - edi->di_cache.u.rti.name_ptr = 0; - /* two 32-bit values (ip_offset/fde_offset) per table-entry: */ - edi->di_cache.u.rti.table_len = (fde_count * 8) / sizeof (unw_word_t); - edi->di_cache.u.rti.table_data = ((load_base + peh_hdr->p_vaddr) - + (addr - (unw_word_t) edi->ei.image - - peh_hdr->p_offset)); - - /* For the binary-search table in the eh_frame_hdr, data-relative - means relative to the start of that section... */ - edi->di_cache.u.rti.segbase = ((load_base + peh_hdr->p_vaddr) - + ((unw_word_t) hdr - (unw_word_t) edi->ei.image - - peh_hdr->p_offset)); - found = 1; - } - -#if UNW_TARGET_ARM - if (parm_exidx) - { - edi->di_arm.format = UNW_INFO_FORMAT_ARM_EXIDX; - edi->di_arm.start_ip = start_ip; - edi->di_arm.end_ip = end_ip; - edi->di_arm.u.rti.name_ptr = (unw_word_t) path; - edi->di_arm.u.rti.table_data = load_base + parm_exidx->p_vaddr; - edi->di_arm.u.rti.table_len = parm_exidx->p_memsz; - found = 1; - } -#endif - -#ifdef CONFIG_DEBUG_FRAME - /* Try .debug_frame. */ - found = dwarf_find_debug_frame (found, &edi->edi.di_debug, ip, segbase, path, - start_ip, end_ip); -#endif - - return found; -} - -#endif /* UNW_TARGET_X86 || UNW_TARGET_X86_64 || UNW_TARGET_HPPA*/ static int get_unwind_info (struct elf_dyn_info *edi, pid_t pid, unw_addr_space_t as, unw_word_t ip) @@ -391,7 +65,7 @@ get_unwind_info (struct elf_dyn_info *ed /* Here, SEGBASE is the starting-address of the (mmap'ped) segment which covers the IP we're looking for. */ - if (_UPTi_find_unwind_table (edi, as, path, segbase, mapoff, ip) < 0) + if (dwarf_find_unwind_table (edi, as, path, segbase, mapoff, ip) < 0) return -UNW_ENOINFO; /* This can happen in corner cases where dynamically generated diff -d -urpN libunwind.1/src/ptrace/_UPT_get_dyn_info_list_addr.c libunwind.2/src/ptrace/_UPT_get_dyn_info_list_addr.c --- libunwind.1/src/ptrace/_UPT_get_dyn_info_list_addr.c 2012-02-21 17:56:38.461568435 +0100 +++ libunwind.2/src/ptrace/_UPT_get_dyn_info_list_addr.c 2012-02-27 16:18:27.494629027 +0100 @@ -54,7 +54,7 @@ get_list_addr (unw_addr_space_t as, unw_ Debug (16, "checking object %s\n", path); - if (_UPTi_find_unwind_table (&ui->edi, as, path, lo, off, 0) > 0) + if (dwarf_find_unwind_table (&ui->edi, as, path, lo, off, 0) > 0) { res = _Uia64_find_dyn_list (as, &ui->edi.di_cache, arg); if (res && count++ == 0) diff -d -urpN libunwind.1/src/ptrace/_UPT_internal.h libunwind.2/src/ptrace/_UPT_internal.h --- libunwind.1/src/ptrace/_UPT_internal.h 2012-02-21 17:56:38.461568435 +0100 +++ libunwind.2/src/ptrace/_UPT_internal.h 2012-02-21 17:57:16.864510402 +0100 @@ -56,11 +56,4 @@ struct UPT_info extern int _UPT_reg_offset[UNW_REG_LAST + 1]; -extern int _UPTi_find_unwind_table (struct elf_dyn_info *ui, - unw_addr_space_t as, - char *path, - unw_word_t segbase, - unw_word_t mapoff, - unw_word_t ip); - #endif /* _UPT_internal_h */ --------------060801080503000600010903 Content-Type: text/x-patch; name="3.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="3.patch" diff -d -urpN libunwind.2/src/elfxx.c libunwind.3/src/elfxx.c --- libunwind.2/src/elfxx.c 2012-02-13 18:43:50.000000000 +0100 +++ libunwind.3/src/elfxx.c 2012-02-27 15:54:09.738896424 +0100 @@ -127,22 +127,19 @@ elf_w (lookup_symbol) (unw_addr_space_t sensitive to the performance of this routine, why bother... */ HIDDEN int -elf_w (get_proc_name) (unw_addr_space_t as, pid_t pid, unw_word_t ip, +elf_w (get_proc_name_in_image) (unw_addr_space_t as, struct elf_image *ei, + unsigned long segbase, + unsigned long mapoff, + unw_word_t ip, char *buf, size_t buf_len, unw_word_t *offp) { - unsigned long segbase, mapoff; Elf_W (Addr) load_offset = 0; - struct elf_image ei; Elf_W (Ehdr) *ehdr; Elf_W (Phdr) *phdr; int i, ret; - ret = tdep_get_elf_image (&ei, pid, ip, &segbase, &mapoff, NULL, 0); - if (ret < 0) - return ret; - - ehdr = ei.image; - phdr = (Elf_W (Phdr) *) ((char *) ei.image + ehdr->e_phoff); + ehdr = ei->image; + phdr = (Elf_W (Phdr) *) ((char *) ei->image + ehdr->e_phoff); for (i = 0; i < ehdr->e_phnum; ++i) if (phdr[i].p_type == PT_LOAD && phdr[i].p_offset == mapoff) @@ -151,7 +148,24 @@ elf_w (get_proc_name) (unw_addr_space_t break; } - ret = elf_w (lookup_symbol) (as, ip, &ei, load_offset, buf, buf_len, offp); + ret = elf_w (lookup_symbol) (as, ip, ei, load_offset, buf, buf_len, offp); + + return ret; +} + +HIDDEN int +elf_w (get_proc_name) (unw_addr_space_t as, pid_t pid, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp) +{ + unsigned long segbase, mapoff; + struct elf_image ei; + int ret; + + ret = tdep_get_elf_image (&ei, pid, ip, &segbase, &mapoff, NULL, 0); + if (ret < 0) + return ret; + + ret = elf_w (get_proc_name_in_image) (as, &ei, segbase, mapoff, ip, buf, buf_len, offp); munmap (ei.image, ei.size); ei.image = NULL; diff -d -urpN libunwind.2/src/elfxx.h libunwind.3/src/elfxx.h --- libunwind.2/src/elfxx.h 2012-02-13 18:43:50.000000000 +0100 +++ libunwind.3/src/elfxx.h 2012-02-27 15:54:09.738896424 +0100 @@ -48,6 +48,18 @@ extern int elf_w (get_proc_name) (unw_ad char *buf, size_t len, unw_word_t *offp); +extern int elf_w (get_proc_name_in_image) (unw_addr_space_t as, + struct elf_image *ei, + unsigned long segbase, + unsigned long mapoff, + unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp); + +extern int elf_w (get_proc_name) (unw_addr_space_t as, + pid_t pid, unw_word_t ip, + char *buf, size_t len, + unw_word_t *offp); + static inline int elf_w (valid_object) (struct elf_image *ei) { --------------060801080503000600010903 Content-Type: text/x-patch; name="4.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="4.patch" diff -d -urpN libunwind.3/configure.in libunwind.4/configure.in --- libunwind.3/configure.in 2012-02-13 18:43:50.000000000 +0100 +++ libunwind.4/configure.in 2012-02-21 17:58:31.210417230 +0100 @@ -44,6 +44,7 @@ AC_C_CONST AC_C_INLINE AC_TYPE_SIGNAL AC_TYPE_SIZE_T +AC_CHECK_SIZEOF(off_t) CPPFLAGS="${CPPFLAGS} -D_GNU_SOURCE" diff -d -urpN libunwind.3/include/libunwind-coredump.h libunwind.4/include/libunwind-coredump.h --- libunwind.3/include/libunwind-coredump.h 1970-01-01 01:00:00.000000000 +0100 +++ libunwind.4/include/libunwind-coredump.h 2012-02-24 13:42:00.600687887 +0100 @@ -0,0 +1,69 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef libunwind_coredump_h +#define libunwind_coredump_h + +#include + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* Helper routines which make it easy to use libunwind on a coredump. + They're available only if UNW_REMOTE_ONLY is _not_ defined and they + aren't really part of the libunwind API. They are implemented in a + archive library called libunwind-coredump.a. */ + +struct UCD_info; + +extern struct UCD_info *_UCD_create(const char *filename); +extern void _UCD_destroy(struct UCD_info *); + +extern int _UCD_add_backing_file_at_segment(struct UCD_info *, int phdr_no, const char *filename); +extern int _UCD_add_backing_file_at_vaddr(struct UCD_info *, + unsigned long vaddr, + const char *filename); + +extern int _UCD_find_proc_info (unw_addr_space_t, unw_word_t, + unw_proc_info_t *, int, void *); +extern void _UCD_put_unwind_info (unw_addr_space_t, unw_proc_info_t *, void *); +extern int _UCD_get_dyn_info_list_addr (unw_addr_space_t, unw_word_t *, + void *); +extern int _UCD_access_mem (unw_addr_space_t, unw_word_t, unw_word_t *, int, + void *); +extern int _UCD_access_reg (unw_addr_space_t, unw_regnum_t, unw_word_t *, + int, void *); +extern int _UCD_access_fpreg (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, + int, void *); +extern int _UCD_get_proc_name (unw_addr_space_t, unw_word_t, char *, size_t, + unw_word_t *, void *); +extern int _UCD_resume (unw_addr_space_t, unw_cursor_t *, void *); +extern unw_accessors_t _UCD_accessors; + + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* libunwind_coredump_h */ diff -d -urpN libunwind.3/Makefile.am libunwind.4/Makefile.am --- libunwind.3/Makefile.am 2012-02-13 18:43:50.000000000 +0100 +++ libunwind.4/Makefile.am 2012-02-21 17:58:31.210417230 +0100 @@ -1,4 +1,6 @@ -include_HEADERS = include/libunwind-dynamic.h include/libunwind-ptrace.h +include_HEADERS = include/libunwind-dynamic.h \ + include/libunwind-ptrace.h \ + include/libunwind-coredump.h if ARCH_ARM include_HEADERS += include/libunwind-arm.h diff -d -urpN libunwind.3/src/coredump/example-core-unwind.c libunwind.4/src/coredump/example-core-unwind.c --- libunwind.3/src/coredump/example-core-unwind.c 1970-01-01 01:00:00.000000000 +0100 +++ libunwind.4/src/coredump/example-core-unwind.c 2012-02-27 16:02:42.378292779 +0100 @@ -0,0 +1,315 @@ +/* + * Example program for unwinding core dumps. + * + * Compile a-la: + * gcc -Os -Wall \ + * -Wl,--start-group \ + * -lunwind -lunwind-x86 -lunwind-coredump \ + * example-core-unwind.c \ + * -Wl,--end-group \ + * -oexample-core-unwind + * + * Run: + * objdump -sx COREDUMP + * eu-unstrip -n --core COREDUMP + * figure out which segments in COREDUMP correspond to which mapped executable files + * (binary and libraries), then supply them like this: + * ./example-core-unwind COREDUMP 3:/bin/crashed_program 6:/lib/libc.so.6 [...] + */ + +#undef _GNU_SOURCE +#define _GNU_SOURCE 1 +#undef __USE_GNU +#define __USE_GNU 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* For SIGSEGV handler code */ +#include +#include + +#include + + +/* Utility logging functions */ + +enum { + LOGMODE_NONE = 0, + LOGMODE_STDIO = (1 << 0), + LOGMODE_SYSLOG = (1 << 1), + LOGMODE_BOTH = LOGMODE_SYSLOG + LOGMODE_STDIO, +}; +const char *msg_prefix = ""; +const char *msg_eol = "\n"; +int logmode = LOGMODE_STDIO; +int xfunc_error_retval = EXIT_FAILURE; + +void xfunc_die(void) +{ + exit(xfunc_error_retval); +} + +static void verror_msg_helper(const char *s, + va_list p, + const char* strerr, + int flags) +{ + char *msg; + int prefix_len, strerr_len, msgeol_len, used; + + if (!logmode) + return; + + used = vasprintf(&msg, s, p); + if (used < 0) + return; + + /* This is ugly and costs +60 bytes compared to multiple + * fprintf's, but is guaranteed to do a single write. + * This is needed for e.g. when multiple children + * can produce log messages simultaneously. */ + + prefix_len = msg_prefix[0] ? strlen(msg_prefix) + 2 : 0; + strerr_len = strerr ? strlen(strerr) : 0; + msgeol_len = strlen(msg_eol); + /* +3 is for ": " before strerr and for terminating NUL */ + char *msg1 = (char*) realloc(msg, prefix_len + used + strerr_len + msgeol_len + 3); + if (!msg1) + { + free(msg); + return; + } + msg = msg1; + /* TODO: maybe use writev instead of memmoving? Need full_writev? */ + if (prefix_len) + { + char *p; + memmove(msg + prefix_len, msg, used); + used += prefix_len; + p = stpcpy(msg, msg_prefix); + p[0] = ':'; + p[1] = ' '; + } + if (strerr) + { + if (s[0]) + { + msg[used++] = ':'; + msg[used++] = ' '; + } + strcpy(&msg[used], strerr); + used += strerr_len; + } + strcpy(&msg[used], msg_eol); + + if (flags & LOGMODE_STDIO) + { + fflush(stdout); + write(STDERR_FILENO, msg, used + msgeol_len); + } + msg[used] = '\0'; /* remove msg_eol (usually "\n") */ + if (flags & LOGMODE_SYSLOG) + { + syslog(LOG_ERR, "%s", msg + prefix_len); + } + free(msg); +} + +void log_msg(const char *s, ...) +{ + va_list p; + va_start(p, s); + verror_msg_helper(s, p, NULL, logmode); + va_end(p); +} +/* It's a macro, not function, since it collides with log() from math.h */ +#undef log +#define log(...) log_msg(__VA_ARGS__) + +void error_msg(const char *s, ...) +{ + va_list p; + va_start(p, s); + verror_msg_helper(s, p, NULL, logmode); + va_end(p); +} + +void error_msg_and_die(const char *s, ...) +{ + va_list p; + va_start(p, s); + verror_msg_helper(s, p, NULL, logmode); + va_end(p); + xfunc_die(); +} + +void perror_msg(const char *s, ...) +{ + va_list p; + va_start(p, s); + /* Guard against ": Success" */ + verror_msg_helper(s, p, errno ? strerror(errno) : NULL, logmode); + va_end(p); +} + +void perror_msg_and_die(const char *s, ...) +{ + va_list p; + va_start(p, s); + /* Guard against ": Success" */ + verror_msg_helper(s, p, errno ? strerror(errno) : NULL, logmode); + va_end(p); + xfunc_die(); +} + +void die_out_of_memory(void) +{ + error_msg_and_die("Out of memory, exiting"); +} + +/* End of utility logging functions */ + + + +static +void handle_sigsegv(int sig, siginfo_t *info, void *ucontext) +{ + long ip; + ucontext_t *uc; + + uc = ucontext; + ip = uc->uc_mcontext.gregs[REG_EIP]; + dprintf(2, "signal:%d address:0x%lx ip:0x%lx\n", + sig, + /* this is void*, but using %p would print "(null)" + * even for ptrs which are not exactly 0, but, say, 0x123: + */ + (long)info->si_addr, + ip); + + { + /* glibc extension */ + void *array[50]; + int size; + size = backtrace(array, 50); + backtrace_symbols_fd(array, size, 2); + } + + _exit(1); +} + +static void install_sigsegv_handler(void) +{ + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = handle_sigsegv; + sa.sa_flags = SA_SIGINFO; + sigaction(SIGSEGV, &sa, NULL); + sigaction(SIGILL, &sa, NULL); + sigaction(SIGFPE, &sa, NULL); + sigaction(SIGBUS, &sa, NULL); +} + +int +main(int argc, char **argv) +{ + unw_addr_space_t as; + struct UCD_info *ui; + unw_cursor_t c; + int ret; + + install_sigsegv_handler(); + + const char *progname = strrchr(argv[0], '/'); + if (progname) + progname++; + else + progname = argv[0]; + + if (!argv[1]) + error_msg_and_die("Usage: %s COREDUMP [SEGMENT_NO:BINARY_FILE]...", progname); + + msg_prefix = progname; + + as = unw_create_addr_space(&_UCD_accessors, 0); + if (!as) + error_msg_and_die("unw_create_addr_space() failed"); + + ui = _UCD_create(argv[1]); + if (!ui) + error_msg_and_die("_UCD_create('%s') failed", argv[1]); + ret = unw_init_remote(&c, as, ui); + if (ret < 0) + error_msg_and_die("unw_init_remote() failed: ret=%d\n", ret); + + argv += 2; + while (*argv) + { + char *colon = strchr(*argv, ':'); + if (!colon) + error_msg_and_die("Bad format: '%s'", *argv); + *colon = '\0'; + unsigned n = atoi(*argv); + *colon = ':'; + if (_UCD_add_backing_file_at_segment(ui, n, colon + 1) < 0) + error_msg_and_die("Can't add backing file '%s'", *argv); + argv++; + } + + for (;;) + { + unw_word_t ip; + ret = unw_get_reg(&c, UNW_REG_IP, &ip); + if (ret < 0) + error_msg_and_die("unw_get_reg(UNW_REG_IP) failed: ret=%d\n", ret); + + unw_proc_info_t pi; + ret = unw_get_proc_info(&c, &pi); + if (ret < 0) + error_msg_and_die("unw_get_proc_info(ip=0x%lx) failed: ret=%d\n", (long) ip, ret); + printf("\tip=0x%08lx proc=%08lx-%08lx handler=0x%08lx lsda=0x%08lx\n", + (long) ip, + (long) pi.start_ip, (long) pi.end_ip, + (long) pi.handler, (long) pi.lsda); + + log("step"); + ret = unw_step(&c); + log("step done:%d", ret); + if (ret < 0) + error_msg_and_die("FAILURE: unw_step() returned %d", ret); + if (ret == 0) + break; + } + log("stepping ended"); + + _UCD_destroy(ui); + + return 0; +} diff -d -urpN libunwind.3/src/coredump/README libunwind.4/src/coredump/README --- libunwind.3/src/coredump/README 1970-01-01 01:00:00.000000000 +0100 +++ libunwind.4/src/coredump/README 2012-02-21 17:58:31.211417235 +0100 @@ -0,0 +1,8 @@ +This code is based on "unwinding via ptrace" code from ptrace/ +directory. + +Files with names starting with _UCD_ are substantially changed +from their ptrace/_UPT_... progenitors. + +Files which still have _UPT_... names are either verbiatim copies +from ptrace/, or unimplemented stubs. diff -d -urpN libunwind.3/src/coredump/_UCD_access_mem.c libunwind.4/src/coredump/_UCD_access_mem.c --- libunwind.3/src/coredump/_UCD_access_mem.c 1970-01-01 01:00:00.000000000 +0100 +++ libunwind.4/src/coredump/_UCD_access_mem.c 2012-02-21 18:03:23.400383339 +0100 @@ -0,0 +1,102 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +int +_UCD_access_mem(unw_addr_space_t as, unw_word_t addr, unw_word_t *val, + int write, void *arg) +{ + if (write) + { + Debug(0, "%s: write is not supported\n", __func__); + return -UNW_EINVAL; + } + + struct UCD_info *ui = arg; + + unw_word_t addr_last = addr + sizeof(*val)-1; + coredump_phdr_t *phdr; + unsigned i; + for (i = 0; i < ui->phdrs_count; i++) + { + phdr = &ui->phdrs[i]; + if (phdr->p_vaddr <= addr && addr_last < phdr->p_vaddr + phdr->p_memsz) + { + goto found; + } + } + Debug(1, "%s: addr 0x%llx is unmapped\n", + __func__, (unsigned long long)addr + ); + return -UNW_EINVAL; + + found: ; + + const char *filename; + off_t fileofs; + int fd; + if (addr_last >= phdr->p_vaddr + phdr->p_filesz) + { + /* This part of mapped address space is not present in coredump file */ + /* Do we have it in the backup file? */ + if (phdr->backing_fd < 0) + { + Debug(1, "%s: access to not-present data in phdr[%d]: addr:0x%llx\n", + __func__, i, (unsigned long long)addr + ); + return -UNW_EINVAL; + } + filename = phdr->backing_filename; + fileofs = addr - phdr->p_vaddr; + fd = phdr->backing_fd; + goto read; + } + + filename = ui->coredump_filename; + fileofs = phdr->p_offset + (addr - phdr->p_vaddr); + fd = ui->coredump_fd; + read: + if (lseek(fd, fileofs, SEEK_SET) != fileofs) + goto read_error; + if (read(fd, val, sizeof(*val)) != sizeof(*val)) + goto read_error; + + Debug(1, "%s: 0x%llx <- [addr:0x%llx fileofs:0x%llx]\n", + __func__, + (unsigned long long)(*val), + (unsigned long long)addr, + (unsigned long long)fileofs + ); + return 0; + + read_error: + Debug(1, "%s: access out of file: addr:0x%llx fileofs:%llx file:'%s'\n", + __func__, + (unsigned long long)addr, + (unsigned long long)fileofs, + filename + ); + return -UNW_EINVAL; +} diff -d -urpN libunwind.3/src/coredump/_UCD_accessors.c libunwind.4/src/coredump/_UCD_accessors.c --- libunwind.3/src/coredump/_UCD_accessors.c 1970-01-01 01:00:00.000000000 +0100 +++ libunwind.4/src/coredump/_UCD_accessors.c 2012-02-21 18:03:23.400383339 +0100 @@ -0,0 +1,36 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_internal.h" + +PROTECTED unw_accessors_t _UCD_accessors = + { + .find_proc_info = _UCD_find_proc_info, + .put_unwind_info = _UCD_put_unwind_info, + .get_dyn_info_list_addr = _UCD_get_dyn_info_list_addr, + .access_mem = _UCD_access_mem, + .access_reg = _UCD_access_reg, + .access_fpreg = _UCD_access_fpreg, + .resume = _UCD_resume, + .get_proc_name = _UCD_get_proc_name + }; diff -d -urpN libunwind.3/src/coredump/_UCD_access_reg.c libunwind.4/src/coredump/_UCD_access_reg.c --- libunwind.3/src/coredump/_UCD_access_reg.c 1970-01-01 01:00:00.000000000 +0100 +++ libunwind.4/src/coredump/_UCD_access_reg.c 2012-02-27 16:09:34.019069575 +0100 @@ -0,0 +1,92 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_lib.h" + +#include "_UCD_internal.h" + +int +_UCD_access_reg (unw_addr_space_t as, + unw_regnum_t regnum, unw_word_t *valp, + int write, void *arg) +{ + if (write) + { + Debug(0, "%s: write is not supported\n", __func__); + return -UNW_EINVAL; + } + +#if defined(UNW_TARGET_X86) + static const uint8_t remap_regs[] = + { + /* names from libunwind-x86.h */ + [UNW_X86_EAX] = offsetof(struct user_regs_struct, eax) / sizeof(long), + [UNW_X86_EDX] = offsetof(struct user_regs_struct, edx) / sizeof(long), + [UNW_X86_ECX] = offsetof(struct user_regs_struct, ecx) / sizeof(long), + [UNW_X86_EBX] = offsetof(struct user_regs_struct, ebx) / sizeof(long), + [UNW_X86_ESI] = offsetof(struct user_regs_struct, esi) / sizeof(long), + [UNW_X86_EDI] = offsetof(struct user_regs_struct, edi) / sizeof(long), + [UNW_X86_EBP] = offsetof(struct user_regs_struct, ebp) / sizeof(long), + [UNW_X86_ESP] = offsetof(struct user_regs_struct, esp) / sizeof(long), + [UNW_X86_EIP] = offsetof(struct user_regs_struct, eip) / sizeof(long), + [UNW_X86_EFLAGS] = offsetof(struct user_regs_struct, eflags) / sizeof(long), + [UNW_X86_TRAPNO] = offsetof(struct user_regs_struct, orig_eax) / sizeof(long), + }; +#elif defined(UNW_TARGET_X86_64) + static const int8_t remap_regs[] = + { + [UNW_X86_RAX] = offsetof(struct user_regs_struct, rax) / sizeof(long), + [UNW_X86_RDX] = offsetof(struct user_regs_struct, rdx) / sizeof(long), + [UNW_X86_RCX] = offsetof(struct user_regs_struct, rcx) / sizeof(long), + [UNW_X86_RBX] = offsetof(struct user_regs_struct, rbx) / sizeof(long), + [UNW_X86_RSI] = offsetof(struct user_regs_struct, rsi) / sizeof(long), + [UNW_X86_RDI] = offsetof(struct user_regs_struct, rdi) / sizeof(long), + [UNW_X86_RBP] = offsetof(struct user_regs_struct, rbp) / sizeof(long), + [UNW_X86_RSP] = offsetof(struct user_regs_struct, rsp) / sizeof(long), + [UNW_X86_RIP] = offsetof(struct user_regs_struct, rip) / sizeof(long), + [UNW_X86_RFLAGS] = offsetof(struct user_regs_struct, rflags) / sizeof(long), + [UNW_X86_TRAPNO] = offsetof(struct user_regs_struct, orig_rax) / sizeof(long), + }; +#else +#error Port me +#endif + + struct UCD_info *ui = arg; + if (regnum < 0 || regnum >= (unw_regnum_t)ARRAY_SIZE(remap_regs)) + { + Debug(0, "%s: bad regnum:%d\n", __func__, regnum); + return -UNW_EINVAL; + } + regnum = remap_regs[regnum]; + + /* pr_reg is a long[] array, but it contains struct user_regs_struct's + * image. + */ + Debug(1 "pr_reg[%d]:%ld (0x%lx)", regnum, + (long)ui->prstatus->pr_reg[regnum], + (long)ui->prstatus->pr_reg[regnum] + ); + *valp = ui->prstatus->pr_reg[regnum]; + + return 0; +} diff -d -urpN libunwind.3/src/coredump/_UCD_create.c libunwind.4/src/coredump/_UCD_create.c --- libunwind.3/src/coredump/_UCD_create.c 1970-01-01 01:00:00.000000000 +0100 +++ libunwind.4/src/coredump/_UCD_create.c 2012-02-24 13:42:48.009640340 +0100 @@ -0,0 +1,379 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* Endian detection */ +#include +#include +#include +#if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN +# define WE_ARE_BIG_ENDIAN 1 +# define WE_ARE_LITTLE_ENDIAN 0 +#elif defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN +# define WE_ARE_BIG_ENDIAN 0 +# define WE_ARE_LITTLE_ENDIAN 1 +#elif defined(_BYTE_ORDER) && _BYTE_ORDER == _BIG_ENDIAN +# define WE_ARE_BIG_ENDIAN 1 +# define WE_ARE_LITTLE_ENDIAN 0 +#elif defined(_BYTE_ORDER) && _BYTE_ORDER == _LITTLE_ENDIAN +# define WE_ARE_BIG_ENDIAN 0 +# define WE_ARE_LITTLE_ENDIAN 1 +#elif defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN +# define WE_ARE_BIG_ENDIAN 1 +# define WE_ARE_LITTLE_ENDIAN 0 +#elif defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN +# define WE_ARE_BIG_ENDIAN 0 +# define WE_ARE_LITTLE_ENDIAN 1 +#elif defined(__386__) +# define WE_ARE_BIG_ENDIAN 0 +# define WE_ARE_LITTLE_ENDIAN 1 +#else +# error "Can't determine endianness" +#endif + +#include +#include /* struct elf_prstatus */ + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +struct UCD_info * +_UCD_create(const char *filename) +{ + union + { + Elf32_Ehdr h32; + Elf64_Ehdr h64; + } elf_header; +#define elf_header32 elf_header.h32 +#define elf_header64 elf_header.h64 + bool _64bits; + + struct UCD_info *ui = memset(malloc(sizeof(*ui)), 0, sizeof(*ui)); + ui->edi.di_cache.format = -1; + ui->edi.di_debug.format = -1; +#if UNW_TARGET_IA64 + ui->edi.ktab.format = -1; +#endif + + int fd = ui->coredump_fd = open(filename, O_RDONLY); + if (fd < 0) + goto err; + ui->coredump_filename = strdup(filename); + + /* No sane ELF32 file is going to be smaller then ELF64 _header_, + * so let's just read 64-bit sized one. + */ + if (read(fd, &elf_header64, sizeof(elf_header64)) != sizeof(elf_header64)) + { + Debug(0, "'%s' is not an ELF file\n", filename); + goto err; + } + + if (memcmp(&elf_header32, "\x7f""ELF", 4) != 0) + { + Debug(0, "'%s' is not an ELF file\n", filename); + goto err; + } + + if (elf_header32.e_ident[EI_CLASS] != ELFCLASS32 + && elf_header32.e_ident[EI_CLASS] != ELFCLASS64) + { + Debug(0, "'%s' is not a 32/64 bit ELF file\n", filename); + goto err; + } + + if (WE_ARE_LITTLE_ENDIAN != (elf_header32.e_ident[EI_DATA] == ELFDATA2LSB)) + { + Debug(0, "'%s' is endian-incompatible\n", filename); + goto err; + } + + _64bits = (elf_header32.e_ident[EI_CLASS] == ELFCLASS64); + if (_64bits && sizeof(elf_header64.e_entry) > sizeof(off_t)) + { + Debug(0, "Can't process '%s': 64-bit file " + "while only %d bits are supported", + filename, 8 * sizeof(off_t)); + goto err; + } + + /* paranoia check */ + if (_64bits + ? 0 /* todo: (elf_header64.e_ehsize != NN || elf_header64.e_phentsize != NN) */ + : (elf_header32.e_ehsize != 52 || elf_header32.e_phentsize != 32) + ) + { + Debug(0, "'%s' has wrong e_ehsize or e_phentsize\n", filename); + goto err; + } + + off_t ofs = (_64bits ? elf_header64.e_phoff : elf_header32.e_phoff); + if (lseek(fd, ofs, SEEK_SET) != ofs) + { + Debug(0, "Can't read phdrs from '%s'\n", filename); + goto err; + } + unsigned size = ui->phdrs_count = (_64bits ? elf_header64.e_phnum : elf_header32.e_phnum); + coredump_phdr_t *phdrs = ui->phdrs = memset(malloc(size * sizeof(phdrs[0])), 0, size * sizeof(phdrs[0])); + if (_64bits) + { + coredump_phdr_t *cur = phdrs; + unsigned i = 0; + while (i < size) + { + Elf64_Phdr hdr64; + if (read(fd, &hdr64, sizeof(hdr64)) != sizeof(hdr64)) + { + Debug(0, "Can't read phdrs from '%s'\n", filename); + goto err; + } + cur->p_type = hdr64.p_type ; + cur->p_flags = hdr64.p_flags ; + cur->p_offset = hdr64.p_offset; + cur->p_vaddr = hdr64.p_vaddr ; + /*cur->p_paddr = hdr32.p_paddr ; always 0 */ +//TODO: check that and abort if it isn't? + cur->p_filesz = hdr64.p_filesz; + cur->p_memsz = hdr64.p_memsz ; + cur->p_align = hdr64.p_align ; + /* cur->backing_filename = NULL; - done by memset */ + cur->backing_fd = -1; + cur->backing_filesize = hdr64.p_filesz; + i++; + cur++; + } + } else { + coredump_phdr_t *cur = phdrs; + unsigned i = 0; + while (i < size) + { + Elf32_Phdr hdr32; + if (read(fd, &hdr32, sizeof(hdr32)) != sizeof(hdr32)) + { + Debug(0, "Can't read phdrs from '%s'\n", filename); + goto err; + } + cur->p_type = hdr32.p_type ; + cur->p_flags = hdr32.p_flags ; + cur->p_offset = hdr32.p_offset; + cur->p_vaddr = hdr32.p_vaddr ; + /*cur->p_paddr = hdr32.p_paddr ; always 0 */ + cur->p_filesz = hdr32.p_filesz; + cur->p_memsz = hdr32.p_memsz ; + cur->p_align = hdr32.p_align ; + /* cur->backing_filename = NULL; - done by memset */ + cur->backing_fd = -1; + cur->backing_filesize = hdr32.p_memsz; + i++; + cur++; + } + } + + unsigned i = 0; + coredump_phdr_t *cur = phdrs; + while (i < size) + { + Debug(2, "phdr[%03d]: type:%d", i, cur->p_type); + if (cur->p_type == PT_NOTE) + { + ui->note_phdr = malloc(cur->p_filesz); + if (lseek(fd, cur->p_offset, SEEK_SET) != (off_t)cur->p_offset + || (uoff_t)read(fd, ui->note_phdr, cur->p_filesz) != cur->p_filesz + ) + { + Debug(0, "Can't read PT_NOTE from '%s'\n", filename); + goto err; + } + + /* Note is three 32-bit words: */ + /* Elf32_Word n_namesz; Length of the note's name */ + /* Elf32_Word n_descsz; Length of the note's descriptor */ + /* Elf32_Word n_type; Type */ + /* followed by name (padded to 32 bits(?)) and then descr */ + Elf32_Nhdr *note_hdr = ui->note_phdr; + if (cur->p_filesz >= 3*4 + && note_hdr->n_type == NT_PRSTATUS + && cur->p_filesz >= (3*4 + note_hdr->n_namesz + note_hdr->n_descsz + sizeof(*ui->prstatus)) + ) + { + ui->prstatus = (void*) ((((long)note_hdr + sizeof(*note_hdr) + note_hdr->n_namesz) + 3) & ~3L); +#if 0 + printf("pid:%d\n", ui->prstatus->pr_pid); + printf("ebx:%ld\n", (long)ui->prstatus->pr_reg[0]); + printf("ecx:%ld\n", (long)ui->prstatus->pr_reg[1]); + printf("edx:%ld\n", (long)ui->prstatus->pr_reg[2]); + printf("esi:%ld\n", (long)ui->prstatus->pr_reg[3]); + printf("edi:%ld\n", (long)ui->prstatus->pr_reg[4]); + printf("ebp:%ld\n", (long)ui->prstatus->pr_reg[5]); + printf("eax:%ld\n", (long)ui->prstatus->pr_reg[6]); + printf("xds:%ld\n", (long)ui->prstatus->pr_reg[7]); + printf("xes:%ld\n", (long)ui->prstatus->pr_reg[8]); + printf("xfs:%ld\n", (long)ui->prstatus->pr_reg[9]); + printf("xgs:%ld\n", (long)ui->prstatus->pr_reg[10]); + printf("orig_eax:%ld\n", (long)ui->prstatus->pr_reg[11]); +#endif + } + } + if (cur->p_type == PT_LOAD) + { + Debug(2, " ofs:%08llx va:%08llx filesize:%08llx memsize:%08llx flg:%x", + (unsigned long long) cur->p_offset, + (unsigned long long) cur->p_vaddr, + (unsigned long long) cur->p_filesz, + (unsigned long long) cur->p_memsz, + cur->p_flags + ); + if (cur->p_filesz < cur->p_memsz) + Debug(2, " partial"); + if (cur->p_flags & PF_X) + Debug(2, " executable"); + } + Debug(2, "\n"); + i++; + cur++; + } + + if (!ui->prstatus) + { + Debug(0, "No NT_PRSTATUS note found in '%s'\n", filename); + goto err; + } + + return ui; + + err: + _UCD_destroy(ui); + return NULL; +} + +int _UCD_add_backing_file_at_segment(struct UCD_info *ui, int phdr_no, const char *filename) +{ + if ((unsigned)phdr_no >= ui->phdrs_count) + { + Debug(0, "There is no segment %d in this coredump\n", phdr_no); + return -1; + } + + struct coredump_phdr *phdr = &ui->phdrs[phdr_no]; + if (phdr->backing_filename) + { + Debug(0, "Backing file already added to segment %d\n", phdr_no); + return -1; + } + + int fd = open(filename, O_RDONLY); + if (fd < 0) + { + Debug(0, "Can't open '%s'\n", filename); + return -1; + } + + phdr->backing_fd = fd; + phdr->backing_filename = strdup(filename); + + struct stat statbuf; + if (fstat(fd, &statbuf) != 0) + { + Debug(0, "Can't stat '%s'\n", filename); + goto err; + } + phdr->backing_filesize = (uoff_t)statbuf.st_size; + + if (phdr->p_flags != (PF_X | PF_R)) + Debug(1, "Note: phdr[%u] is not r-x: flags are 0x%x\n", phdr_no, phdr->p_flags); + + if (phdr->backing_filesize > phdr->p_memsz) + { + /* This is expected */ + Debug(2, "Note: phdr[%u] is %lld bytes, file is larger: %lld bytes\n", + phdr_no, + (unsigned long long)phdr->p_memsz, + (unsigned long long)phdr->backing_filesize + ); + } +//TODO: else loudly complain? Maybe even fail? + + if (phdr->p_filesz != 0) + { +//TODO: loop and compare in smaller blocks + char *core_buf = malloc(phdr->p_filesz); + char *file_buf = malloc(phdr->p_filesz); + if (lseek(ui->coredump_fd, phdr->p_offset, SEEK_SET) != (off_t)phdr->p_offset + || (uoff_t)read(ui->coredump_fd, core_buf, phdr->p_filesz) != phdr->p_filesz + ) + { + Debug(0, "Error reading from coredump file\n"); + err_read: + free(core_buf); + free(file_buf); + goto err; + } + if ((uoff_t)read(fd, file_buf, phdr->p_filesz) != phdr->p_filesz) + { + Debug(0, "Error reading from '%s'\n", filename); + goto err_read; + } + int r = memcmp(core_buf, file_buf, phdr->p_filesz); + free(core_buf); + free(file_buf); + if (r != 0) + { + Debug(1, "Note: phdr[%u] first %lld bytes in core dump and in file do not match\n", + phdr_no, (unsigned long long)phdr->p_filesz + ); + } else { + Debug(1, "Note: phdr[%u] first %lld bytes in core dump and in file match\n", + phdr_no, (unsigned long long)phdr->p_filesz + ); + } + } + + /* Success */ + return 0; + + err: + if (phdr->backing_fd >= 0) + { + close(phdr->backing_fd); + phdr->backing_fd = -1; + } + free(phdr->backing_filename); + phdr->backing_filename = NULL; + return -1; +} + +int _UCD_add_backing_file_at_vaddr(struct UCD_info *ui, + unsigned long vaddr, + const char *filename) +{ + unsigned i; + for (i = 0; i < ui->phdrs_count; i++) + { + struct coredump_phdr *phdr = &ui->phdrs[i]; + if (phdr->p_vaddr != vaddr) + continue; + /* It seems to match. Add it. */ + return _UCD_add_backing_file_at_segment(ui, i, filename); + } + return -1; +} diff -d -urpN libunwind.3/src/coredump/_UCD_destroy.c libunwind.4/src/coredump/_UCD_destroy.c --- libunwind.3/src/coredump/_UCD_destroy.c 1970-01-01 01:00:00.000000000 +0100 +++ libunwind.4/src/coredump/_UCD_destroy.c 2012-02-21 18:03:23.400383339 +0100 @@ -0,0 +1,50 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_internal.h" + +void +_UCD_destroy (struct UCD_info *ui) +{ + if (!ui) + return; + + if (ui->coredump_fd >= 0) + close(ui->coredump_fd); + free(ui->coredump_filename); + + invalidate_edi (&ui->edi); + + unsigned i; + for (i = 0; i < ui->phdrs_count; i++) + { + struct coredump_phdr *phdr = &ui->phdrs[i]; + free(phdr->backing_filename); + if (phdr->backing_fd >= 0) + close(phdr->backing_fd); + } + + free(ui->note_phdr); + + free(ui); +} diff -d -urpN libunwind.3/src/coredump/_UCD_elf_map_image.c libunwind.4/src/coredump/_UCD_elf_map_image.c --- libunwind.3/src/coredump/_UCD_elf_map_image.c 1970-01-01 01:00:00.000000000 +0100 +++ libunwind.4/src/coredump/_UCD_elf_map_image.c 2012-02-27 15:55:53.833512723 +0100 @@ -0,0 +1,98 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +static coredump_phdr_t * +CD_elf_map_image(struct UCD_info *ui, coredump_phdr_t *phdr) +{ + struct elf_image *ei = &ui->edi.ei; + + if (phdr->backing_fd < 0) + { + /* Note: coredump file contains only phdr->p_filesz bytes. + * We want to map bigger area (phdr->p_memsz bytes) to make sure + * these pages are allocated, but non-accessible. + */ + /* addr, length, prot, flags, fd, fd_offset */ + ei->image = mmap(NULL, phdr->p_memsz, PROT_READ, MAP_PRIVATE, ui->coredump_fd, phdr->p_offset); + if (ei->image == MAP_FAILED) + { + ei->image = NULL; + return NULL; + } + ei->size = phdr->p_filesz; + size_t remainder_len = phdr->p_memsz - phdr->p_filesz; + if (remainder_len > 0) + { + void *remainder_base = (char*) ei->image + phdr->p_filesz; + munmap(remainder_base, remainder_len); + } + } else { + /* We have a backing file for this segment. + * This file is always longer than phdr->p_memsz, + * and if phdr->p_filesz !=0, first phdr->p_filesz bytes in coredump + * are the same as first bytes in the file. (Thus no need to map coredump) + * We map the entire file: + * unwinding may need data which is past phdr->p_memsz bytes. + */ + /* addr, length, prot, flags, fd, fd_offset */ + ei->image = mmap(NULL, phdr->backing_filesize, PROT_READ, MAP_PRIVATE, phdr->backing_fd, 0); + if (ei->image == MAP_FAILED) + { + ei->image = NULL; + return NULL; + } + ei->size = phdr->backing_filesize; + } + + /* Check ELF header for sanity */ + if (!elf_w(valid_object)(ei)) + { + munmap(ei->image, ei->size); + ei->image = NULL; + ei->size = 0; + return NULL; + } + + return phdr; +} + +HIDDEN coredump_phdr_t * +_UCD_get_elf_image(struct UCD_info *ui, unw_word_t ip) +{ + unsigned i; + for (i = 0; i < ui->phdrs_count; i++) + { + coredump_phdr_t *phdr = &ui->phdrs[i]; + if (phdr->p_vaddr <= ip && ip < phdr->p_vaddr + phdr->p_memsz) + { + phdr = CD_elf_map_image(ui, phdr); + return phdr; + } + } + return NULL; +} diff -d -urpN libunwind.3/src/coredump/_UCD_find_proc_info.c libunwind.4/src/coredump/_UCD_find_proc_info.c --- libunwind.3/src/coredump/_UCD_find_proc_info.c 1970-01-01 01:00:00.000000000 +0100 +++ libunwind.4/src/coredump/_UCD_find_proc_info.c 2012-02-27 16:13:24.616856591 +0100 @@ -0,0 +1,163 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +static int +get_unwind_info(struct UCD_info *ui, unw_addr_space_t as, unw_word_t ip) +{ + unsigned long segbase, mapoff; + +#if UNW_TARGET_IA64 && defined(__linux) + if (!ui->edi.ktab.start_ip && _Uia64_get_kernel_table (&ui->edi.ktab) < 0) + return -UNW_ENOINFO; + + if (ui->edi.ktab.format != -1 && ip >= ui->edi.ktab.start_ip && ip < ui->edi.ktab.end_ip) + return 0; +#endif + + if ((ui->edi.di_cache.format != -1 + && ip >= ui->edi.di_cache.start_ip && ip < ui->edi.di_cache.end_ip) +#if UNW_TARGET_ARM + || (ui->edi.di_debug.format != -1 + && ip >= ui->edi.di_arm.start_ip && ip < ui->edi.di_arm.end_ip) +#endif + || (ui->edi.di_debug.format != -1 + && ip >= ui->edi.di_debug.start_ip && ip < ui->edi.di_debug.end_ip)) + return 0; + + invalidate_edi (&ui->edi); + + /* Used to be tdep_get_elf_image() in ptrace unwinding code */ + coredump_phdr_t *phdr = _UCD_get_elf_image(ui, ip); + if (!phdr) + { + Debug(1, "%s returns error: _UCD_get_elf_image failed\n", __func__); + return -UNW_ENOINFO; + } + /* segbase: where it is mapped in virtual memory */ + /* mapoff: offset in the file */ + segbase = phdr->p_vaddr; + /*mapoff = phdr->p_offset; WRONG! phdr->p_offset is the offset in COREDUMP file */ + mapoff = 0; +///FIXME. text segment is USUALLY, not always, at offset 0 in the binary/.so file. +// ensure that at initialization. + + /* Here, SEGBASE is the starting-address of the (mmap'ped) segment + which covers the IP we're looking for. */ + if (dwarf_find_unwind_table(&ui->edi, as, phdr->backing_filename, segbase, mapoff, ip) < 0) + { + Debug(1, "%s returns error: dwarf_find_unwind_table failed\n", __func__); + return -UNW_ENOINFO; + } + + /* This can happen in corner cases where dynamically generated + code falls into the same page that contains the data-segment + and the page-offset of the code is within the first page of + the executable. */ + if (ui->edi.di_cache.format != -1 + && (ip < ui->edi.di_cache.start_ip || ip >= ui->edi.di_cache.end_ip)) + ui->edi.di_cache.format = -1; + + if (ui->edi.di_debug.format != -1 + && (ip < ui->edi.di_debug.start_ip || ip >= ui->edi.di_debug.end_ip)) + ui->edi.di_debug.format = -1; + + if (ui->edi.di_cache.format == -1 +#if UNW_TARGET_ARM + && ui->edi.di_arm.format == -1 +#endif + && ui->edi.di_debug.format == -1) + { + Debug(1, "%s returns error: all formats are -1\n", __func__); + return -UNW_ENOINFO; + } + + Debug(1, "%s returns success\n", __func__); + return 0; +} + +int +_UCD_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, + int need_unwind_info, void *arg) +{ + struct UCD_info *ui = arg; + + Debug(1, "%s: entering\n", __func__); + + int ret = -UNW_ENOINFO; + + if (get_unwind_info(ui, as, ip) < 0) { + Debug(1, "%s returns error: get_unwind_info failed\n", __func__); + return -UNW_ENOINFO; + } + +#if UNW_TARGET_IA64 + if (ui->edi.ktab.format != -1) + { + /* The kernel unwind table resides in local memory, so we have + to use the local address space to search it. Since + _UCD_put_unwind_info() has no easy way of detecting this + case, we simply make a copy of the unwind-info, so + _UCD_put_unwind_info() can always free() the unwind-info + without ill effects. */ + ret = tdep_search_unwind_table (unw_local_addr_space, ip, &ui->edi.ktab, pi, + need_unwind_info, arg); + if (ret >= 0) + { + if (!need_unwind_info) + pi->unwind_info = NULL; + else + { + void *mem = malloc (pi->unwind_info_size); + + if (!mem) + return -UNW_ENOMEM; + memcpy (mem, pi->unwind_info, pi->unwind_info_size); + pi->unwind_info = mem; + } + } + } +#endif + + if (ret == -UNW_ENOINFO && ui->edi.di_cache.format != -1) + ret = tdep_search_unwind_table (as, ip, &ui->edi.di_cache, + pi, need_unwind_info, arg); + +#if UNW_TARGET_ARM + if (ret == -UNW_ENOINFO && ui->edi.di_arm.format != -1) + ret = tdep_search_unwind_table (as, ip, &ui->edi.di_arm, pi, + need_unwind_info, arg); +#endif + + if (ret == -UNW_ENOINFO && ui->edi.di_debug.format != -1) + ret = tdep_search_unwind_table (as, ip, &ui->edi.di_debug, pi, + need_unwind_info, arg); + + Debug(1, "%s: returns %d\n", __func__, ret); + + return ret; +} diff -d -urpN libunwind.3/src/coredump/_UCD_get_proc_name.c libunwind.4/src/coredump/_UCD_get_proc_name.c --- libunwind.3/src/coredump/_UCD_get_proc_name.c 1970-01-01 01:00:00.000000000 +0100 +++ libunwind.4/src/coredump/_UCD_get_proc_name.c 2012-02-27 16:16:11.479074657 +0100 @@ -0,0 +1,70 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + + +/* Find the ELF image that contains IP and return the "closest" + procedure name, if there is one. With some caching, this could be + sped up greatly, but until an application materializes that's + sensitive to the performance of this routine, why bother... */ +static int +elf_w (CD_get_proc_name) (struct UCD_info *ui, unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp) +{ + unsigned long segbase, mapoff; + int ret; + + /* Used to be tdep_get_elf_image() in ptrace unwinding code */ + coredump_phdr_t *cphdr = _UCD_get_elf_image(ui, ip); + if (!cphdr) + { + Debug(1, "%s returns error: _UCD_get_elf_image failed\n", __func__); + return -UNW_ENOINFO; + } + /* segbase: where it is mapped in virtual memory */ + /* mapoff: offset in the file */ + segbase = cphdr->p_vaddr; + /*mapoff = phdr->p_offset; WRONG! phdr->p_offset is the offset in COREDUMP file */ + mapoff = 0; + + ret = elf_w (get_proc_name_in_image) (as, &ui->edi.ei, segbase, mapoff, ip, buf, buf_len, offp); + + return ret; +} + +int +_UCD_get_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, void *arg) +{ + struct UCD_info *ui = arg; + +#if ELF_CLASS == ELFCLASS64 + return _Uelf64_CD_get_proc_name (ui, as, ip, buf, buf_len, offp); +#elif ELF_CLASS == ELFCLASS32 + return _Uelf32_CD_get_proc_name (ui, as, ip, buf, buf_len, offp); +#else + return -UNW_ENOINFO; +#endif +} diff -d -urpN libunwind.3/src/coredump/_UCD_internal.h libunwind.4/src/coredump/_UCD_internal.h --- libunwind.3/src/coredump/_UCD_internal.h 1970-01-01 01:00:00.000000000 +0100 +++ libunwind.4/src/coredump/_UCD_internal.h 2012-02-27 15:55:53.834512730 +0100 @@ -0,0 +1,93 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef _UCD_internal_h +#define _UCD_internal_h + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_PROCFS_H +#include /* struct elf_prstatus */ +#endif +#include +#include +#include +#include +#include + +#include + +#include "libunwind_i.h" + + +#if SIZEOF_OFF_T == 4 +typedef uint32_t uoff_t; +#elif SIZEOF_OFF_T == 8 +typedef uint64_t uoff_t; +#else +# error Unknown size of off_t! +#endif + + +/* Similar to ELF phdrs. p_paddr element is absent, + * since it's always 0 in coredumps. + */ +struct coredump_phdr + { + uint32_t p_type; + uint32_t p_flags; + uoff_t p_offset; + uoff_t p_vaddr; + uoff_t p_filesz; + uoff_t p_memsz; + uoff_t p_align; + /* Data for backing file. If backing_fd < 0, there is no file */ + uoff_t backing_filesize; + char *backing_filename; /* for error meesages only */ + int backing_fd; + }; + +typedef struct coredump_phdr coredump_phdr_t; + + +struct UCD_info + { + int big_endian; /* bool */ + int coredump_fd; + char *coredump_filename; /* for error meesages only */ + coredump_phdr_t *phdrs; /* array, allocated */ + unsigned phdrs_count; + void *note_phdr; /* allocated or NULL */ + struct elf_prstatus *prstatus; /* points inside note_phdr */ + + struct elf_dyn_info edi; + }; + +extern coredump_phdr_t * _UCD_get_elf_image(struct UCD_info *ui, unw_word_t ip); + +#endif diff -d -urpN libunwind.3/src/coredump/_UCD_lib.h libunwind.4/src/coredump/_UCD_lib.h --- libunwind.3/src/coredump/_UCD_lib.h 1970-01-01 01:00:00.000000000 +0100 +++ libunwind.4/src/coredump/_UCD_lib.h 2012-02-21 17:58:41.578456227 +0100 @@ -0,0 +1,53 @@ +/* + Copyright (C) 2010 ABRT team + Copyright (C) 2010 RedHat Inc + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef _UCD_lib_h +#define _UCD_lib_h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff -d -urpN libunwind.3/src/coredump/_UPT_access_fpreg.c libunwind.4/src/coredump/_UPT_access_fpreg.c --- libunwind.3/src/coredump/_UPT_access_fpreg.c 1970-01-01 01:00:00.000000000 +0100 +++ libunwind.4/src/coredump/_UPT_access_fpreg.c 2012-02-21 18:03:23.401383333 +0100 @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +int +_UCD_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + print_error (__func__); + print_error (" not implemented\n"); + return -UNW_EINVAL; +} diff -d -urpN libunwind.3/src/coredump/_UPT_elf.c libunwind.4/src/coredump/_UPT_elf.c --- libunwind.3/src/coredump/_UPT_elf.c 1970-01-01 01:00:00.000000000 +0100 +++ libunwind.4/src/coredump/_UPT_elf.c 2012-02-21 18:17:35.506073389 +0100 @@ -0,0 +1,5 @@ +/* We need to get a separate copy of the ELF-code into + libunwind-coredump since it cannot (and must not) have any ELF + dependencies on libunwind. */ +#include "libunwind_i.h" /* get ELFCLASS defined */ +#include "../elfxx.c" diff -d -urpN libunwind.3/src/coredump/_UPT_get_dyn_info_list_addr.c libunwind.4/src/coredump/_UPT_get_dyn_info_list_addr.c --- libunwind.3/src/coredump/_UPT_get_dyn_info_list_addr.c 1970-01-01 01:00:00.000000000 +0100 +++ libunwind.4/src/coredump/_UPT_get_dyn_info_list_addr.c 2012-02-27 16:13:28.504860367 +0100 @@ -0,0 +1,108 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +#if UNW_TARGET_IA64 && defined(__linux) +# include "elf64.h" +# include "os-linux.h" + +static inline int +get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, + int *countp) +{ + unsigned long lo, hi, off; + struct UPT_info *ui = arg; + struct map_iterator mi; + char path[PATH_MAX]; + unw_dyn_info_t *di; + unw_word_t res; + int count = 0; + + maps_init (&mi, ui->pid); + while (maps_next (&mi, &lo, &hi, &off)) + { + if (off) + continue; + + invalidate_edi (&ui->edi); + + if (elf_map_image (&ui->ei, path) < 0) + /* ignore unmappable stuff like "/SYSV00001b58 (deleted)" */ + continue; + + Debug (16, "checking object %s\n", path); + + di = dwarf_find_unwind_table (&ui->edi, as, path, lo, off); + if (di) + { + res = _Uia64_find_dyn_list (as, di, arg); + if (res && count++ == 0) + { + Debug (12, "dyn_info_list_addr = 0x%lx\n", (long) res); + *dil_addr = res; + } + } + } + maps_close (&mi); + *countp = count; + return 0; +} + +#else + +static inline int +get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, + int *countp) +{ +# warning Implement get_list_addr(), please. + *countp = 0; + return 0; +} + +#endif + +int +_UCD_get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, + void *arg) +{ + int count, ret; + + Debug (12, "looking for dyn_info list\n"); + + if ((ret = get_list_addr (as, dil_addr, arg, &count)) < 0) + return ret; + + /* If multiple dynamic-info list addresses are found, we would have + to determine which was is the one actually in use (since the + dynamic name resolution algorithm will pick one "winner"). + Perhaps we'd have to track them all until we find one that's + non-empty. Hopefully, this case simply will never arise, since + only libunwind defines the dynamic info list head. */ + assert (count <= 1); + + return (count > 0) ? 0 : -UNW_ENOINFO; +} diff -d -urpN libunwind.3/src/coredump/_UPT_put_unwind_info.c libunwind.4/src/coredump/_UPT_put_unwind_info.c --- libunwind.3/src/coredump/_UPT_put_unwind_info.c 1970-01-01 01:00:00.000000000 +0100 +++ libunwind.4/src/coredump/_UPT_put_unwind_info.c 2012-02-21 18:03:23.401383333 +0100 @@ -0,0 +1,36 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +void +_UCD_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg) +{ + if (!pi->unwind_info) + return; + free (pi->unwind_info); + pi->unwind_info = NULL; +} diff -d -urpN libunwind.3/src/coredump/_UPT_resume.c libunwind.4/src/coredump/_UPT_resume.c --- libunwind.3/src/coredump/_UPT_resume.c 1970-01-01 01:00:00.000000000 +0100 +++ libunwind.4/src/coredump/_UPT_resume.c 2012-02-21 18:03:23.401383333 +0100 @@ -0,0 +1,35 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +int +_UCD_resume (unw_addr_space_t as, unw_cursor_t *c, void *arg) +{ + print_error (__func__); + print_error (" not implemented\n"); + return -UNW_EINVAL; +} diff -d -urpN libunwind.3/src/Makefile.am libunwind.4/src/Makefile.am --- libunwind.3/src/Makefile.am 2012-02-21 17:57:16.863510404 +0100 +++ libunwind.4/src/Makefile.am 2012-02-27 15:55:53.835512739 +0100 @@ -8,7 +8,7 @@ COMMON_SO_LDFLAGS = -XCClinker -nostartf lib_LIBRARIES = lib_LTLIBRARIES = if !REMOTE_ONLY -lib_LIBRARIES += libunwind-ptrace.a +lib_LIBRARIES += libunwind-ptrace.a libunwind-coredump.a lib_LTLIBRARIES += libunwind.la endif @@ -26,6 +26,24 @@ libunwind_ptrace_a_SOURCES = \ ptrace/_UPT_reg_offset.c ptrace/_UPT_resume.c noinst_HEADERS += ptrace/_UPT_internal.h +### libunwind-coredump: +libunwind_coredump_a_SOURCES = \ + coredump/_UCD_accessors.c \ + coredump/_UCD_create.c \ + coredump/_UCD_destroy.c \ + coredump/_UCD_access_reg.c \ + coredump/_UCD_access_mem.c \ + coredump/_UCD_elf_map_image.c \ + coredump/_UCD_find_proc_info.c \ + coredump/_UCD_get_proc_name.c \ + \ + coredump/_UPT_elf.c \ + coredump/_UPT_access_fpreg.c \ + coredump/_UPT_get_dyn_info_list_addr.c \ + coredump/_UPT_put_unwind_info.c \ + coredump/_UPT_resume.c +noinst_HEADERS += coredump/_UCD_internal.h + ### libunwind-setjmp: libunwind_setjmp_la_LDFLAGS = $(COMMON_SO_LDFLAGS) \ -version-info $(SETJMP_SO_VERSION) --------------060801080503000600010903-- From MAILER-DAEMON Mon Mar 12 23:27:01 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1S7IO5-00026E-14 for mharc-libunwind-devel@gnu.org; Mon, 12 Mar 2012 23:27:01 -0400 Received: from eggs.gnu.org ([208.118.235.92]:45275) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S7IO1-000260-QN for libunwind-devel@nongnu.org; Mon, 12 Mar 2012 23:26:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1S7INz-0000e0-TU for libunwind-devel@nongnu.org; Mon, 12 Mar 2012 23:26:57 -0400 Received: from mail-yw0-f45.google.com ([209.85.213.45]:57765) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S7INz-0000dn-N7 for libunwind-devel@nongnu.org; Mon, 12 Mar 2012 23:26:55 -0400 Received: by yhoo21 with SMTP id o21so109086yho.4 for ; Mon, 12 Mar 2012 20:26:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type; bh=uUUWa/PBZ5oET85zloWFMfxMMMkK5SZJYVKxiaSBb8M=; b=kY8N8/WBWM6OjHvcsLPfLbZiMjtF+gXNUNhdrNGgmnQoq9luKqL7vHvEZoqdOPOC8I +GITwjOlFUjuqpqZImahbZeKTsdvCYcPLWodKXNrQwWKsdy9ICBFHd/oQpxuP3C+ZobX VHSSi/JUGbFkizN2wNqjKP4KE4Cn7TiCrjRVNc13GIkrQoTA5IedqsoySGoBW0qawO05 mjnZpNgXFxMedyyuxsGhyfjP2XfEnowbeAhR9UsPBTECEGi4ZNqtfbDfxbJhg92M84cs qCUwkdgW6gwveSsfNyTBvR4SIqoR10ixLfZbvmPCSReTvo4vYS9S9fFzGrPQoiHafULF Tlag== MIME-Version: 1.0 Received: by 10.229.137.85 with SMTP id v21mr3338309qct.70.1331609212897; Mon, 12 Mar 2012 20:26:52 -0700 (PDT) Sender: arun.sharma@gmail.com Received: by 10.229.94.141 with HTTP; Mon, 12 Mar 2012 20:26:52 -0700 (PDT) In-Reply-To: <4F57579B.5060003@redhat.com> References: <4F4BA6FD.6000503@redhat.com> <4F4BA743.4030405@redhat.com> <4F57579B.5060003@redhat.com> Date: Mon, 12 Mar 2012 20:26:52 -0700 X-Google-Sender-Auth: BXhae-luRtdfYtzLermnU04xA1M Message-ID: From: Arun Sharma To: Denys Vlasenko Content-Type: text/plain; charset=UTF-8 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.213.45 Cc: Karel Klic , Jiri Moskovcak , mtoman@redhat.com, Petr Machata , libunwind-devel@nongnu.org, Jan Kratochvil Subject: Re: [Libunwind-devel] [PATCHv3 1/4] Add core dump unwinding support to libunwind X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Mar 2012 03:26:59 -0000 I copied your patches + some build fixes for x64 to: https://github.com/adsharma/libunwind/commits/coredump2 Please verify that everything still works on your end. Some loose ends to be tied up before I can push to libunwind HEAD: * tests/test-coredump-unwind doesn't test anything right now. An actual test that fails if future commits break things would be great. This might require a test core dump file for every platform you care about. * _UCD_libs.h seems to have a different license. Please let me know if relicensing is possible. * I suspect ia64 is broken by 2.patch $ grep -i ia64 src/dwarf/Gfind_unwind_table.c #if UNW_TARGET_IA64 ia64 is not a dwarf platform and shouldn't be using stuff under src/dwarf. Please send me an incremental diff to move that code back to the original location. People working on other platforms: please verify that this works for you (or at least doesn't break anything). -Arun PS: git clone -b coredump2 git://github.com/adsharma/libunwind.git From MAILER-DAEMON Tue Mar 13 08:12:06 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1S7QaE-00043u-HY for mharc-libunwind-devel@gnu.org; Tue, 13 Mar 2012 08:12:06 -0400 Received: from eggs.gnu.org ([208.118.235.92]:54250) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S7QaB-00043A-59 for libunwind-devel@nongnu.org; Tue, 13 Mar 2012 08:12:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1S7QZm-0007BJ-Gc for libunwind-devel@nongnu.org; Tue, 13 Mar 2012 08:12:02 -0400 Received: from mx0.zoral.com.ua ([91.193.166.200]:51365 helo=mail.zoral.com.ua) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S7QZm-0007A3-41 for libunwind-devel@nongnu.org; Tue, 13 Mar 2012 08:11:38 -0400 Received: from skuns.kiev.zoral.com.ua (localhost [127.0.0.1]) by mail.zoral.com.ua (8.14.2/8.14.2) with ESMTP id q2DCBGaj082962; Tue, 13 Mar 2012 14:11:16 +0200 (EET) (envelope-from kostikbel@gmail.com) Received: from deviant.kiev.zoral.com.ua (kostik@localhost [127.0.0.1]) by deviant.kiev.zoral.com.ua (8.14.5/8.14.5) with ESMTP id q2DCBFS7037132; Tue, 13 Mar 2012 14:11:15 +0200 (EET) (envelope-from kostikbel@gmail.com) Received: (from kostik@localhost) by deviant.kiev.zoral.com.ua (8.14.5/8.14.5/Submit) id q2DCBD3p037131; Tue, 13 Mar 2012 14:11:13 +0200 (EET) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: deviant.kiev.zoral.com.ua: kostik set sender to kostikbel@gmail.com using -f Date: Tue, 13 Mar 2012 14:11:13 +0200 From: Konstantin Belousov To: Arun Sharma Message-ID: <20120313121113.GO75778@deviant.kiev.zoral.com.ua> References: <4F4BA6FD.6000503@redhat.com> <4F4BA743.4030405@redhat.com> <4F57579B.5060003@redhat.com> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="aT2fykPtWJaIx2HX" Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.4.2.3i X-Virus-Scanned: clamav-milter 0.95.2 at skuns.kiev.zoral.com.ua X-Virus-Status: Clean X-detected-operating-system: by eggs.gnu.org: FreeBSD 6.x (1) X-Received-From: 91.193.166.200 Cc: Karel Klic , Jiri Moskovcak , mtoman@redhat.com, Petr Machata , libunwind-devel@nongnu.org, Jan Kratochvil Subject: Re: [Libunwind-devel] [PATCHv3 1/4] Add core dump unwinding support to libunwind X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Mar 2012 12:12:04 -0000 --aT2fykPtWJaIx2HX Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Mon, Mar 12, 2012 at 08:26:52PM -0700, Arun Sharma wrote: > I copied your patches + some build fixes for x64 to: >=20 > https://github.com/adsharma/libunwind/commits/coredump2 >=20 > Please verify that everything still works on your end. Some loose ends > to be tied up before I can push to libunwind HEAD: >=20 > * tests/test-coredump-unwind doesn't test anything right now. An > actual test that fails if future commits break things would be great. > This might require a test core dump file for every platform you care > about. I think it is requirement to generate a coredump on machine where the testing is performed. >=20 > * _UCD_libs.h seems to have a different license. Please let me know if > relicensing is possible. >=20 > * I suspect ia64 is broken by 2.patch >=20 > $ grep -i ia64 src/dwarf/Gfind_unwind_table.c > #if UNW_TARGET_IA64 >=20 > ia64 is not a dwarf platform and shouldn't be using stuff under > src/dwarf. Please send me an incremental diff to move that code back > to the original location. >=20 > People working on other platforms: please verify that this works for > you (or at least doesn't break anything). It does break build. Please look at http://people.freebsd.org/~kib/git/libunwind.git/ branch coredump2, were I made it at least compilable for FreeBSD/i386 and FreeBSD/amd64. The commit 52a8e2119d86a55218b8bf131f46a78fdac861dd is probably wrong, I do not have Linux machine to test. I am not sure how to test the functionality. >=20 > -Arun >=20 > PS: git clone -b coredump2 git://github.com/adsharma/libunwind.git --aT2fykPtWJaIx2HX Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (FreeBSD) iEYEARECAAYFAk9fOWEACgkQC3+MBN1Mb4h1NQCgk/Gp8oyqQRLIBMNrqtt3YHVf kdwAn1v6u1PB/FT+vuC7gUwYe71Jtg5V =TNu5 -----END PGP SIGNATURE----- --aT2fykPtWJaIx2HX-- From MAILER-DAEMON Tue Mar 13 11:07:11 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1S7TJf-0006xH-73 for mharc-libunwind-devel@gnu.org; Tue, 13 Mar 2012 11:07:11 -0400 Received: from eggs.gnu.org ([208.118.235.92]:37438) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S7TJG-0006qO-2y for libunwind-devel@nongnu.org; Tue, 13 Mar 2012 11:07:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1S7TJA-0008H3-V6 for libunwind-devel@nongnu.org; Tue, 13 Mar 2012 11:06:45 -0400 Received: from mail-ey0-f173.google.com ([209.85.215.173]:52927) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S7TJA-0008Go-Lf for libunwind-devel@nongnu.org; Tue, 13 Mar 2012 11:06:40 -0400 Received: by eaaf11 with SMTP id f11so334843eaa.4 for ; Tue, 13 Mar 2012 08:06:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type; bh=fBka8SHgIns5DPW88bP6OOSxg5/pu8ZZcsN6WqYEibM=; b=JEkGaOx8ztma4YeqdILJszptHL7wCn4aoTQekTNTx5be3HN45vm7ReiQqJ1+raAjBG xsuv8XGoa8FtMjPCY8j75Ch/ft9XqRxyLIexCy520iQyZJYLPwKbVfZEz1D5G6CwWdUy Zg5wh/xzO6pJR0O93wiTO1TsUxBOKttVzUwTt7EqJgjbDSs0quDeyKKEOCBQfPS5wqq5 1kOwtj3ickFpCeMRCILT+Y/YwyI3KizhVgL01LI2XWWRBgNiBvVMoXPad4HPOoHAt5GD kxDlydSVNGrK+UTIUZZz/zcIu0EMsp88KBgMK17y9gpd5pKZ75ox0faaOHx5EPQqzM72 +N+Q== MIME-Version: 1.0 Received: by 10.229.69.33 with SMTP id x33mr3997425qci.30.1331651197747; Tue, 13 Mar 2012 08:06:37 -0700 (PDT) Sender: arun.sharma@gmail.com Received: by 10.229.94.141 with HTTP; Tue, 13 Mar 2012 08:06:37 -0700 (PDT) In-Reply-To: <20120313121113.GO75778@deviant.kiev.zoral.com.ua> References: <4F4BA6FD.6000503@redhat.com> <4F4BA743.4030405@redhat.com> <4F57579B.5060003@redhat.com> <20120313121113.GO75778@deviant.kiev.zoral.com.ua> Date: Tue, 13 Mar 2012 08:06:37 -0700 X-Google-Sender-Auth: 29woTUMgMlE27-ehvNzQorarenI Message-ID: From: Arun Sharma To: Konstantin Belousov Content-Type: text/plain; charset=UTF-8 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.215.173 Cc: Karel Klic , Jiri Moskovcak , mtoman@redhat.com, Petr Machata , libunwind-devel@nongnu.org, Jan Kratochvil Subject: Re: [Libunwind-devel] [PATCHv3 1/4] Add core dump unwinding support to libunwind X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Mar 2012 15:07:10 -0000 On Tue, Mar 13, 2012 at 5:11 AM, Konstantin Belousov wrote: >> * tests/test-coredump-unwind doesn't test anything right now. An >> actual test that fails if future commits break things would be great. >> This might require a test core dump file for every platform you care >> about. > I think it is requirement to generate a coredump on machine where the > testing is performed. You're right. I don't think coredump unwinding on another platform is supported. >> People working on other platforms: please verify that this works for >> you (or at least doesn't break anything). > It does break build. > Please look at http://people.freebsd.org/~kib/git/libunwind.git/ > branch coredump2, were I made it at least compilable for FreeBSD/i386 > and FreeBSD/amd64. > > The commit 52a8e2119d86a55218b8bf131f46a78fdac861dd is probably wrong, > I do not have Linux machine to test. Yes - it breaks Linux. I pulled everything up to dc9be1a into: git://github.com/adsharma/libunwind.git (coredump2) > > I am not sure how to test the functionality. The comments at the top of test-coredump-unwind might be useful. I recall getting some reasonable output in the last iteration of the patch. * * Run: * objdump -sx COREDUMP * eu-unstrip -n --core COREDUMP * figure out which segments in COREDUMP correspond to which mapped executable files * (binary and libraries), then supply them like this: * ./example-core-unwind COREDUMP 3:/bin/crashed_program 6:/lib/libc.so.6 [...] Denys: can you automate the objdump step or have the test figure out the right segment automatically? -Arun From MAILER-DAEMON Tue Mar 13 12:22:52 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1S7UUt-0006yA-WF for mharc-libunwind-devel@gnu.org; Tue, 13 Mar 2012 12:22:52 -0400 Received: from eggs.gnu.org ([208.118.235.92]:45501) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S7UUi-0006sl-Jb for libunwind-devel@nongnu.org; Tue, 13 Mar 2012 12:22:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1S7UUZ-0008Kp-4j for libunwind-devel@nongnu.org; Tue, 13 Mar 2012 12:22:40 -0400 Received: from mx0.zoral.com.ua ([91.193.166.200]:64315 helo=mail.zoral.com.ua) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S7UUY-0008JO-Oh for libunwind-devel@nongnu.org; Tue, 13 Mar 2012 12:22:31 -0400 Received: from skuns.kiev.zoral.com.ua (localhost [127.0.0.1]) by mail.zoral.com.ua (8.14.2/8.14.2) with ESMTP id q2DGLfqd009412; Tue, 13 Mar 2012 18:21:41 +0200 (EET) (envelope-from konstantin.belousov@zoral.com.ua) Received: from deviant.kiev.zoral.com.ua (kostik@localhost [127.0.0.1]) by deviant.kiev.zoral.com.ua (8.14.5/8.14.5) with ESMTP id q2DGLftG047735; Tue, 13 Mar 2012 18:21:41 +0200 (EET) (envelope-from konstantin.belousov@zoral.com.ua) Received: (from kostik@localhost) by deviant.kiev.zoral.com.ua (8.14.5/8.14.5/Submit) id q2DGLe1l047734; Tue, 13 Mar 2012 18:21:40 +0200 (EET) (envelope-from konstantin.belousov@zoral.com.ua) X-Authentication-Warning: deviant.kiev.zoral.com.ua: kostik set sender to konstantin.belousov@zoral.com.ua using -f Date: Tue, 13 Mar 2012 18:21:40 +0200 From: Konstantin Belousov To: Arun Sharma Message-ID: <20120313162140.GT75778@deviant.kiev.zoral.com.ua> References: <4F4BA6FD.6000503@redhat.com> <4F4BA743.4030405@redhat.com> <4F57579B.5060003@redhat.com> <20120313121113.GO75778@deviant.kiev.zoral.com.ua> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="WoVkYvKea/6+mhsn" Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.4.2.3i X-Virus-Scanned: clamav-milter 0.95.2 at skuns.kiev.zoral.com.ua X-Virus-Status: Clean X-detected-operating-system: by eggs.gnu.org: FreeBSD 6.x (1) X-Received-From: 91.193.166.200 Cc: Karel Klic , Jiri Moskovcak , mtoman@redhat.com, Petr Machata , libunwind-devel@nongnu.org, Jan Kratochvil Subject: Re: [Libunwind-devel] [PATCHv3 1/4] Add core dump unwinding support to libunwind X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Mar 2012 16:22:50 -0000 --WoVkYvKea/6+mhsn Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Tue, Mar 13, 2012 at 08:06:37AM -0700, Arun Sharma wrote: > On Tue, Mar 13, 2012 at 5:11 AM, Konstantin Belousov > wrote: >=20 > >> * tests/test-coredump-unwind doesn't test anything right now. An > >> actual test that fails if future commits break things would be great. > >> This might require a test core dump file for every platform you care > >> about. > > I think it is requirement to generate a coredump on machine where the > > testing is performed. >=20 > You're right. I don't think coredump unwinding on another platform is sup= ported. Not just platform, but I expect that exact versions of all objects participated in the dumped image shall be the same. >=20 > >> People working on other platforms: please verify that this works for > >> you (or at least doesn't break anything). > > It does break build. > > Please look at http://people.freebsd.org/~kib/git/libunwind.git/ > > branch coredump2, were I made it at least compilable for FreeBSD/i386 > > and FreeBSD/amd64. > > > > The commit 52a8e2119d86a55218b8bf131f46a78fdac861dd is probably wrong, > > I do not have Linux machine to test. >=20 > Yes - it breaks Linux. I pulled everything up to dc9be1a into: >=20 > git://github.com/adsharma/libunwind.git (coredump2) I hope that cc7c74e691032b8c694d673dc1530c26ce801736 would be fine for Linux too, the tip of the branch was forcibly updated. >=20 > > > > I am not sure how to test the functionality. >=20 > The comments at the top of test-coredump-unwind might be useful. I > recall getting some reasonable output in the last iteration of the > patch. >=20 > * > * Run: > * objdump -sx COREDUMP > * eu-unstrip -n --core COREDUMP > * figure out which segments in COREDUMP correspond to which mapped > executable files > * (binary and libraries), then supply them like this: > * ./example-core-unwind COREDUMP 3:/bin/crashed_program 6:/lib/libc.so.6= [...] What is eu-unstrip ? Hm, test-coredump-unwind.c needs some changes too. I will look at it later. >=20 > Denys: can you automate the objdump step or have the test figure out > the right segment automatically? >=20 > -Arun --WoVkYvKea/6+mhsn Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (FreeBSD) iEUEARECAAYFAk9fdBMACgkQC3+MBN1Mb4hf8wCeKeXYPCDTbifswUdA6SSgdCOa wowAmIdX0OcZSFEWb0AaoUmBnd2G7B8= =QM08 -----END PGP SIGNATURE----- --WoVkYvKea/6+mhsn-- From MAILER-DAEMON Thu Mar 15 13:57:47 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1S8Evr-0007zu-NJ for mharc-libunwind-devel@gnu.org; Thu, 15 Mar 2012 13:57:47 -0400 Received: from eggs.gnu.org ([208.118.235.92]:47166) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S8EvQ-0007p5-F8 for libunwind-devel@nongnu.org; Thu, 15 Mar 2012 13:57:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1S8EvL-0007fS-Bu for libunwind-devel@nongnu.org; Thu, 15 Mar 2012 13:57:20 -0400 Received: from mx1.redhat.com ([209.132.183.28]:46709) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S8EvL-0007fG-2a for libunwind-devel@nongnu.org; Thu, 15 Mar 2012 13:57:15 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q2FHvBU7028378 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 15 Mar 2012 13:57:11 -0400 Received: from [10.34.25.62] (dhcp-25-62.brq.redhat.com [10.34.25.62]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q2FHv7ac015413; Thu, 15 Mar 2012 13:57:09 -0400 Message-ID: <4F622D73.7050400@redhat.com> Date: Thu, 15 Mar 2012 18:57:07 +0100 From: Denys Vlasenko User-Agent: Mozilla/5.0 (X11; Linux i686; rv:10.0.1) Gecko/20120216 Thunderbird/10.0.1 MIME-Version: 1.0 To: Arun Sharma References: <4F4BA6FD.6000503@redhat.com> <4F4BA743.4030405@redhat.com> <4F57579B.5060003@redhat.com> In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: Karel Klic , Jiri Moskovcak , mtoman@redhat.com, Petr Machata , libunwind-devel@nongnu.org, Jan Kratochvil Subject: Re: [Libunwind-devel] [PATCHv3 1/4] Add core dump unwinding support to libunwind X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 15 Mar 2012 17:57:44 -0000 On 03/13/2012 04:26 AM, Arun Sharma wrote: > I copied your patches + some build fixes for x64 to: > > https://github.com/adsharma/libunwind/commits/coredump2 > > Please verify that everything still works on your end. Checked out, built it, installed, built my program against it, and tested that it still works. Thanks! > Some loose ends > to be tied up before I can push to libunwind HEAD: > > * tests/test-coredump-unwind doesn't test anything right now. An > actual test that fails if future commits break things would be great. > This might require a test core dump file for every platform you care > about. I think I can create an actual working test for you based on my other program. Give me a few days... > * _UCD_libs.h seems to have a different license. Please let me know if > relicensing is possible. Sure. It's a trivial file, I don't mind if you use whatever license you like on it :) > * I suspect ia64 is broken by 2.patch > > $ grep -i ia64 src/dwarf/Gfind_unwind_table.c > #if UNW_TARGET_IA64 > > ia64 is not a dwarf platform and shouldn't be using stuff under > src/dwarf. Please send me an incremental diff to move that code back > to the original location. Patch 2 moves ptrace-independent code from src/ptrace/_UPT_find_proc_info.c to src/dwarf/{G,L}find_unwind_table.c. Before my patch set: the code under "#if UNW_TARGET_IA64" consists of IA64-specific implementation of _UPTi_find_unwind_table() function. This function is called from get_unwind_info() function. I need to make it available for use by the analogous get_unwind_info() function in src/coredump/_UCD_find_proc_info.c file. Meaning that I would rather use a common code for that than duplicate it in src/ptrace/* and src/coredump/*. You say that it's wrong to call it *dwarf*_find_unwind_table and put it into src/dwarf/*. I'm ok with it. Where do you think is the best place to have it? I'll move it there. -- vda From MAILER-DAEMON Thu Mar 15 14:32:51 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1S8FTn-0004Jp-3T for mharc-libunwind-devel@gnu.org; Thu, 15 Mar 2012 14:32:51 -0400 Received: from eggs.gnu.org ([208.118.235.92]:43164) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S8FTh-0004II-A7 for libunwind-devel@nongnu.org; Thu, 15 Mar 2012 14:32:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1S8FTf-0006ba-OY for libunwind-devel@nongnu.org; Thu, 15 Mar 2012 14:32:44 -0400 Received: from mail-yx0-f173.google.com ([209.85.213.173]:57664) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S8FTf-0006b5-GN for libunwind-devel@nongnu.org; Thu, 15 Mar 2012 14:32:43 -0400 Received: by yenr5 with SMTP id r5so3852493yen.4 for ; Thu, 15 Mar 2012 11:32:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type; bh=ai2mMDjxSHXS38HAowovzeds2qFnvyvGFey/KHOeRrU=; b=CztGEnPk1NgO8LJ/Hm7Bre61LlJUNPKCosoKb1UkujNUBRaPfFfGbnTY3z9Jx/1qCQ svG32t/WqqOPYPL8nOV+oG0/eEXMRyBRauplp8JIgayN7fJpJCGNba3RvLP2/iNynJCv iXhVcw7tkgPMXrMgM4FvXAn17VB1kBWgXSDLVX3lpAFfx8hr8Sxcc3WqR9ig/lXSeOTs SySEYM3+9fHa8r4THZoxZ7b8dylY+yFYs7GXNMVLPHuISnCoy/Tz6jyz7MH6rjv+GI3e petEb8pp/vOl619cYFQQ+Uq+CN+zc1EEUmaPEU4ieB3PA7bhizYS43iWGyiqOzmeny70 2P1g== MIME-Version: 1.0 Received: by 10.224.33.1 with SMTP id f1mr173066qad.83.1331836360741; Thu, 15 Mar 2012 11:32:40 -0700 (PDT) Sender: arun.sharma@gmail.com Received: by 10.229.94.141 with HTTP; Thu, 15 Mar 2012 11:32:40 -0700 (PDT) In-Reply-To: <4F622D73.7050400@redhat.com> References: <4F4BA6FD.6000503@redhat.com> <4F4BA743.4030405@redhat.com> <4F57579B.5060003@redhat.com> <4F622D73.7050400@redhat.com> Date: Thu, 15 Mar 2012 11:32:40 -0700 X-Google-Sender-Auth: nCZ0jdJkrjN2XQ9jOBBntZ4lYvI Message-ID: From: Arun Sharma To: Denys Vlasenko Content-Type: text/plain; charset=UTF-8 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.213.173 Cc: Karel Klic , Jiri Moskovcak , mtoman@redhat.com, Petr Machata , libunwind-devel@nongnu.org, Jan Kratochvil Subject: Re: [Libunwind-devel] [PATCHv3 1/4] Add core dump unwinding support to libunwind X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 15 Mar 2012 18:32:49 -0000 On Thu, Mar 15, 2012 at 10:57 AM, Denys Vlasenko wrote: > You say that it's wrong to call it *dwarf*_find_unwind_table > and put it into src/dwarf/*. > I'm ok with it. > Where do you think is the best place to have it? > I'll move it there. How about moving the ia64 find_unwind_table to its own file under src/ptrace? Then you can then share it via #include in src/coredump/_UPT*. -Arun From MAILER-DAEMON Fri Mar 16 08:54:44 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1S8Wg8-00009p-Pm for mharc-libunwind-devel@gnu.org; Fri, 16 Mar 2012 08:54:44 -0400 Received: from eggs.gnu.org ([208.118.235.92]:58589) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S8Wfj-0008A7-7J for libunwind-devel@nongnu.org; Fri, 16 Mar 2012 08:54:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1S8Wfc-0000MC-UU for libunwind-devel@nongnu.org; Fri, 16 Mar 2012 08:54:18 -0400 Received: from mx1.redhat.com ([209.132.183.28]:21965) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S8Wfc-0000M7-M9 for libunwind-devel@nongnu.org; Fri, 16 Mar 2012 08:54:12 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q2GCs47w008769 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 16 Mar 2012 08:54:04 -0400 Received: from [10.34.25.62] (dhcp-25-62.brq.redhat.com [10.34.25.62]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q2GCrxvG010176; Fri, 16 Mar 2012 08:54:02 -0400 Message-ID: <4F6337E7.2080105@redhat.com> Date: Fri, 16 Mar 2012 13:53:59 +0100 From: Denys Vlasenko User-Agent: Mozilla/5.0 (X11; Linux i686; rv:10.0.1) Gecko/20120216 Thunderbird/10.0.1 MIME-Version: 1.0 To: Arun Sharma References: <4F4BA6FD.6000503@redhat.com> <4F4BA743.4030405@redhat.com> <4F57579B.5060003@redhat.com> <4F622D73.7050400@redhat.com> In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: Karel Klic , Jiri Moskovcak , mtoman@redhat.com, Petr Machata , libunwind-devel@nongnu.org, Jan Kratochvil Subject: Re: [Libunwind-devel] [PATCHv3 1/4] Add core dump unwinding support to libunwind X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 Mar 2012 12:54:43 -0000 On 03/15/2012 07:32 PM, Arun Sharma wrote: > On Thu, Mar 15, 2012 at 10:57 AM, Denys Vlasenko wrote: > >> You say that it's wrong to call it *dwarf*_find_unwind_table >> and put it into src/dwarf/*. >> I'm ok with it. >> Where do you think is the best place to have it? >> I'll move it there. > > How about moving the ia64 find_unwind_table to its own file under > src/ptrace? Then you can then share it via #include in > src/coredump/_UPT*. Well... this would create a bad situation where libunwind-coredump.a library either requires libunwind-ptrace.a, or includes a copy of part of it. I want this code to end up in libunwind.so instead, so we can use it equally from both libs. Our predicament seems to be that we have no good place to put its source in the source tree, right? drwxr-xr-x. 2 root root 4096 Feb 13 18:43 arm drwxr-xr-x. 2 root root 4096 Feb 13 18:43 hppa drwxr-xr-x. 2 root root 4096 Feb 13 18:43 ia64 drwxr-xr-x. 2 root root 4096 Feb 13 18:43 mi drwxr-xr-x. 2 root root 4096 Feb 13 18:43 mips drwxr-xr-x. 2 root root 4096 Feb 13 18:43 ppc drwxr-xr-x. 2 root root 4096 Feb 13 18:43 ppc32 drwxr-xr-x. 2 root root 4096 Feb 13 18:43 ppc64 drwxr-xr-x. 2 root root 4096 Feb 13 18:43 x86 drwxr-xr-x. 2 root root 4096 Feb 13 18:43 x86_64 The above dirs are arch specific - not suitable. drwxr-xr-x. 2 root root 4096 Feb 24 11:36 coredump drwxr-xr-x. 2 root root 4096 Feb 21 16:51 ptrace Sources of libunwind-coredump.a and libunwind-ptrace.a - not good too, we want to share it between them, that's the whole point. drwxr-xr-x. 2 root root 4096 Feb 21 17:21 dwarf But this function has nothing to do with dwarf... drwxr-xr-x. 2 root root 4096 Feb 13 18:43 setjmp It is unrelated to setjmp'ing too... This leaves us with the only remaining source dir: drwxr-xr-x. 2 root root 4096 Feb 13 18:43 unwind Can we put it into this dir? If not, let's just create a new one, say common/*, for the miscellaneous shared code bits... What do you say? -- vda From MAILER-DAEMON Sat Mar 17 09:44:12 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1S8tvY-0008BV-KK for mharc-libunwind-devel@gnu.org; Sat, 17 Mar 2012 09:44:12 -0400 Received: from eggs.gnu.org ([208.118.235.92]:44390) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S8ZVP-00047q-Ue for libunwind-devel@nongnu.org; Fri, 16 Mar 2012 11:55:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1S8ZVG-0001Wh-HX for libunwind-devel@nongnu.org; Fri, 16 Mar 2012 11:55:51 -0400 Received: from smtp2.mathworks.com ([144.212.95.218]:59525) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S8ZVG-0001WN-CP for libunwind-devel@nongnu.org; Fri, 16 Mar 2012 11:55:42 -0400 Received: from mail-vif.mathworks.com (newscl02ah.mathworks.com [144.212.95.122]) by smtp2.mathworks.com (8.13.8/8.12.11) with ESMTP id q2GFtdSn020745 for ; Fri, 16 Mar 2012 11:55:39 -0400 (EDT) Received: from EXHUB-01-AH.ad.mathworks.com (exhub-01-ah.mathworks.com [172.31.22.59]) by mail-vif.mathworks.com (8.13.8/8.13.8) with ESMTP id q2GFtda8021727 for ; Fri, 16 Mar 2012 11:55:39 -0400 (EDT) Received: from exmb-00-ah.ad.mathworks.com ([fe80::d936:14a5:ccfb:c26b]) by EXHUB-01-AH.ad.mathworks.com ([::1]) with mapi id 14.01.0339.001; Fri, 16 Mar 2012 11:55:38 -0400 From: Prabhat Verma To: "libunwind-devel@nongnu.org" Thread-Topic: Libunwind support for NULL IP Thread-Index: Ac0DjTUa6/Td2PqQRHuKzLeMOGqNNQ== Date: Fri, 16 Mar 2012 15:55:37 +0000 Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [144.212.107.58] Content-Type: multipart/alternative; boundary="_000_F5BA174BCF4EB748B411513D10BD3B2209A95Eexmb00ahadmathwor_" MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Solaris 10 (beta) X-Received-From: 144.212.95.218 X-Mailman-Approved-At: Sat, 17 Mar 2012 09:44:10 -0400 Subject: [Libunwind-devel] Libunwind support for NULL IP X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 Mar 2012 15:55:55 -0000 --_000_F5BA174BCF4EB748B411513D10BD3B2209A95Eexmb00ahadmathwor_ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hello, We are trying to replace backtrace with libunwind (local unwinding) for our= diagnostic purposes. A major motivation behind this decision was the inabi= lity of backtrace to handle stack frames containing NULL IP. In our case, t= his may happen if someone ends up doing this: void (*p)() =3D NULL; p(); In our case, we may have a call-chain that can look like: Foo() calls bar() calls foobar() calls .... calls p() Ideally, the aim is to get a trace starting with p() down to the start.... As a POC, I wrote a small test-case that makes nested function calls. In th= e most nested function, I do a getcontext and unw_init_local. During unw_st= ep I clobber one of the IP (from the initialized cursor) using set_unw_reg.= The subsequent call to unw_step either segfaults or aborts (based on what = configuration options were used to build libunwind). Is this a correct simu= lation of my test-case? I would like to ask the developers if such an abort is the expected behavio= r (I have limited knowledge of stack unwinding)? If not, is there any fix o= r workaround that would enable moving on to the next frame (possibly droppi= ng the NULL IP frame or replacing it with a known dummy frame?). As a secon= d experiment, I tried setting the IP to some dummy address and the results = are unreliable (sometimes it works and other times it fails). In our case, libunwind calls will sit inside our signal handler. On the cur= rent platform, getcontext() and unw_getcontext() seem to be interchangeable= (I am guessing unw_context does less work than getcontext). All help is highly appreciated. Regards, Prabhat Specs: Debian GNU/Linux 6.0.1 % g++ -v Using built-in specs. Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion=3D'Debian 4.4.5-8' -= -with-bugurl=3Dfile:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages= =3Dc,c++,fortran,objc,obj-c++ --prefix=3D/usr --program-suffix=3D-4.4 --ena= ble-shared --enable-multiarch --enable-linker-build-id --with-system-zlib -= -libexecdir=3D/usr/lib --without-included-gettext --enable-threads=3Dposix = --with-gxx-include-dir=3D/usr/include/c++/4.4 --libdir=3D/usr/lib --enable-= nls --enable-clocale=3Dgnu --enable-libstdcxx-debug --enable-objc-gc --with= -arch-32=3Di586 --with-tune=3Dgeneric --enable-checking=3Drelease --build= =3Dx86_64-linux-gnu --host=3Dx86_64-linux-gnu --target=3Dx86_64-linux-gnu Thread model: posix gcc version 4.4.5 (Debian 4.4.5-8) The output of testcase (foo9 calls foo8 calls .....foo1 calls foo): No Clobber: Inside foo9() Inside foo8() Inside foo7() Inside foo6() Inside foo5() Inside foo4() Inside foo3() Inside foo2() Inside foo1() Inside foo () Depth Registers 0---> ip =3D 400ae7, sp =3D 7fff8706c4f0 1---> ip =3D 400b01, sp =3D 7fff8706c500 2---> ip =3D 400b1b, sp =3D 7fff8706c510 3---> ip =3D 400b35, sp =3D 7fff8706c520 4---> ip =3D 400b4f, sp =3D 7fff8706c530 5---> ip =3D 400b69, sp =3D 7fff8706c540 6---> ip =3D 400b83, sp =3D 7fff8706c550 7---> ip =3D 400b9d, sp =3D 7fff8706c560 8---> ip =3D 400bb7, sp =3D 7fff8706c570 9---> ip =3D 400bd1, sp =3D 7fff8706c580 10---> ip =3D 400bfd, sp =3D 7fff8706c590 11---> ip =3D 7fe960cf2c4d, sp =3D 7fff8706c5a0 12---> ip =3D 400919, sp =3D 7fff8706c660 Clobbered IP: Inside foo9() Inside foo8() Inside foo7() Inside foo6() Inside foo5() Inside foo4() Inside foo3() Inside foo2() Inside foo1() Inside foo () Depth Registers libunwindtest: dwarf/Gparser.c:754: apply_reg_state: Assertion `rs->reg[17]= .where =3D=3D DWARF_WHERE_EXPR' failed. Aborted --_000_F5BA174BCF4EB748B411513D10BD3B2209A95Eexmb00ahadmathwor_ Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable

Hello,

 

We are trying to replace backtrace with libunwind (l= ocal unwinding) for our diagnostic purposes. A major motivation behind this= decision was the inability of backtrace to handle stack frames containing = NULL IP. In our case, this may happen if someone ends up doing this:

 

void (*p)() =3D NULL;

p();

 

In our case, we may have a call-chain that can look = like:

Foo() calls bar() calls foobar() calls …. call= s p()

 

Ideally, the aim is to get a trace starting with p()= down to the start….

 

As a POC, I wrote a small test-case that makes neste= d function calls. In the most nested function, I do a getcontext and unw_in= it_local. During unw_step I clobber one of the IP (from the initialized cur= sor) using set_unw_reg. The subsequent call to unw_step either segfaults or aborts (based on what configuration o= ptions were used to build libunwind). Is this a correct simulation of my te= st-case?

 

I would like to ask the developers if such an abort = is the expected behavior (I have limited knowledge of stack unwinding)? If = not, is there any fix or workaround that would enable moving on to the next= frame (possibly dropping the NULL IP frame or replacing it with a known dummy frame?). As a second experimen= t, I tried setting the IP to some dummy address and the results are unrelia= ble (sometimes it works and other times it fails).

 

In our case, libunwind calls will sit inside our sig= nal handler. On the current platform, getcontext() and unw_getcontext() see= m to be interchangeable (I am guessing unw_context does less work than getc= ontext).

 

All help is highly appreciated.

 

Regards,

Prabhat

 

Specs:

Debian GNU/Linux 6.0.1

 

% g++ -v

Using built-in specs.

Target: x86_64-linux-gnu

Configured with: ../src/configure -v --with-pkgversi= on=3D'Debian 4.4.5-8' --with-bugurl=3Dfile:///usr/share/doc/gcc-4.4/README.= Bugs --enable-languages=3Dc,c++,fortran,objc,obj-c++ --pref= ix=3D/usr --program-suffix=3D-4.4 --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=3D/usr/lib --with= out-included-gettext --enable-threads=3Dposix --with-gxx-include-dir=3D/usr= /include/c++/4.4 --libdir=3D/usr/lib --enable-nls --enable-clocale= =3Dgnu --enable-libstdcxx-debug --enable-objc-gc --with-arch-32=3Di586 --with-tune=3Dgeneric --enable-checking=3Drelease --build=3Dx86_64-linux-g= nu --host=3Dx86_64-linux-gnu --target=3Dx86_64-linux-gnu

Thread model: posix

gcc version 4.4.5 (Debian 4.4.5-8)

 

 

The output of testcase (foo9 calls foo8 calls …= ;..foo1 calls foo):

No Clobber:

 

Inside foo9()

Inside foo8()

Inside foo7()

Inside foo6()

Inside foo5()

Inside foo4()

Inside foo3()

Inside foo2()

Inside foo1()

Inside foo ()

 

Depth   Registers

0--->      ip =3D 400ae7= , sp =3D 7fff8706c4f0

1--->      ip =3D 400b01= , sp =3D 7fff8706c500

2--->      ip =3D 400b1b= , sp =3D 7fff8706c510

3--->      ip =3D 400b35= , sp =3D 7fff8706c520

4--->      ip =3D 400b4f= , sp =3D 7fff8706c530

5--->      ip =3D 400b69= , sp =3D 7fff8706c540

6--->      ip =3D 400b83= , sp =3D 7fff8706c550

7--->      ip =3D 400b9d= , sp =3D 7fff8706c560

8--->      ip =3D 400bb7= , sp =3D 7fff8706c570

9--->      ip =3D 400bd1= , sp =3D 7fff8706c580

10--->    ip =3D 400bfd, sp =3D 7f= ff8706c590

11--->    ip =3D 7fe960cf2c4d, sp = =3D 7fff8706c5a0

12--->    ip =3D 400919, sp =3D 7f= ff8706c660

 

Clobbered IP:

 

Inside foo9()

Inside foo8()

Inside foo7()

Inside foo6()

Inside foo5()

Inside foo4()

Inside foo3()

Inside foo2()

Inside foo1()

Inside foo ()

 

Depth   Registers

libunwindtest: dwarf/Gparser.c:754: apply_reg_state:= Assertion `rs->reg[17].where =3D=3D DWARF_WHERE_EXPR' failed.

Aborted

--_000_F5BA174BCF4EB748B411513D10BD3B2209A95Eexmb00ahadmathwor_-- From MAILER-DAEMON Fri Mar 23 16:00:46 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1SBAfG-00073a-9Y for mharc-libunwind-devel@gnu.org; Fri, 23 Mar 2012 16:00:46 -0400 Received: from eggs.gnu.org ([208.118.235.92]:33204) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SBAfE-00072c-06 for libunwind-devel@nongnu.org; Fri, 23 Mar 2012 16:00:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SBAfB-0006yf-Fc for libunwind-devel@nongnu.org; Fri, 23 Mar 2012 16:00:43 -0400 Received: from mx1.redhat.com ([209.132.183.28]:4366) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SBAfB-0006yX-77 for libunwind-devel@nongnu.org; Fri, 23 Mar 2012 16:00:41 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q2NK0dp0011207 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 23 Mar 2012 16:00:39 -0400 Received: from localhost.localdomain (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q2NK0YS0003055; Fri, 23 Mar 2012 16:00:39 -0400 From: Alexander Larsson To: libunwind-devel@nongnu.org Date: Fri, 23 Mar 2012 21:00:27 +0100 Message-Id: <1332532830-9327-2-git-send-email-alexl@redhat.com> In-Reply-To: <1332532830-9327-1-git-send-email-alexl@redhat.com> References: <1332532830-9327-1-git-send-email-alexl@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Subject: [Libunwind-devel] [PATCH 1/4] Fix build with --enable-debug X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 23 Mar 2012 20:00:45 -0000 This just fixes a typo --- src/coredump/_UCD_access_reg_linux.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/coredump/_UCD_access_reg_linux.c b/src/coredump/_UCD_access_reg_linux.c index 87156c9..72b6e22 100644 --- a/src/coredump/_UCD_access_reg_linux.c +++ b/src/coredump/_UCD_access_reg_linux.c @@ -80,7 +80,7 @@ _UCD_access_reg (unw_addr_space_t as, /* pr_reg is a long[] array, but it contains struct user_regs_struct's * image. */ - Debug(1 "pr_reg[%d]:%ld (0x%lx)", regnum, + Debug(1, "pr_reg[%d]:%ld (0x%lx)", regnum, (long)ui->prstatus->pr_reg[regnum], (long)ui->prstatus->pr_reg[regnum] ); -- 1.7.7.6 From MAILER-DAEMON Fri Mar 23 16:00:48 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1SBAfI-00076X-Co for mharc-libunwind-devel@gnu.org; Fri, 23 Mar 2012 16:00:48 -0400 Received: from eggs.gnu.org ([208.118.235.92]:33191) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SBAfD-00072S-21 for libunwind-devel@nongnu.org; Fri, 23 Mar 2012 16:00:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SBAf8-0006yF-7A for libunwind-devel@nongnu.org; Fri, 23 Mar 2012 16:00:42 -0400 Received: from mx1.redhat.com ([209.132.183.28]:2758) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SBAf7-0006xt-V4 for libunwind-devel@nongnu.org; Fri, 23 Mar 2012 16:00:38 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q2NK0Z79027900 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 23 Mar 2012 16:00:35 -0400 Received: from localhost.localdomain (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q2NK0YRx003055; Fri, 23 Mar 2012 16:00:34 -0400 From: Alexander Larsson To: libunwind-devel@nongnu.org Date: Fri, 23 Mar 2012 21:00:26 +0100 Message-Id: <1332532830-9327-1-git-send-email-alexl@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Subject: [Libunwind-devel] [PATCH 0/4] Support for multiple threads in coredumps X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 23 Mar 2012 20:00:47 -0000 This is based on the coredump2 branch at: https://github.com/adsharma/libunwind/commits/coredump2 It fixes a build issue and adds features i needed to make backtraces from coredumps with multiple threads. Alexander Larsson (4): Fix build with --enable-debug Add _UCD_get_pid and _UCD_get_cursig Break out the ifdefs for the UCD_info.prstatus type Add support for multiple threads in core files include/libunwind-coredump.h | 4 ++ src/coredump/_UCD_access_reg_linux.c | 2 +- src/coredump/_UCD_create.c | 93 ++++++++++++++++++++++++---------- src/coredump/_UCD_internal.h | 17 ++++--- 4 files changed, 81 insertions(+), 35 deletions(-) -- 1.7.7.6 From MAILER-DAEMON Fri Mar 23 16:00:49 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1SBAfJ-00079E-IY for mharc-libunwind-devel@gnu.org; Fri, 23 Mar 2012 16:00:49 -0400 Received: from eggs.gnu.org ([208.118.235.92]:33239) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SBAfH-000751-6G for libunwind-devel@nongnu.org; Fri, 23 Mar 2012 16:00:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SBAfE-0006zZ-GV for libunwind-devel@nongnu.org; Fri, 23 Mar 2012 16:00:46 -0400 Received: from mx1.redhat.com ([209.132.183.28]:49536) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SBAfE-0006yz-4O for libunwind-devel@nongnu.org; Fri, 23 Mar 2012 16:00:44 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q2NK0gse027921 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 23 Mar 2012 16:00:42 -0400 Received: from localhost.localdomain (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q2NK0YS2003055; Fri, 23 Mar 2012 16:00:42 -0400 From: Alexander Larsson To: libunwind-devel@nongnu.org Date: Fri, 23 Mar 2012 21:00:29 +0100 Message-Id: <1332532830-9327-4-git-send-email-alexl@redhat.com> In-Reply-To: <1332532830-9327-1-git-send-email-alexl@redhat.com> References: <1332532830-9327-1-git-send-email-alexl@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Subject: [Libunwind-devel] [PATCH 3/4] Break out the ifdefs for the UCD_info.prstatus type X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 23 Mar 2012 20:00:48 -0000 This cleans up the code a bit and makes it easier to refer to the prstatus type in other places. --- src/coredump/_UCD_internal.h | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/coredump/_UCD_internal.h b/src/coredump/_UCD_internal.h index 82ffa66..ecad0bd 100644 --- a/src/coredump/_UCD_internal.h +++ b/src/coredump/_UCD_internal.h @@ -74,6 +74,13 @@ struct coredump_phdr typedef struct coredump_phdr coredump_phdr_t; +#if defined(HAVE_STRUCT_ELF_PRSTATUS) +#define PRSTATUS_STRUCT elf_prstatus +#elif defined(HAVE_STRUCT_PRSTATUS) +#define PRSTATUS_STRUCT prstatus +#else +#define PRSTATUS_STRUCT non_existent +#endif struct UCD_info { @@ -83,13 +90,7 @@ struct UCD_info coredump_phdr_t *phdrs; /* array, allocated */ unsigned phdrs_count; void *note_phdr; /* allocated or NULL */ -#if defined(HAVE_STRUCT_ELF_PRSTATUS) - struct elf_prstatus *prstatus; /* points inside note_phdr */ -#elif defined(HAVE_STRUCT_PRSTATUS) - struct prstatus *prstatus; /* points inside note_phdr */ -#else - struct non_existent *prstatus; -#endif + struct PRSTATUS_STRUCT *prstatus; /* points inside note_phdr */ struct elf_dyn_info edi; }; -- 1.7.7.6 From MAILER-DAEMON Fri Mar 23 16:00:51 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1SBAfL-0007Fp-MI for mharc-libunwind-devel@gnu.org; Fri, 23 Mar 2012 16:00:51 -0400 Received: from eggs.gnu.org ([208.118.235.92]:33253) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SBAfI-00076I-1S for libunwind-devel@nongnu.org; Fri, 23 Mar 2012 16:00:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SBAfF-0006zt-UL for libunwind-devel@nongnu.org; Fri, 23 Mar 2012 16:00:47 -0400 Received: from mx1.redhat.com ([209.132.183.28]:36817) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SBAfF-0006zd-LH for libunwind-devel@nongnu.org; Fri, 23 Mar 2012 16:00:45 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q2NK0iKw004423 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 23 Mar 2012 16:00:44 -0400 Received: from localhost.localdomain (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q2NK0YS3003055; Fri, 23 Mar 2012 16:00:43 -0400 From: Alexander Larsson To: libunwind-devel@nongnu.org Date: Fri, 23 Mar 2012 21:00:30 +0100 Message-Id: <1332532830-9327-5-git-send-email-alexl@redhat.com> In-Reply-To: <1332532830-9327-1-git-send-email-alexl@redhat.com> References: <1332532830-9327-1-git-send-email-alexl@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Subject: [Libunwind-devel] [PATCH 4/4] Add support for multiple threads in core files X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 23 Mar 2012 20:00:49 -0000 _UCD_select_thread() lets you select the active thread from the core file and _UCD_get_num_threads() tells you how many there are. --- include/libunwind-coredump.h | 2 + src/coredump/_UCD_create.c | 83 ++++++++++++++++++++++++++++-------------- src/coredump/_UCD_internal.h | 2 + 3 files changed, 60 insertions(+), 27 deletions(-) diff --git a/include/libunwind-coredump.h b/include/libunwind-coredump.h index a44536f..d2b05e7 100644 --- a/include/libunwind-coredump.h +++ b/include/libunwind-coredump.h @@ -40,6 +40,8 @@ struct UCD_info; extern struct UCD_info *_UCD_create(const char *filename); extern void _UCD_destroy(struct UCD_info *); +extern int _UCD_get_num_threads(struct UCD_info *); +extern void _UCD_select_thread(struct UCD_info *, int); extern pid_t _UCD_get_pid(struct UCD_info *); extern int _UCD_get_cursig(struct UCD_info *); extern int _UCD_add_backing_file_at_segment(struct UCD_info *, int phdr_no, const char *filename); diff --git a/src/coredump/_UCD_create.c b/src/coredump/_UCD_create.c index ec0dfb5..02df5e5 100644 --- a/src/coredump/_UCD_create.c +++ b/src/coredump/_UCD_create.c @@ -206,6 +206,9 @@ _UCD_create(const char *filename) Debug(2, "phdr[%03d]: type:%d", i, cur->p_type); if (cur->p_type == PT_NOTE) { + unsigned char *p, *note_end; + unsigned n_threads; + ui->note_phdr = malloc(cur->p_filesz); if (lseek(fd, cur->p_offset, SEEK_SET) != (off_t)cur->p_offset || (uoff_t)read(fd, ui->note_phdr, cur->p_filesz) != cur->p_filesz @@ -215,33 +218,46 @@ _UCD_create(const char *filename) goto err; } - /* Note is three 32-bit words: */ - /* Elf32_Word n_namesz; Length of the note's name */ - /* Elf32_Word n_descsz; Length of the note's descriptor */ - /* Elf32_Word n_type; Type */ - /* followed by name (padded to 32 bits(?)) and then descr */ - Elf32_Nhdr *note_hdr = ui->note_phdr; - if (cur->p_filesz >= 3*4 - && note_hdr->n_type == NT_PRSTATUS - && cur->p_filesz >= (3*4 + note_hdr->n_namesz + note_hdr->n_descsz + sizeof(*ui->prstatus)) - ) + note_end = (unsigned char *)ui->note_phdr + cur->p_filesz; + + /* Count number of threads */ + n_threads = 0; + p = ui->note_phdr; + while (p + sizeof (Elf32_Nhdr) <= note_end) { - ui->prstatus = (void*) ((((long)note_hdr + sizeof(*note_hdr) + note_hdr->n_namesz) + 3) & ~3L); -#if 0 - printf("pid:%d\n", ui->prstatus->pr_pid); - printf("ebx:%ld\n", (long)ui->prstatus->pr_reg[0]); - printf("ecx:%ld\n", (long)ui->prstatus->pr_reg[1]); - printf("edx:%ld\n", (long)ui->prstatus->pr_reg[2]); - printf("esi:%ld\n", (long)ui->prstatus->pr_reg[3]); - printf("edi:%ld\n", (long)ui->prstatus->pr_reg[4]); - printf("ebp:%ld\n", (long)ui->prstatus->pr_reg[5]); - printf("eax:%ld\n", (long)ui->prstatus->pr_reg[6]); - printf("xds:%ld\n", (long)ui->prstatus->pr_reg[7]); - printf("xes:%ld\n", (long)ui->prstatus->pr_reg[8]); - printf("xfs:%ld\n", (long)ui->prstatus->pr_reg[9]); - printf("xgs:%ld\n", (long)ui->prstatus->pr_reg[10]); - printf("orig_eax:%ld\n", (long)ui->prstatus->pr_reg[11]); -#endif + Elf32_Nhdr *note_hdr = (Elf32_Nhdr *)p; + unsigned char *p_next; + + p_next = p + sizeof (Elf32_Nhdr) + ((note_hdr->n_namesz + 3) & ~3L) + note_hdr->n_descsz; + + if (p_next >= note_end) + break; + + if (note_hdr->n_type == NT_PRSTATUS) + n_threads++; + + p = p_next; + } + + ui->n_threads = n_threads; + ui->threads = malloc(sizeof (void *) * n_threads); + + n_threads = 0; + p = ui->note_phdr; + while (p + sizeof (Elf32_Nhdr) <= note_end) + { + Elf32_Nhdr *note_hdr = (Elf32_Nhdr *)p; + unsigned char *p_next; + + p_next = p + sizeof (Elf32_Nhdr) + ((note_hdr->n_namesz + 3) & ~3L) + note_hdr->n_descsz; + + if (p_next >= note_end) + break; + + if (note_hdr->n_type == NT_PRSTATUS) + ui->threads[n_threads++] = (void*) ((((long)note_hdr + sizeof(*note_hdr) + note_hdr->n_namesz) + 3) & ~3L); + + p = p_next; } } if (cur->p_type == PT_LOAD) @@ -263,12 +279,14 @@ _UCD_create(const char *filename) cur++; } - if (!ui->prstatus) + if (ui->n_threads == 0) { Debug(0, "No NT_PRSTATUS note found in '%s'\n", filename); goto err; } + ui->prstatus = ui->threads[0]; + return ui; err: @@ -276,6 +294,17 @@ _UCD_create(const char *filename) return NULL; } +int _UCD_get_num_threads(struct UCD_info *ui) +{ + return ui->n_threads; +} + +void _UCD_select_thread(struct UCD_info *ui, int n) +{ + if (n >= 0 && n < ui->n_threads) + ui->prstatus = ui->threads[n]; +} + pid_t _UCD_get_pid(struct UCD_info *ui) { return ui->prstatus->pr_pid; diff --git a/src/coredump/_UCD_internal.h b/src/coredump/_UCD_internal.h index ecad0bd..8b36729 100644 --- a/src/coredump/_UCD_internal.h +++ b/src/coredump/_UCD_internal.h @@ -91,6 +91,8 @@ struct UCD_info unsigned phdrs_count; void *note_phdr; /* allocated or NULL */ struct PRSTATUS_STRUCT *prstatus; /* points inside note_phdr */ + int n_threads; + struct PRSTATUS_STRUCT **threads; struct elf_dyn_info edi; }; -- 1.7.7.6 From MAILER-DAEMON Fri Mar 23 16:00:48 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1SBAfI-00076b-ET for mharc-libunwind-devel@gnu.org; Fri, 23 Mar 2012 16:00:48 -0400 Received: from eggs.gnu.org ([208.118.235.92]:33221) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SBAfF-00072p-L1 for libunwind-devel@nongnu.org; Fri, 23 Mar 2012 16:00:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SBAfD-0006yv-1X for libunwind-devel@nongnu.org; Fri, 23 Mar 2012 16:00:45 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45302) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SBAfC-0006yj-PB for libunwind-devel@nongnu.org; Fri, 23 Mar 2012 16:00:42 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q2NK0ffv010481 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 23 Mar 2012 16:00:41 -0400 Received: from localhost.localdomain (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q2NK0YS1003055; Fri, 23 Mar 2012 16:00:40 -0400 From: Alexander Larsson To: libunwind-devel@nongnu.org Date: Fri, 23 Mar 2012 21:00:28 +0100 Message-Id: <1332532830-9327-3-git-send-email-alexl@redhat.com> In-Reply-To: <1332532830-9327-1-git-send-email-alexl@redhat.com> References: <1332532830-9327-1-git-send-email-alexl@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Subject: [Libunwind-devel] [PATCH 2/4] Add _UCD_get_pid and _UCD_get_cursig X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 23 Mar 2012 20:00:47 -0000 These let you get the pid and the current signal from the coredump. This isn't strictly unwind related, but these are trivial to implement as we have the info, and you almost always want these when you're printing a backtrace from a core file. --- include/libunwind-coredump.h | 2 ++ src/coredump/_UCD_create.c | 10 ++++++++++ 2 files changed, 12 insertions(+), 0 deletions(-) diff --git a/include/libunwind-coredump.h b/include/libunwind-coredump.h index 3838549..a44536f 100644 --- a/include/libunwind-coredump.h +++ b/include/libunwind-coredump.h @@ -40,6 +40,8 @@ struct UCD_info; extern struct UCD_info *_UCD_create(const char *filename); extern void _UCD_destroy(struct UCD_info *); +extern pid_t _UCD_get_pid(struct UCD_info *); +extern int _UCD_get_cursig(struct UCD_info *); extern int _UCD_add_backing_file_at_segment(struct UCD_info *, int phdr_no, const char *filename); extern int _UCD_add_backing_file_at_vaddr(struct UCD_info *, unsigned long vaddr, diff --git a/src/coredump/_UCD_create.c b/src/coredump/_UCD_create.c index 00117f3..ec0dfb5 100644 --- a/src/coredump/_UCD_create.c +++ b/src/coredump/_UCD_create.c @@ -276,6 +276,16 @@ _UCD_create(const char *filename) return NULL; } +pid_t _UCD_get_pid(struct UCD_info *ui) +{ + return ui->prstatus->pr_pid; +} + +int _UCD_get_cursig(struct UCD_info *ui) +{ + return ui->prstatus->pr_cursig; +} + int _UCD_add_backing_file_at_segment(struct UCD_info *ui, int phdr_no, const char *filename) { if ((unsigned)phdr_no >= ui->phdrs_count) -- 1.7.7.6 From MAILER-DAEMON Sat Mar 24 01:39:17 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1SBJh7-0000IA-Gn for mharc-libunwind-devel@gnu.org; Sat, 24 Mar 2012 01:39:17 -0400 Received: from eggs.gnu.org ([208.118.235.92]:45262) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SBJh4-0000I3-QM for libunwind-devel@nongnu.org; Sat, 24 Mar 2012 01:39:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SBJh3-0003oS-5k for libunwind-devel@nongnu.org; Sat, 24 Mar 2012 01:39:14 -0400 Received: from mail-qa0-f45.google.com ([209.85.216.45]:35682) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SBJh2-0003o6-VE for libunwind-devel@nongnu.org; Sat, 24 Mar 2012 01:39:13 -0400 Received: by qafi31 with SMTP id i31so1308706qaf.4 for ; Fri, 23 Mar 2012 22:39:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type :content-transfer-encoding; bh=qGxZYNxz7A/IzKKsR5XbZ9l3MaTEzq+VKoBOWLewtds=; b=QaHvD+VXbx9DG55FjDQHdlBaRr4BA7nktaj8gSj9ztTKOd9Gd6j/h1pUkCGQjVNdi6 qyTVHo+PpXVpxIjAGK4oZAI6LTlsW1iF7PISVmFhdrl9K8sCluWhwHGaLzcvKyks2sM0 Xp4ghfh4/FK70ZVUO6xU9VGwTAP9F8x7wLUsAwtHzgOK3Pof4MzGDfUp+xSxdBks46CJ TrATTTWWc2sDKsJI1OoVq4GrNOcWn5ggp4fWncDI3hL9Tl7WkTeJAWq0wEi8hMOAax6v SbJv6SCSlvkRJU/BZoxDBjUudDP9+mYNuGbTV7nhzi8FHjgG4nzn047VKtxuej7+10u7 6uOA== MIME-Version: 1.0 Received: by 10.229.114.213 with SMTP id f21mr5548517qcq.15.1332567550139; Fri, 23 Mar 2012 22:39:10 -0700 (PDT) Sender: arun.sharma@gmail.com Received: by 10.229.134.196 with HTTP; Fri, 23 Mar 2012 22:39:10 -0700 (PDT) In-Reply-To: <1332532830-9327-5-git-send-email-alexl@redhat.com> References: <1332532830-9327-1-git-send-email-alexl@redhat.com> <1332532830-9327-5-git-send-email-alexl@redhat.com> Date: Fri, 23 Mar 2012 22:39:10 -0700 X-Google-Sender-Auth: R-6DSoZp6PrHdAd_l1SIhKxJoDs Message-ID: From: Arun Sharma To: Alexander Larsson Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.216.45 Cc: libunwind-devel@nongnu.org Subject: Re: [Libunwind-devel] [PATCH 4/4] Add support for multiple threads in core files X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 24 Mar 2012 05:39:16 -0000 I pushed this patch series with some whitespace cleanup to the github branch. Please use 2 spaces instead of tabs like the rest of the code. On Fri, Mar 23, 2012 at 1:00 PM, Alexander Larsson wrote= : > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* Count number of threads */ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 n_threads =3D 0; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 p =3D ui->note_phdr; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 while (p + sizeof (Elf32_Nhdr) <=3D = note_end) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ The two while loops look redundant. May be write a for_each() type macro to eliminate redundant code. > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ui->prstatus =3D (void= *) ((((long)note_hdr + sizeof(*note_hdr) + note_hdr->n_namesz) + 3) & ~3L); And use a ALIGN() macro instead of the explicit arithmetic here. -Arun From MAILER-DAEMON Sat Mar 24 18:31:57 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1SBZV7-0004sg-Ki for mharc-libunwind-devel@gnu.org; Sat, 24 Mar 2012 18:31:57 -0400 Received: from eggs.gnu.org ([208.118.235.92]:37988) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SBZV4-0004sK-Vz for libunwind-devel@nongnu.org; Sat, 24 Mar 2012 18:31:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SBZV3-00034y-6u for libunwind-devel@nongnu.org; Sat, 24 Mar 2012 18:31:54 -0400 Received: from mail-qa0-f45.google.com ([209.85.216.45]:36606) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SBZV2-00034h-W8 for libunwind-devel@nongnu.org; Sat, 24 Mar 2012 18:31:53 -0400 Received: by qafi31 with SMTP id i31so1531697qaf.4 for ; Sat, 24 Mar 2012 15:31:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type :content-transfer-encoding; bh=myJuisFF9n/0uxUJu+Pd3w+sqwQ5C3pAf/hnQ9JZoRs=; b=0ZxtJ0RfCvxVuUQbVhyGecVEQhVN303DSIc6KL1HVZdixNoA+LnuxjLeBnwtSWjCBs ZKb/je/LZjdHJimGBKMNduLyIEzwbWWC85ReoiKxlTiElnSI+EhhWI6kW++o8/sdaj33 L7JHSbc/6nnBEWPancoH3Zd08jQOXCu0sUBVLRkOLLKmCYAclk9Uw+2GWlyrUjNAstl5 h1TiP1jJpE6iKSlqww+malQla9VNrElWMA0A0T6VcocjxC4VBzpa56zsahlr37K8cdiL MFoFZ23ICpHCV383de7uKvNmvCeLlYHD/MLKm1dGo2OAaIlupLxjmRVxA6hGFhL1523B p+pw== MIME-Version: 1.0 Received: by 10.229.114.213 with SMTP id f21mr6367226qcq.15.1332628311061; Sat, 24 Mar 2012 15:31:51 -0700 (PDT) Sender: arun.sharma@gmail.com Received: by 10.229.36.21 with HTTP; Sat, 24 Mar 2012 15:31:50 -0700 (PDT) In-Reply-To: <4F6337E7.2080105@redhat.com> References: <4F4BA6FD.6000503@redhat.com> <4F4BA743.4030405@redhat.com> <4F57579B.5060003@redhat.com> <4F622D73.7050400@redhat.com> <4F6337E7.2080105@redhat.com> Date: Sat, 24 Mar 2012 15:31:50 -0700 X-Google-Sender-Auth: NKlwpFNe552PwY5vm4m5auYqjX4 Message-ID: From: Arun Sharma To: Denys Vlasenko Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.216.45 Cc: Karel Klic , Jiri Moskovcak , mtoman@redhat.com, Petr Machata , libunwind-devel@nongnu.org, Jan Kratochvil Subject: Re: [Libunwind-devel] [PATCHv3 1/4] Add core dump unwinding support to libunwind X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 24 Mar 2012 22:31:56 -0000 On Fri, Mar 16, 2012 at 5:53 AM, Denys Vlasenko wrote= : > I want this code to end up in libunwind.so instead, > so we can use it equally from both libs. > > Our predicament seems to be that we have no good > place to put its source in the source tree, right? > > drwxr-xr-x. 2 root root =C2=A04096 Feb 13 18:43 arm > drwxr-xr-x. 2 root root =C2=A04096 Feb 13 18:43 hppa > drwxr-xr-x. 2 root root =C2=A04096 Feb 13 18:43 ia64 > drwxr-xr-x. 2 root root =C2=A04096 Feb 13 18:43 mi > drwxr-xr-x. 2 root root =C2=A04096 Feb 13 18:43 mips > drwxr-xr-x. 2 root root =C2=A04096 Feb 13 18:43 ppc > drwxr-xr-x. 2 root root =C2=A04096 Feb 13 18:43 ppc32 > drwxr-xr-x. 2 root root =C2=A04096 Feb 13 18:43 ppc64 > drwxr-xr-x. 2 root root =C2=A04096 Feb 13 18:43 x86 > drwxr-xr-x. 2 root root =C2=A04096 Feb 13 18:43 x86_64 > > The above dirs are arch specific - not suitable. The code is also ia64 specific. I don't have any objections to putting it under ia64. > drwxr-xr-x. 2 root root =C2=A04096 Feb 13 18:43 unwind > > Can we put it into this dir? That dir is for C++ ABI support. We shouldn't move it there. Re: common There is also a dir called "mi" (machine independent). But this is arch specific code, so we shouldn't move it there. If runtime dependency between different components of libunwind*.a is a concern, you can statically link object files into libunwind-coredump.a with some Makefile hackery. -Arun From MAILER-DAEMON Sun Mar 25 21:52:55 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1SBz79-0005GR-Dk for mharc-libunwind-devel@gnu.org; Sun, 25 Mar 2012 21:52:55 -0400 Received: from eggs.gnu.org ([208.118.235.92]:32877) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SBz76-0005G7-Uy for libunwind-devel@nongnu.org; Sun, 25 Mar 2012 21:52:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SBz75-0005m3-5P for libunwind-devel@nongnu.org; Sun, 25 Mar 2012 21:52:52 -0400 Received: from mail-qc0-f173.google.com ([209.85.216.173]:58060) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SBz74-0005lh-UE for libunwind-devel@nongnu.org; Sun, 25 Mar 2012 21:52:51 -0400 Received: by qcsc20 with SMTP id c20so3164894qcs.4 for ; Sun, 25 Mar 2012 18:52:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type; bh=EhCFcnvDQdq1C34yYpaEDI2pLjsLMlIpKDMFb/9rpMs=; b=CtKubeoJvG5Qv0bqOTeFSCdoSXpoixWjD9RbHTgNgrIGl02Gl9P3HyidAtEW2A8MLR /p3GiEfIJskRt2ji/X0C0jOTqz+0ZgQJjyygsuUhiIAFJZ73wi1knDGCZ/4knzXvbTPo GWhU7D9jOB6WOuMyNfKzHQ8FuPrpnIUq45qtJukwd5HKLiUtk/smUhj20JdXHmDwyfPv c7OF1MgaIc8OroUgswnhrkM1a2eRviaJCMNPWN9J/b/qgDJ0oG+gkmO+VcLg/d3oDtt0 Q4O3in/G/dTCJhHMczhIsmDhdVfgLAw64yBLghkvsRw0xEiz5OyUwaIB1/+arnhPsRu6 ltXQ== MIME-Version: 1.0 Received: by 10.229.112.14 with SMTP id u14mr7591439qcp.75.1332726767950; Sun, 25 Mar 2012 18:52:47 -0700 (PDT) Sender: arun.sharma@gmail.com Received: by 10.229.36.21 with HTTP; Sun, 25 Mar 2012 18:52:47 -0700 (PDT) In-Reply-To: References: Date: Sun, 25 Mar 2012 18:52:47 -0700 X-Google-Sender-Auth: vpDWN74s9m7D55c7r-e4EHpSwa8 Message-ID: From: Arun Sharma To: Prabhat Verma Content-Type: text/plain; charset=UTF-8 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.216.173 Cc: "libunwind-devel@nongnu.org" Subject: Re: [Libunwind-devel] Libunwind support for NULL IP X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 26 Mar 2012 01:52:54 -0000 On Fri, Mar 16, 2012 at 8:55 AM, Prabhat Verma wrote: > We are trying to replace backtrace with libunwind (local unwinding) for our > diagnostic purposes. A major motivation behind this decision was the > inability of backtrace to handle stack frames containing NULL IP. In our > case, this may happen if someone ends up doing this: I pushed a few changes to the git repo. Could you please try them to see if things work better for you? In short: dwarf says NULL RBP is the end of the callchain. But libunwind was terminating unwind on NULL RIP as well. In the process I seem to have introduced a test failure (run-ptrace-misc used to pass earlier). I'll dig into it when I get a chance. On the face of it, it looks like unwinding from (ip == 0) used to succeed earlier, but it fails now (due to lack of unwind info?). -Arun From MAILER-DAEMON Mon Mar 26 05:18:44 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1SC64a-0000iH-Ly for mharc-libunwind-devel@gnu.org; Mon, 26 Mar 2012 05:18:44 -0400 Received: from eggs.gnu.org ([208.118.235.92]:43463) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SC64T-0000hH-8u for libunwind-devel@nongnu.org; Mon, 26 Mar 2012 05:18:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SC64R-0007BD-Eb for libunwind-devel@nongnu.org; Mon, 26 Mar 2012 05:18:36 -0400 Received: from mx1.redhat.com ([209.132.183.28]:19305) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SC64R-0007At-70 for libunwind-devel@nongnu.org; Mon, 26 Mar 2012 05:18:35 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q2Q9IWUT007491 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 26 Mar 2012 05:18:33 -0400 Received: from localhost.localdomain (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q2Q9IVsq030379; Mon, 26 Mar 2012 05:18:32 -0400 From: Alexander Larsson To: libunwind-devel@nongnu.org Date: Mon, 26 Mar 2012 11:18:21 +0200 Message-Id: <1332753503-11943-1-git-send-email-alexl@redhat.com> In-Reply-To: References: X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Subject: [Libunwind-devel] [PATCH 0/2] Clean up notes handling in the corefile parser X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 26 Mar 2012 09:18:43 -0000 This uses macros for ALIGN and avoids code duplication. Alexander Larsson (2): Add helper macros for pointer arithmetics Clean up the elf notes handling in the coredump code include/libunwind_i.h | 3 ++ src/coredump/_UCD_create.c | 45 ++++++++++++++----------------------------- 2 files changed, 18 insertions(+), 30 deletions(-) -- 1.7.7.6 From MAILER-DAEMON Mon Mar 26 05:18:45 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1SC64b-0000kJ-Oc for mharc-libunwind-devel@gnu.org; Mon, 26 Mar 2012 05:18:45 -0400 Received: from eggs.gnu.org ([208.118.235.92]:43467) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SC64U-0000hK-0v for libunwind-devel@nongnu.org; Mon, 26 Mar 2012 05:18:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SC64S-0007BM-9N for libunwind-devel@nongnu.org; Mon, 26 Mar 2012 05:18:37 -0400 Received: from mx1.redhat.com ([209.132.183.28]:50085) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SC64S-0007B7-1D for libunwind-devel@nongnu.org; Mon, 26 Mar 2012 05:18:36 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q2Q9IYqv016446 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 26 Mar 2012 05:18:34 -0400 Received: from localhost.localdomain (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q2Q9IVsr030379; Mon, 26 Mar 2012 05:18:34 -0400 From: Alexander Larsson To: libunwind-devel@nongnu.org Date: Mon, 26 Mar 2012 11:18:22 +0200 Message-Id: <1332753503-11943-2-git-send-email-alexl@redhat.com> In-Reply-To: <1332753503-11943-1-git-send-email-alexl@redhat.com> References: <1332753503-11943-1-git-send-email-alexl@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Subject: [Libunwind-devel] [PATCH 1/2] Add helper macros for pointer arithmetics X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 26 Mar 2012 09:18:44 -0000 ALIGN lets you align pointers and STRUCT_MEMBER lets you get structure members at a specific offset. These are useful in general, and will be needed for the coredump notes cleanup work. --- include/libunwind_i.h | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/include/libunwind_i.h b/include/libunwind_i.h index 2ece7f0..f769b13 100644 --- a/include/libunwind_i.h +++ b/include/libunwind_i.h @@ -108,6 +108,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #endif #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) +#define ALIGN(x,a) (((x)+(a)-1UL)&~((a)-1UL)) +#define STRUCT_MEMBER_P(struct_p, struct_offset) ((void *) ((char*) (struct_p) + (long) (struct_offset))) +#define STRUCT_MEMBER(member_type, struct_p, struct_offset) (*(member_type*) STRUCT_MEMBER_P ((struct_p), (struct_offset))) /* Make it easy to write thread-safe code which may or may not be linked against libpthread. The macros below can be used -- 1.7.7.6 From MAILER-DAEMON Mon Mar 26 05:18:52 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1SC64i-0000o8-Rq for mharc-libunwind-devel@gnu.org; Mon, 26 Mar 2012 05:18:52 -0400 Received: from eggs.gnu.org ([208.118.235.92]:43490) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SC64b-0000jb-IJ for libunwind-devel@nongnu.org; Mon, 26 Mar 2012 05:18:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SC64U-0007C3-LD for libunwind-devel@nongnu.org; Mon, 26 Mar 2012 05:18:45 -0400 Received: from mx1.redhat.com ([209.132.183.28]:6901) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SC64U-0007Ba-DF for libunwind-devel@nongnu.org; Mon, 26 Mar 2012 05:18:38 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q2Q9Ib12016456 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 26 Mar 2012 05:18:37 -0400 Received: from localhost.localdomain (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q2Q9IVss030379; Mon, 26 Mar 2012 05:18:36 -0400 From: Alexander Larsson To: libunwind-devel@nongnu.org Date: Mon, 26 Mar 2012 11:18:23 +0200 Message-Id: <1332753503-11943-3-git-send-email-alexl@redhat.com> In-Reply-To: <1332753503-11943-1-git-send-email-alexl@redhat.com> References: <1332753503-11943-1-git-send-email-alexl@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Subject: [Libunwind-devel] [PATCH 2/2] Clean up the elf notes handling in the coredump code X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 26 Mar 2012 09:18:51 -0000 We centralize the elf notes handling code in some macros, thus simplifying the loops over the notes and avoiding code duplication. --- src/coredump/_UCD_create.c | 45 ++++++++++++++----------------------------- 1 files changed, 15 insertions(+), 30 deletions(-) diff --git a/src/coredump/_UCD_create.c b/src/coredump/_UCD_create.c index 4991e27..0f791af 100644 --- a/src/coredump/_UCD_create.c +++ b/src/coredump/_UCD_create.c @@ -66,6 +66,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "_UCD_lib.h" #include "_UCD_internal.h" +#define NOTE_DATA(_hdr) STRUCT_MEMBER_P((_hdr), sizeof (Elf32_Nhdr) + ALIGN((_hdr)->n_namesz, 4)) +#define NOTE_SIZE(_hdr) (sizeof (Elf32_Nhdr) + ALIGN((_hdr)->n_namesz, 4) + (_hdr)->n_descsz) +#define NOTE_NEXT(_hdr) STRUCT_MEMBER_P((_hdr), NOTE_SIZE(_hdr)) +#define NOTE_FITS_IN(_hdr, _size) ((_size) >= sizeof (Elf32_Nhdr) && (_size) >= NOTE_SIZE (_hdr)) +#define NOTE_FITS(_hdr, _end) NOTE_FITS_IN((_hdr), (unsigned long)((char *)(_end) - (char *)(_hdr))) + struct UCD_info * _UCD_create(const char *filename) { @@ -206,7 +212,7 @@ _UCD_create(const char *filename) Debug(2, "phdr[%03d]: type:%d", i, cur->p_type); if (cur->p_type == PT_NOTE) { - unsigned char *p, *note_end; + Elf32_Nhdr *note_hdr, *note_end; unsigned n_threads; ui->note_phdr = malloc(cur->p_filesz); @@ -217,51 +223,30 @@ _UCD_create(const char *filename) goto err; } - note_end = (unsigned char *)ui->note_phdr + cur->p_filesz; + note_end = STRUCT_MEMBER_P (ui->note_phdr, cur->p_filesz); /* Count number of threads */ n_threads = 0; - p = ui->note_phdr; - while (p + sizeof (Elf32_Nhdr) <= note_end) + note_hdr = (Elf32_Nhdr *)ui->note_phdr; + while (NOTE_FITS (note_hdr, note_end)) { - Elf32_Nhdr *note_hdr = (Elf32_Nhdr *)p; - unsigned char *p_next; - - p_next = p + sizeof (Elf32_Nhdr) - + ((note_hdr->n_namesz + 3) & ~3L) - + note_hdr->n_descsz; - - if (p_next >= note_end) - break; - if (note_hdr->n_type == NT_PRSTATUS) n_threads++; - p = p_next; + note_hdr = NOTE_NEXT (note_hdr); } ui->n_threads = n_threads; ui->threads = malloc(sizeof (void *) * n_threads); n_threads = 0; - p = ui->note_phdr; - while (p + sizeof (Elf32_Nhdr) <= note_end) + note_hdr = (Elf32_Nhdr *)ui->note_phdr; + while (NOTE_FITS (note_hdr, note_end)) { - Elf32_Nhdr *note_hdr = (Elf32_Nhdr *)p; - unsigned char *p_next; - - p_next = p + sizeof (Elf32_Nhdr) - + ((note_hdr->n_namesz + 3) & ~3L) - + note_hdr->n_descsz; - - if (p_next >= note_end) - break; - if (note_hdr->n_type == NT_PRSTATUS) - ui->threads[n_threads++] = (void*) ((((long)note_hdr - + sizeof(*note_hdr) + note_hdr->n_namesz) + 3) & ~3L); + ui->threads[n_threads++] = NOTE_DATA (note_hdr); - p = p_next; + note_hdr = NOTE_NEXT (note_hdr); } } if (cur->p_type == PT_LOAD) -- 1.7.7.6 From MAILER-DAEMON Mon Mar 26 19:36:31 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1SCJSh-0007h6-24 for mharc-libunwind-devel@gnu.org; Mon, 26 Mar 2012 19:36:31 -0400 Received: from eggs.gnu.org ([208.118.235.92]:58322) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SCJSd-0007fg-F4 for libunwind-devel@nongnu.org; Mon, 26 Mar 2012 19:36:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SCJSb-0007lV-Kw for libunwind-devel@nongnu.org; Mon, 26 Mar 2012 19:36:27 -0400 Received: from rock.gnat.com ([205.232.38.15]:46396) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SCJSb-0007kD-Ga for libunwind-devel@nongnu.org; Mon, 26 Mar 2012 19:36:25 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id B81981C6856; Mon, 26 Mar 2012 19:36:12 -0400 (EDT) X-Virus-Scanned: Debian amavisd-new at gnat.com 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 5PpvOw79FNDZ; Mon, 26 Mar 2012 19:36:12 -0400 (EDT) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 5864B1C6854; Mon, 26 Mar 2012 19:36:12 -0400 (EDT) Received: by joel.gnat.com (Postfix, from userid 1000) id A8AFB145616; Mon, 26 Mar 2012 16:36:08 -0700 (PDT) From: Joel Brobecker To: libunwind-devel@nongnu.org Date: Mon, 26 Mar 2012 16:36:05 -0700 Message-Id: <1332804965-16613-1-git-send-email-brobecker@adacore.com> X-Mailer: git-send-email 1.7.1 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 205.232.38.15 Subject: [Libunwind-devel] [PATCH] dangling pointer in ia64/Gtables.c:unw_search_ia64_unwind_table X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 26 Mar 2012 23:36:28 -0000 Hello, We noticed the following problem after we started building libunwind (version 0.98.5) with GCC 4.7. What happens is that unw_search_ia64_unwind_table uses remote_lookup to search a libunwind entry, and stores the result into a variable defined locally; When the lookup succeeds, it then saves a reference to that local in a variable whose scope is more global, thus creating a dangling reference as soon as we leave the local variable's scope: else { struct ia64_table_entry ent; segbase = di->u.rti.segbase; if ((ret = remote_lookup (as, di->u.rti.table_data, di->u.rti.table_len * sizeof (unw_word_t), ip - segbase, &ent, arg)) < 0) return ret; if (ret) e = &ent; } [...] pi->start_ip = e->start_offset + segbase; pi->end_ip = e->end_offset + segbase; It's been working so far, but some changes in GCC's optimizer now make it inline the call to remote_lookup and then optimize out the tail end of that function where it was supposed to set the "info_offset" field of our struct ia64_table_entry. The following patch was only tested with libunwin 0.98.5, but applied almost cleanly on the HEAD, and it seems pretty clear that HEAD also suffers from the same problem. I would test it further on the head, but I haven't been able to fix the last build issue I had on ia64-hpux (mentioned when I sent the my previous series of patches). src/ia64: * Gtables.c (unw_search_ia64_unwind_table): Move declaration of variable "ent" outside of "else" block to avoid having a dangling reference to an out-of-scope local. --- src/ia64/Gtables.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/src/ia64/Gtables.c b/src/ia64/Gtables.c index 1a16a2e..5ed72f0 100644 --- a/src/ia64/Gtables.c +++ b/src/ia64/Gtables.c @@ -255,6 +255,7 @@ unw_search_ia64_unwind_table (unw_addr_space_t as, unw_word_t ip, unw_word_t addr, hdr_addr, info_addr, info_end_addr, hdr, *wp; const struct ia64_table_entry *e = NULL; unw_word_t handler_offset, segbase = 0; + struct ia64_table_entry ent; int ret, is_local; assert ((di->format == UNW_INFO_FORMAT_TABLE @@ -275,8 +276,6 @@ unw_search_ia64_unwind_table (unw_addr_space_t as, unw_word_t ip, #ifndef UNW_LOCAL_ONLY else { - struct ia64_table_entry ent; - segbase = di->u.rti.segbase; if ((ret = remote_lookup (as, di->u.rti.table_data, di->u.rti.table_len * sizeof (unw_word_t), -- 1.7.1 From MAILER-DAEMON Mon Mar 26 21:57:04 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1SCLei-0001Go-Bp for mharc-libunwind-devel@gnu.org; Mon, 26 Mar 2012 21:57:04 -0400 Received: from eggs.gnu.org ([208.118.235.92]:60379) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SCLef-0001GA-IE for libunwind-devel@nongnu.org; Mon, 26 Mar 2012 21:57:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SCLed-0004H0-PD for libunwind-devel@nongnu.org; Mon, 26 Mar 2012 21:57:01 -0400 Received: from mail-qc0-f173.google.com ([209.85.216.173]:43150) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SCLed-0004Em-Ir for libunwind-devel@nongnu.org; Mon, 26 Mar 2012 21:56:59 -0400 Received: by qcsc20 with SMTP id c20so3868014qcs.4 for ; Mon, 26 Mar 2012 18:56:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type; bh=EJGRgNnhzRr56+kcMRB8Tn4vdXRVV7A8y2ze6gjMz74=; b=kxsY9iMSRe0Cukf3tZaqEQsU5JPL+i5FTGIsHuSFmdNbkxbvQs21eBrLJcltqr6rWq uNaMnHybUCU+9Dz5E6MqHYJDoFkCxIQ63znq8Ij0ognZGfbR6oKvD1Ks6Q6GSLdDFrQ8 dmPhRt0kfza+tJFruyY7LjW9ZsFb/1k+c7+LkUUzVFeHoUYjHqbxZRj01k2uU0T2dCvl IhspbHmZU5f1N5uKoGQuWpPmKnJ2IjVy5d2VOxX07nEpEjx0eGW2ETEdEHjhMB7HiSNF 7aTSu9nr4GYI5waHH2h0Yo/KXkDpfn4NPcSIQtV33qVOFCBBB/eyAsK3YQsXO3Kre3Cs Hbaw== MIME-Version: 1.0 Received: by 10.229.136.208 with SMTP id s16mr9101525qct.35.1332813416818; Mon, 26 Mar 2012 18:56:56 -0700 (PDT) Sender: arun.sharma@gmail.com Received: by 10.229.36.21 with HTTP; Mon, 26 Mar 2012 18:56:56 -0700 (PDT) In-Reply-To: <1332804965-16613-1-git-send-email-brobecker@adacore.com> References: <1332804965-16613-1-git-send-email-brobecker@adacore.com> Date: Mon, 26 Mar 2012 18:56:56 -0700 X-Google-Sender-Auth: RdjfQ2MAbUnnxFxEJsYsuIuZXW8 Message-ID: From: Arun Sharma To: Joel Brobecker Content-Type: text/plain; charset=UTF-8 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.216.173 Cc: libunwind-devel@nongnu.org Subject: Re: [Libunwind-devel] [PATCH] dangling pointer in ia64/Gtables.c:unw_search_ia64_unwind_table X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Mar 2012 01:57:02 -0000 On Mon, Mar 26, 2012 at 4:36 PM, Joel Brobecker wrote: > Hello, > > We noticed the following problem after we started building libunwind > (version 0.98.5) with GCC 4.7. Applied. Thanks. -Arun From MAILER-DAEMON Mon Mar 26 22:13:04 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1SCLuC-0004fn-EF for mharc-libunwind-devel@gnu.org; Mon, 26 Mar 2012 22:13:04 -0400 Received: from eggs.gnu.org ([208.118.235.92]:43570) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SCLu9-0004eH-ED for libunwind-devel@nongnu.org; Mon, 26 Mar 2012 22:13:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SCLu4-0000Cs-N2 for libunwind-devel@nongnu.org; Mon, 26 Mar 2012 22:13:01 -0400 Received: from mail-qa0-f52.google.com ([209.85.216.52]:39195) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SCLu4-00006C-DH for libunwind-devel@nongnu.org; Mon, 26 Mar 2012 22:12:56 -0400 Received: by qabg40 with SMTP id g40so2477262qab.4 for ; Mon, 26 Mar 2012 19:12:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type; bh=OIacdaj+xFCzGdXWLeEViX2zvxQNFh5YHlCKUt+GciQ=; b=olF6M79UhzAdKv4NttDY0/Swgja86lJLQDa10wVL9ihglrX1oHQ+W/z+AEOdjU+0bv LBod7MLRzRucUDfbFK+94XTwDGbxCY8maZbgtRUchpTIylkZppAt3Qos5p0mSy4dEzuA vX2CMH4gd7MkLA0RzkLULNEEkWys4r1n63TZX1qIuoogPPvSLjqXtbhBnWYOQSdVfvVB MvQhY+gflk+O6ZklXF2Czjvf6U3hOzDnmUsHN3BZbH+AeNKLjdmp17SIMv2qSB6pG1jS 3UCzIz4RtnymYLXiK3LI+F29AaPTYtrggtEv2jZDAwP5f+iQZNLiLrEVvJXPcRDL7Zov r8Ew== MIME-Version: 1.0 Received: by 10.224.31.84 with SMTP id x20mr30978084qac.63.1332814374436; Mon, 26 Mar 2012 19:12:54 -0700 (PDT) Sender: arun.sharma@gmail.com Received: by 10.229.36.21 with HTTP; Mon, 26 Mar 2012 19:12:54 -0700 (PDT) In-Reply-To: <1332753503-11943-2-git-send-email-alexl@redhat.com> References: <1332753503-11943-1-git-send-email-alexl@redhat.com> <1332753503-11943-2-git-send-email-alexl@redhat.com> Date: Mon, 26 Mar 2012 19:12:54 -0700 X-Google-Sender-Auth: Ev-dnJZN5GTzWue09je4f1T9Mvs Message-ID: From: Arun Sharma To: Alexander Larsson Content-Type: text/plain; charset=UTF-8 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.216.52 Cc: libunwind-devel@nongnu.org Subject: Re: [Libunwind-devel] [PATCH 1/2] Add helper macros for pointer arithmetics X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Mar 2012 02:13:02 -0000 On Mon, Mar 26, 2012 at 2:18 AM, Alexander Larsson wrote: > ALIGN lets you align pointers and STRUCT_MEMBER lets you get > structure members at a specific offset. > > These are useful in general, and will be needed for the coredump notes > cleanup work. I applied this patch to _UCD_internal.h for now. Let's move the macros to libunwind_i.h if there is a user outside of src/coredump. I believe moving ia64 code outside of src/dwarf is the only merge blocker remaining. -Arun From MAILER-DAEMON Thu Mar 29 09:59:52 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1SDFtI-0000QU-37 for mharc-libunwind-devel@gnu.org; Thu, 29 Mar 2012 09:59:52 -0400 Received: from eggs.gnu.org ([208.118.235.92]:41768) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SDBlI-0003bM-Gk for libunwind-devel@nongnu.org; Thu, 29 Mar 2012 05:35:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SDBl7-0005rP-Ez for libunwind-devel@nongnu.org; Thu, 29 Mar 2012 05:35:20 -0400 Received: from mail-lpp01m010-f45.google.com ([209.85.215.45]:59024) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SDBl7-0005p7-5L for libunwind-devel@nongnu.org; Thu, 29 Mar 2012 05:35:09 -0400 Received: by lahe6 with SMTP id e6so2428326lah.4 for ; Thu, 29 Mar 2012 02:35:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:from:date:message-id:subject:to:content-type; bh=n0FxQ4pOkJhWFOMZ6YkjJvkOqrHhW1UW28lUddN2qMw=; b=ay4vgoBTO6i827RAtbP465ci13OXxMwWT3+pMbT9HCeKPZcCGuLN/yqwN+SjadebuN 5nu/52xpLem2BCx73Mc66T389N37nOAwOPcD24bVz5WCBtd+aZwJ/EMlZDxbHIM+GI9d Ieie3v3NrZ9SdDzbBLdGloOus77uSXObLF5ApJo2DcLCw3cvPZ4dXb2YM03ifOOPOLwx LLb80ytKq9tYdWUgL+BiPSDt1xQ+UZK8kQro47T8rLqVyawVfR/sFFbSltN/SViMYz9q IOyNuZ14k2M3Idtzeuemjcrgve7IsH0tlHTZbozk1LJtCpeMtA52akEanJ2nch393Z2L AWTg== Received: by 10.152.110.193 with SMTP id ic1mr27195904lab.4.1333013706161; Thu, 29 Mar 2012 02:35:06 -0700 (PDT) MIME-Version: 1.0 Received: by 10.152.11.234 with HTTP; Thu, 29 Mar 2012 02:34:45 -0700 (PDT) From: Paul Korir Date: Thu, 29 Mar 2012 10:34:45 +0100 Message-ID: To: libunwind-devel@nongnu.org Content-Type: multipart/alternative; boundary=f46d04083b0f6fbcfa04bc5e7076 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.215.45 X-Mailman-Approved-At: Thu, 29 Mar 2012 09:59:51 -0400 Subject: [Libunwind-devel] (no subject) X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 29 Mar 2012 09:35:26 -0000 --f46d04083b0f6fbcfa04bc5e7076 Content-Type: text/plain; charset=ISO-8859-1 Dear Unwind Developers, Please see below test failures. Please let me know what else you might want to know to resolve these issues. make check-TESTS make[2]: Entering directory `/home/paulk/libunwind-0.99-beta/tests' PASS: test-proc-info PASS: test-static-link PASS: test-strerror PASS: Gtest-bt PASS: Ltest-bt PASS: Gtest-exc PASS: Ltest-exc PASS: Gtest-init PASS: Ltest-init PASS: Gtest-concurrent PASS: Ltest-concurrent failed to get SIGUSR2 FAILURE: detected 1 errors FAIL: Gtest-resume-sig failed to get SIGUSR2 FAILURE: detected 1 errors FAIL: Ltest-resume-sig FAILURE: expected 13, not 1 frames below signal frame FAIL: Gtest-dyn1 FAILURE: expected 13, not 1 frames below signal frame FAIL: Ltest-dyn1 PASS: test-async-sig PASS: test-flush-cache PASS: test-init-remote PASS: test-mem /bin/sh: line 4: 9663 Segmentation fault ${dir}$tst FAIL: test-setjmp PASS: test-ptrace PASS: Ltest-nomalloc PASS: run-check-namespace PASS: run-ptrace-mapper FAILURE: unw_step() returned -8 for ip=2aaaaaab451c (start ip=2aaaaaab451c) unwind failed with ret=-8 FAILURE: detected 2 errors FAIL: run-ptrace-misc =========================================== 6 of 25 tests failed Please report to libunwind-devel@nongnu.org =========================================== make[2]: *** [check-TESTS] Error 1 make[2]: Leaving directory `/home/paulk/libunwind-0.99-beta/tests' make[1]: *** [check-am] Error 2 make[1]: Leaving directory `/home/paulk/libunwind-0.99-beta/tests' make: *** [check-recursive] Error 1 -- Paul Korir Bioinformatics PhD student School of Maths, Stats and Applied Maths, NUI, Galway Phone: +353 86 224 19 66 *A theory is an extremely good guess.* --f46d04083b0f6fbcfa04bc5e7076 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Dear Unwind Developers,

Please see below test failures. Please let m= e know what else you might want to know to resolve these issues.

mak= e=A0 check-TESTS
make[2]: Entering directory `/home/paulk/libunwind-0.99= -beta/tests'
PASS: test-proc-info
PASS: test-static-link
PASS: test-strerror
PA= SS: Gtest-bt
PASS: Ltest-bt
PASS: Gtest-exc
PASS: Ltest-exc
PAS= S: Gtest-init
PASS: Ltest-init
PASS: Gtest-concurrent
PASS: Ltest-= concurrent
failed to get SIGUSR2
FAILURE: detected 1 errors
FAIL: Gtest-resume-s= ig
failed to get SIGUSR2
FAILURE: detected 1 errors
FAIL: Ltest-re= sume-sig
FAILURE: expected 13, not 1 frames below signal frame
FAIL: = Gtest-dyn1
FAILURE: expected 13, not 1 frames below signal frame
FAIL: Ltest-dyn1PASS: test-async-sig
PASS: test-flush-cache
PASS: test-init-remote<= br>PASS: test-mem
/bin/sh: line 4:=A0 9663 Segmentation fault=A0=A0=A0= =A0=A0 ${dir}$tst
FAIL: test-setjmp
PASS: test-ptrace
PASS: Ltest-nomalloc
PASS: run= -check-namespace
PASS: run-ptrace-mapper
FAILURE: unw_step() returned= -8 for ip=3D2aaaaaab451c (start ip=3D2aaaaaab451c)
unwind failed with r= et=3D-8
FAILURE: detected 2 errors
FAIL: run-ptrace-misc
=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
6 of 25 tests failed
Please repo= rt to libunwind-devel@nongnu.= org
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
make[2]: *** [che= ck-TESTS] Error 1
make[2]: Leaving directory `/home/paulk/libunwind-0.99= -beta/tests'
make[1]: *** [check-am] Error 2
make[1]: Leaving dir= ectory `/home/paulk/libunwind-0.99-beta/tests'
make: *** [check-recursive] Error 1

--
Paul Korir
Bioinformatic= s PhD student
School of Maths, Stats and Applied Maths,
NUI, Galway Phone: +353 86 224 19 66
A theory is an extremely good guess.
=
--f46d04083b0f6fbcfa04bc5e7076-- From MAILER-DAEMON Thu Mar 29 10:30:39 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1SDGN5-0007D5-8V for mharc-libunwind-devel@gnu.org; Thu, 29 Mar 2012 10:30:39 -0400 Received: from eggs.gnu.org ([208.118.235.92]:50441) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SDGMy-0006tJ-Q0 for libunwind-devel@nongnu.org; Thu, 29 Mar 2012 10:30:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SDGMs-0000DT-Dk for libunwind-devel@nongnu.org; Thu, 29 Mar 2012 10:30:32 -0400 Received: from mail-qc0-f173.google.com ([209.85.216.173]:37292) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SDGMs-0000DA-7G for libunwind-devel@nongnu.org; Thu, 29 Mar 2012 10:30:26 -0400 Received: by qcsc20 with SMTP id c20so1415393qcs.4 for ; Thu, 29 Mar 2012 07:30:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type; bh=j/jIaolzybmf70svcrPdJpHMsMIXRNkvgieaXlXf+oI=; b=Vsv+u/yIiuq68uiTPXpOb288MiAtAYFPNUFqaYAP7qO+N0OKKBZ0vEdB14UMDk/xvo aPHZBV6Bm/LrGExnjlLhMa7QLR/jZQDNsq2rzJr8/yqE7rtIwCOo2M4xqAXbnHJoelnj 6vQQPNGLpbxQDtf2+uB4AXON86HxfV87H592yydDGQbw2RyEFRz7WyHNm1fnaa4ItV9I KzmnZilzYdhVnHwNSFwVsl4So+TrV+nmO4ptHlSxkoBRqqPXaGphEoscJqoyxHISAN5Y fPIQ97LehZM5SuEvyb4By6x6DYIcthGXJzeFtcXGhTkUnMnyLd4n6qP7h3ZREAezdy82 y21A== MIME-Version: 1.0 Received: by 10.229.114.213 with SMTP id f21mr12954769qcq.15.1333031421744; Thu, 29 Mar 2012 07:30:21 -0700 (PDT) Sender: arun.sharma@gmail.com Received: by 10.229.124.200 with HTTP; Thu, 29 Mar 2012 07:30:21 -0700 (PDT) In-Reply-To: References: Date: Thu, 29 Mar 2012 07:30:21 -0700 X-Google-Sender-Auth: c61D_Ui6dvcs32xY3IWlHFq5TOk Message-ID: From: Arun Sharma To: Paul Korir Content-Type: text/plain; charset=UTF-8 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.216.173 Cc: libunwind-devel@nongnu.org Subject: Re: [Libunwind-devel] (no subject) X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 29 Mar 2012 14:30:37 -0000 On Thu, Mar 29, 2012 at 2:34 AM, Paul Korir wrote: > Dear Unwind Developers, > > Please see below test failures. Please let me know what else you might want > to know to resolve these issues. One way to resolve some of them would be to try 1.0.1. I expect 3-4 failures at the end - mostly due to unimplemented functionality. -Arun From MAILER-DAEMON Thu Mar 29 12:36:28 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1SDIKq-0001Ct-Jz for mharc-libunwind-devel@gnu.org; Thu, 29 Mar 2012 12:36:28 -0400 Received: from eggs.gnu.org ([208.118.235.92]:37668) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SDIKi-0001BD-Jf for libunwind-devel@nongnu.org; Thu, 29 Mar 2012 12:36:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SDIKb-0007ok-DI for libunwind-devel@nongnu.org; Thu, 29 Mar 2012 12:36:20 -0400 Received: from mx1.redhat.com ([209.132.183.28]:12003) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SDIKa-0007oX-VQ for libunwind-devel@nongnu.org; Thu, 29 Mar 2012 12:36:13 -0400 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q2TGaAMd021062 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 29 Mar 2012 12:36:10 -0400 Received: from [10.34.25.62] (dhcp-25-62.brq.redhat.com [10.34.25.62]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q2TGa75j012151; Thu, 29 Mar 2012 12:36:08 -0400 Message-ID: <4F748F77.6050907@redhat.com> Date: Thu, 29 Mar 2012 18:36:07 +0200 From: Denys Vlasenko User-Agent: Mozilla/5.0 (X11; Linux i686; rv:11.0) Gecko/20120316 Thunderbird/11.0 MIME-Version: 1.0 To: Arun Sharma References: <4F4BA6FD.6000503@redhat.com> <4F4BA743.4030405@redhat.com> <4F57579B.5060003@redhat.com> <4F622D73.7050400@redhat.com> <4F6337E7.2080105@redhat.com> In-Reply-To: Content-Type: multipart/mixed; boundary="------------090707080600050304030400" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: Karel Klic , Jiri Moskovcak , mtoman@redhat.com, Petr Machata , libunwind-devel@nongnu.org, Jan Kratochvil Subject: Re: [Libunwind-devel] [PATCHv3 1/4] Add core dump unwinding support to libunwind X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 29 Mar 2012 16:36:27 -0000 This is a multi-part message in MIME format. --------------090707080600050304030400 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit On 03/24/2012 11:31 PM, Arun Sharma wrote: > On Fri, Mar 16, 2012 at 5:53 AM, Denys Vlasenko wrote: > >> I want this code to end up in libunwind.so instead, >> so we can use it equally from both libs. >> >> Our predicament seems to be that we have no good >> place to put its source in the source tree, right? >> >> drwxr-xr-x. 2 root root 4096 Feb 13 18:43 arm >> drwxr-xr-x. 2 root root 4096 Feb 13 18:43 hppa >> drwxr-xr-x. 2 root root 4096 Feb 13 18:43 ia64 >> drwxr-xr-x. 2 root root 4096 Feb 13 18:43 mi >> drwxr-xr-x. 2 root root 4096 Feb 13 18:43 mips >> drwxr-xr-x. 2 root root 4096 Feb 13 18:43 ppc >> drwxr-xr-x. 2 root root 4096 Feb 13 18:43 ppc32 >> drwxr-xr-x. 2 root root 4096 Feb 13 18:43 ppc64 >> drwxr-xr-x. 2 root root 4096 Feb 13 18:43 x86 >> drwxr-xr-x. 2 root root 4096 Feb 13 18:43 x86_64 >> >> The above dirs are arch specific - not suitable. > > The code is also ia64 specific. I don't have any objections to putting > it under ia64. It isn't. Please take a look at src/ptrace/_UPT_find_proc_info.c (before patching. Current git, for example). It has the following structure: #if UNW_TARGET_IA64 static unw_word_t find_gp (struct UPT_info *ui, Elf64_Phdr *pdyn, Elf64_Addr load_base) ... HIDDEN int _UPTi_find_unwind_table (struct UPT_info *ui, unw_addr_space_t as, char *path, unw_word_t segbase, unw_word_t mapoff, unw_word_t ip) ... #elif UNW_TARGET_X86 || UNW_TARGET_X86_64 || UNW_TARGET_HPPA \ || UNW_TARGET_PPC32 || UNW_TARGET_PPC64 || UNW_TARGET_ARM int dwarf_read_encoded_pointer (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, unsigned char encoding, const unw_proc_info_t *pi, unw_word_t *valp, void *arg) ... HIDDEN int _UPTi_find_unwind_table (struct UPT_info *ui, unw_addr_space_t as, char *path, unw_word_t segbase, unw_word_t mapoff, unw_word_t ip) ... #endif /* UNW_TARGET_X86 || UNW_TARGET_X86_64 || UNW_TARGET_HPPA*/ static int get_unwind_info (struct UPT_info *ui, unw_addr_space_t as, unw_word_t ip) ... int _UPT_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, int need_unwind_info, void *arg) ... Thus, find_unwind_table exists for all architectures, not only for IA64. It just has two different implementations: one for IA64, and another for e > Re: common > > There is also a dir called "mi" (machine independent). But this is > arch specific code, so we shouldn't move it there. Actually it might be a good place... Please find attached patch which moves find_proc_info() to mi/*. -- vda --------------090707080600050304030400 Content-Type: text/x-patch; name="z1.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="z1.patch" commit 77e89016c23b7fc54a87407405321da6f0142a97 Author: Denys Vlasenko Date: Thu Mar 29 18:34:03 2012 +0200 Move find_unwind_table() from dwarf/ to mi/ Signed-off-by: Denys Vlasenko diff --git a/include/dwarf.h b/include/dwarf.h index 44d30de..20e2e4d 100644 --- a/include/dwarf.h +++ b/include/dwarf.h @@ -369,7 +369,6 @@ struct dwarf_callback_data #define dwarf_find_proc_info UNW_OBJ (dwarf_find_proc_info) #define dwarf_find_debug_frame UNW_OBJ (dwarf_find_debug_frame) #define dwarf_search_unwind_table UNW_OBJ (dwarf_search_unwind_table) -#define dwarf_find_unwind_table UNW_OBJ (dwarf_find_unwind_table) #define dwarf_put_unwind_info UNW_OBJ (dwarf_put_unwind_info) #define dwarf_put_unwind_info UNW_OBJ (dwarf_put_unwind_info) #define dwarf_eval_expr UNW_OBJ (dwarf_eval_expr) @@ -397,9 +396,6 @@ extern int dwarf_search_unwind_table (unw_addr_space_t as, unw_dyn_info_t *di, unw_proc_info_t *pi, int need_unwind_info, void *arg); -extern int dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, - char *path, unw_word_t segbase, unw_word_t mapoff, - unw_word_t ip); extern void dwarf_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg); extern int dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr, diff --git a/include/libunwind_i.h b/include/libunwind_i.h index 2ece7f0..ca22a81 100644 --- a/include/libunwind_i.h +++ b/include/libunwind_i.h @@ -258,6 +258,11 @@ extern int unwi_dyn_validate_cache (unw_addr_space_t as, void *arg); extern unw_dyn_info_list_t _U_dyn_info_list; extern pthread_mutex_t _U_dyn_info_list_lock; +struct elf_dyn_info; +extern int unwi_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, + char *path, unw_word_t segbase, unw_word_t mapoff, + unw_word_t ip); + #if UNW_DEBUG #define unwi_debug_level UNWI_ARCH_OBJ(debug_level) extern long unwi_debug_level; diff --git a/src/Makefile.am b/src/Makefile.am index 11c7b49..b514178 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -81,7 +81,8 @@ libunwind_la_SOURCES_generic = \ mi/Gput_dynamic_unwind_info.c mi/Gdestroy_addr_space.c \ mi/Gget_reg.c mi/Gset_reg.c \ mi/Gget_fpreg.c mi/Gset_fpreg.c \ - mi/Gset_caching_policy.c + mi/Gset_caching_policy.c \ + mi/Gfind_unwind_table.c if SUPPORT_CXX_EXCEPTIONS libunwind_la_SOURCES_local_unwind = \ @@ -109,7 +110,9 @@ libunwind_la_SOURCES_local_nounwind = \ mi/Lput_dynamic_unwind_info.c mi/Ldestroy_addr_space.c \ mi/Lget_reg.c mi/Lset_reg.c \ mi/Lget_fpreg.c mi/Lset_fpreg.c \ - mi/Lset_caching_policy.c + mi/Lset_caching_policy.c \ + mi/Lfind_unwind_table.c + libunwind_la_SOURCES_local = \ $(libunwind_la_SOURCES_local_nounwind) \ @@ -126,14 +129,12 @@ libunwind_dwarf_common_la_SOURCES = dwarf/global.c libunwind_dwarf_local_la_SOURCES = \ dwarf/Lexpr.c dwarf/Lfde.c dwarf/Lparser.c dwarf/Lpe.c dwarf/Lstep.c \ - dwarf/Lfind_proc_info-lsb.c \ - dwarf/Lfind_unwind_table.c + dwarf/Lfind_proc_info-lsb.c libunwind_dwarf_local_la_LIBADD = libunwind-dwarf-common.la libunwind_dwarf_generic_la_SOURCES = \ dwarf/Gexpr.c dwarf/Gfde.c dwarf/Gparser.c dwarf/Gpe.c dwarf/Gstep.c \ - dwarf/Gfind_proc_info-lsb.c \ - dwarf/Gfind_unwind_table.c + dwarf/Gfind_proc_info-lsb.c libunwind_dwarf_generic_la_LIBADD = libunwind-dwarf-common.la if USE_DWARF diff --git a/src/coredump/_UCD_find_proc_info.c b/src/coredump/_UCD_find_proc_info.c index b727ea9..584b18c 100644 --- a/src/coredump/_UCD_find_proc_info.c +++ b/src/coredump/_UCD_find_proc_info.c @@ -68,9 +68,9 @@ get_unwind_info(struct UCD_info *ui, unw_addr_space_t as, unw_word_t ip) /* Here, SEGBASE is the starting-address of the (mmap'ped) segment which covers the IP we're looking for. */ - if (dwarf_find_unwind_table(&ui->edi, as, phdr->backing_filename, segbase, mapoff, ip) < 0) + if (unwi_find_unwind_table(&ui->edi, as, phdr->backing_filename, segbase, mapoff, ip) < 0) { - Debug(1, "%s returns error: dwarf_find_unwind_table failed\n", __func__); + Debug(1, "%s returns error: unwi_find_unwind_table failed\n", __func__); return -UNW_ENOINFO; } diff --git a/src/coredump/_UPT_get_dyn_info_list_addr.c b/src/coredump/_UPT_get_dyn_info_list_addr.c index f1e6568..e68994a 100644 --- a/src/coredump/_UPT_get_dyn_info_list_addr.c +++ b/src/coredump/_UPT_get_dyn_info_list_addr.c @@ -56,7 +56,7 @@ get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, Debug (16, "checking object %s\n", path); - di = dwarf_find_unwind_table (&ui->edi, as, path, lo, off); + di = unwi_find_unwind_table (&ui->edi, as, path, lo, off); if (di) { res = _Uia64_find_dyn_list (as, di, arg); diff --git a/src/dwarf/Gfind_unwind_table.c b/src/dwarf/Gfind_unwind_table.c deleted file mode 100644 index 753e1c6..0000000 --- a/src/dwarf/Gfind_unwind_table.c +++ /dev/null @@ -1,348 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include -#include -#include - -#include - -#include "libunwind_i.h" - -#if UNW_TARGET_IA64 - -#include "elf64.h" - -static unw_word_t -find_gp (struct elf_dyn_info *edi, Elf64_Phdr *pdyn, Elf64_Addr load_base) -{ - Elf64_Off soff, str_soff; - Elf64_Ehdr *ehdr = edi->ei.image; - Elf64_Shdr *shdr; - Elf64_Shdr *str_shdr; - Elf64_Addr gp = 0; - char *strtab; - int i; - - if (pdyn) - { - /* If we have a PT_DYNAMIC program header, fetch the gp-value - from the DT_PLTGOT entry. */ - Elf64_Dyn *dyn = (Elf64_Dyn *) (pdyn->p_offset + (char *) edi->ei.image); - for (; dyn->d_tag != DT_NULL; ++dyn) - if (dyn->d_tag == DT_PLTGOT) - { - gp = (Elf64_Addr) dyn->d_un.d_ptr + load_base; - goto done; - } - } - - /* Without a PT_DYAMIC header, lets try to look for a non-empty .opd - section. If there is such a section, we know it's full of - function descriptors, and we can simply pick up the gp from the - second word of the first entry in this table. */ - - soff = ehdr->e_shoff; - str_soff = soff + (ehdr->e_shstrndx * ehdr->e_shentsize); - - if (soff + ehdr->e_shnum * ehdr->e_shentsize > edi->ei.size) - { - Debug (1, "section table outside of image? (%lu > %lu)", - soff + ehdr->e_shnum * ehdr->e_shentsize, - edi->ei.size); - goto done; - } - - shdr = (Elf64_Shdr *) ((char *) edi->ei.image + soff); - str_shdr = (Elf64_Shdr *) ((char *) edi->ei.image + str_soff); - strtab = (char *) edi->ei.image + str_shdr->sh_offset; - for (i = 0; i < ehdr->e_shnum; ++i) - { - if (strcmp (strtab + shdr->sh_name, ".opd") == 0 - && shdr->sh_size >= 16) - { - gp = ((Elf64_Addr *) ((char *) edi->ei.image + shdr->sh_offset))[1]; - goto done; - } - shdr = (Elf64_Shdr *) (((char *) shdr) + ehdr->e_shentsize); - } - - done: - Debug (16, "image at %p, gp = %lx\n", edi->ei.image, gp); - return gp; -} - -int -dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, - char *path, unw_word_t segbase, unw_word_t mapoff, - unw_word_t ip) -{ - Elf64_Phdr *phdr, *ptxt = NULL, *punw = NULL, *pdyn = NULL; - Elf64_Ehdr *ehdr; - int i; - - if (!_Uelf64_valid_object (&edi->ei)) - return -UNW_ENOINFO; - - ehdr = edi->ei.image; - phdr = (Elf64_Phdr *) ((char *) edi->ei.image + ehdr->e_phoff); - - for (i = 0; i < ehdr->e_phnum; ++i) - { - switch (phdr[i].p_type) - { - case PT_LOAD: - if (phdr[i].p_offset == mapoff) - ptxt = phdr + i; - break; - - case PT_IA_64_UNWIND: - punw = phdr + i; - break; - - case PT_DYNAMIC: - pdyn = phdr + i; - break; - - default: - break; - } - } - if (!ptxt || !punw) - return 0; - - edi->di_cache.start_ip = segbase; - edi->di_cache.end_ip = edi->di_cache.start_ip + ptxt->p_memsz; - edi->di_cache.gp = find_gp (edi, pdyn, segbase - ptxt->p_vaddr); - edi->di_cache.format = UNW_INFO_FORMAT_TABLE; - edi->di_cache.u.ti.name_ptr = 0; - edi->di_cache.u.ti.segbase = segbase; - edi->di_cache.u.ti.table_len = punw->p_memsz / sizeof (unw_word_t); - edi->di_cache.u.ti.table_data = (unw_word_t *) - ((char *) edi->ei.image + (punw->p_vaddr - ptxt->p_vaddr)); - return 1; -} - -#elif UNW_TARGET_X86 || UNW_TARGET_X86_64 || UNW_TARGET_HPPA \ -|| UNW_TARGET_PPC32 || UNW_TARGET_PPC64 || UNW_TARGET_ARM - -#include "dwarf-eh.h" -#include "dwarf_i.h" - -int -dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, - char *path, unw_word_t segbase, unw_word_t mapoff, - unw_word_t ip) -{ - Elf_W(Phdr) *phdr, *ptxt = NULL, *peh_hdr = NULL, *pdyn = NULL; - unw_word_t addr, eh_frame_start, fde_count, load_base; - unw_word_t max_load_addr = 0; - unw_word_t start_ip = (unw_word_t) -1; - unw_word_t end_ip = 0; - struct dwarf_eh_frame_hdr *hdr; - unw_proc_info_t pi; - unw_accessors_t *a; - Elf_W(Ehdr) *ehdr; -#if UNW_TARGET_ARM - const Elf_W(Phdr) *parm_exidx = NULL; -#endif - int i, ret, found = 0; - - /* XXX: Much of this code is Linux/LSB-specific. */ - - if (!elf_w(valid_object) (&edi->ei)) - return -UNW_ENOINFO; - - ehdr = edi->ei.image; - phdr = (Elf_W(Phdr) *) ((char *) edi->ei.image + ehdr->e_phoff); - - for (i = 0; i < ehdr->e_phnum; ++i) - { - switch (phdr[i].p_type) - { - case PT_LOAD: - if (phdr[i].p_vaddr < start_ip) - start_ip = phdr[i].p_vaddr; - - if (phdr[i].p_vaddr + phdr[i].p_memsz > end_ip) - end_ip = phdr[i].p_vaddr + phdr[i].p_memsz; - - if (phdr[i].p_offset == mapoff) - ptxt = phdr + i; - if ((uintptr_t) edi->ei.image + phdr->p_filesz > max_load_addr) - max_load_addr = (uintptr_t) edi->ei.image + phdr->p_filesz; - break; - - case PT_GNU_EH_FRAME: - peh_hdr = phdr + i; - break; - - case PT_DYNAMIC: - pdyn = phdr + i; - break; - -#if UNW_TARGET_ARM - case PT_ARM_EXIDX: - parm_exidx = phdr + i; - break; -#endif - - default: - break; - } - } - - if (!ptxt) - return 0; - - load_base = segbase - ptxt->p_vaddr; - start_ip += load_base; - end_ip += load_base; - - if (peh_hdr) - { - if (pdyn) - { - /* For dynamicly linked executables and shared libraries, - DT_PLTGOT is the value that data-relative addresses are - relative to for that object. We call this the "gp". */ - Elf_W(Dyn) *dyn = (Elf_W(Dyn) *)(pdyn->p_offset - + (char *) edi->ei.image); - for (; dyn->d_tag != DT_NULL; ++dyn) - if (dyn->d_tag == DT_PLTGOT) - { - /* Assume that _DYNAMIC is writable and GLIBC has - relocated it (true for x86 at least). */ - edi->di_cache.gp = dyn->d_un.d_ptr; - break; - } - } - else - /* Otherwise this is a static executable with no _DYNAMIC. Assume - that data-relative addresses are relative to 0, i.e., - absolute. */ - edi->di_cache.gp = 0; - - hdr = (struct dwarf_eh_frame_hdr *) (peh_hdr->p_offset - + (char *) edi->ei.image); - if (hdr->version != DW_EH_VERSION) - { - Debug (1, "table `%s' has unexpected version %d\n", - path, hdr->version); - return -UNW_ENOINFO; - } - - a = unw_get_accessors (unw_local_addr_space); - addr = (unw_word_t) (hdr + 1); - - /* Fill in a dummy proc_info structure. We just need to fill in - enough to ensure that dwarf_read_encoded_pointer() can do it's - job. Since we don't have a procedure-context at this point, all - we have to do is fill in the global-pointer. */ - memset (&pi, 0, sizeof (pi)); - pi.gp = edi->di_cache.gp; - - /* (Optionally) read eh_frame_ptr: */ - if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, - &addr, hdr->eh_frame_ptr_enc, &pi, - &eh_frame_start, NULL)) < 0) - return -UNW_ENOINFO; - - /* (Optionally) read fde_count: */ - if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, - &addr, hdr->fde_count_enc, &pi, - &fde_count, NULL)) < 0) - return -UNW_ENOINFO; - - if (hdr->table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4)) - { - #if 1 - abort (); - #else - unw_word_t eh_frame_end; - - /* If there is no search table or it has an unsupported - encoding, fall back on linear search. */ - if (hdr->table_enc == DW_EH_PE_omit) - Debug (4, "EH lacks search table; doing linear search\n"); - else - Debug (4, "EH table has encoding 0x%x; doing linear search\n", - hdr->table_enc); - - eh_frame_end = max_load_addr; /* XXX can we do better? */ - - if (hdr->fde_count_enc == DW_EH_PE_omit) - fde_count = ~0UL; - if (hdr->eh_frame_ptr_enc == DW_EH_PE_omit) - abort (); - - return linear_search (unw_local_addr_space, ip, - eh_frame_start, eh_frame_end, fde_count, - pi, need_unwind_info, NULL); - #endif - } - - edi->di_cache.start_ip = start_ip; - edi->di_cache.end_ip = end_ip; - edi->di_cache.format = UNW_INFO_FORMAT_REMOTE_TABLE; - edi->di_cache.u.rti.name_ptr = 0; - /* two 32-bit values (ip_offset/fde_offset) per table-entry: */ - edi->di_cache.u.rti.table_len = (fde_count * 8) / sizeof (unw_word_t); - edi->di_cache.u.rti.table_data = ((load_base + peh_hdr->p_vaddr) - + (addr - (unw_word_t) edi->ei.image - - peh_hdr->p_offset)); - - /* For the binary-search table in the eh_frame_hdr, data-relative - means relative to the start of that section... */ - edi->di_cache.u.rti.segbase = ((load_base + peh_hdr->p_vaddr) - + ((unw_word_t) hdr - (unw_word_t) edi->ei.image - - peh_hdr->p_offset)); - found = 1; - } - -#if UNW_TARGET_ARM - if (parm_exidx) - { - edi->di_arm.format = UNW_INFO_FORMAT_ARM_EXIDX; - edi->di_arm.start_ip = start_ip; - edi->di_arm.end_ip = end_ip; - edi->di_arm.u.rti.name_ptr = (unw_word_t) path; - edi->di_arm.u.rti.table_data = load_base + parm_exidx->p_vaddr; - edi->di_arm.u.rti.table_len = parm_exidx->p_memsz; - found = 1; - } -#endif - -#ifdef CONFIG_DEBUG_FRAME - /* Try .debug_frame. */ - found = dwarf_find_debug_frame (found, &edi->edi.di_debug, ip, segbase, path, - start_ip, end_ip); -#endif - - return found; -} - -#endif /* UNW_TARGET_X86 || UNW_TARGET_X86_64 || UNW_TARGET_HPPA*/ diff --git a/src/dwarf/Lfind_unwind_table.c b/src/dwarf/Lfind_unwind_table.c deleted file mode 100644 index 68e269f..0000000 --- a/src/dwarf/Lfind_unwind_table.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gfind_unwind_table.c" -#endif diff --git a/src/mi/Gfind_unwind_table.c b/src/mi/Gfind_unwind_table.c new file mode 100644 index 0000000..bf4edd1 --- /dev/null +++ b/src/mi/Gfind_unwind_table.c @@ -0,0 +1,348 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include +#include + +#include + +#include "libunwind_i.h" + +#if UNW_TARGET_IA64 + +#include "elf64.h" + +static unw_word_t +find_gp (struct elf_dyn_info *edi, Elf64_Phdr *pdyn, Elf64_Addr load_base) +{ + Elf64_Off soff, str_soff; + Elf64_Ehdr *ehdr = edi->ei.image; + Elf64_Shdr *shdr; + Elf64_Shdr *str_shdr; + Elf64_Addr gp = 0; + char *strtab; + int i; + + if (pdyn) + { + /* If we have a PT_DYNAMIC program header, fetch the gp-value + from the DT_PLTGOT entry. */ + Elf64_Dyn *dyn = (Elf64_Dyn *) (pdyn->p_offset + (char *) edi->ei.image); + for (; dyn->d_tag != DT_NULL; ++dyn) + if (dyn->d_tag == DT_PLTGOT) + { + gp = (Elf64_Addr) dyn->d_un.d_ptr + load_base; + goto done; + } + } + + /* Without a PT_DYAMIC header, lets try to look for a non-empty .opd + section. If there is such a section, we know it's full of + function descriptors, and we can simply pick up the gp from the + second word of the first entry in this table. */ + + soff = ehdr->e_shoff; + str_soff = soff + (ehdr->e_shstrndx * ehdr->e_shentsize); + + if (soff + ehdr->e_shnum * ehdr->e_shentsize > edi->ei.size) + { + Debug (1, "section table outside of image? (%lu > %lu)", + soff + ehdr->e_shnum * ehdr->e_shentsize, + edi->ei.size); + goto done; + } + + shdr = (Elf64_Shdr *) ((char *) edi->ei.image + soff); + str_shdr = (Elf64_Shdr *) ((char *) edi->ei.image + str_soff); + strtab = (char *) edi->ei.image + str_shdr->sh_offset; + for (i = 0; i < ehdr->e_shnum; ++i) + { + if (strcmp (strtab + shdr->sh_name, ".opd") == 0 + && shdr->sh_size >= 16) + { + gp = ((Elf64_Addr *) ((char *) edi->ei.image + shdr->sh_offset))[1]; + goto done; + } + shdr = (Elf64_Shdr *) (((char *) shdr) + ehdr->e_shentsize); + } + + done: + Debug (16, "image at %p, gp = %lx\n", edi->ei.image, gp); + return gp; +} + +int +unwi_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, + char *path, unw_word_t segbase, unw_word_t mapoff, + unw_word_t ip) +{ + Elf64_Phdr *phdr, *ptxt = NULL, *punw = NULL, *pdyn = NULL; + Elf64_Ehdr *ehdr; + int i; + + if (!_Uelf64_valid_object (&edi->ei)) + return -UNW_ENOINFO; + + ehdr = edi->ei.image; + phdr = (Elf64_Phdr *) ((char *) edi->ei.image + ehdr->e_phoff); + + for (i = 0; i < ehdr->e_phnum; ++i) + { + switch (phdr[i].p_type) + { + case PT_LOAD: + if (phdr[i].p_offset == mapoff) + ptxt = phdr + i; + break; + + case PT_IA_64_UNWIND: + punw = phdr + i; + break; + + case PT_DYNAMIC: + pdyn = phdr + i; + break; + + default: + break; + } + } + if (!ptxt || !punw) + return 0; + + edi->di_cache.start_ip = segbase; + edi->di_cache.end_ip = edi->di_cache.start_ip + ptxt->p_memsz; + edi->di_cache.gp = find_gp (edi, pdyn, segbase - ptxt->p_vaddr); + edi->di_cache.format = UNW_INFO_FORMAT_TABLE; + edi->di_cache.u.ti.name_ptr = 0; + edi->di_cache.u.ti.segbase = segbase; + edi->di_cache.u.ti.table_len = punw->p_memsz / sizeof (unw_word_t); + edi->di_cache.u.ti.table_data = (unw_word_t *) + ((char *) edi->ei.image + (punw->p_vaddr - ptxt->p_vaddr)); + return 1; +} + +#elif UNW_TARGET_X86 || UNW_TARGET_X86_64 || UNW_TARGET_HPPA \ +|| UNW_TARGET_PPC32 || UNW_TARGET_PPC64 || UNW_TARGET_ARM + +#include "dwarf-eh.h" +#include "dwarf_i.h" + +int +unwi_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, + char *path, unw_word_t segbase, unw_word_t mapoff, + unw_word_t ip) +{ + Elf_W(Phdr) *phdr, *ptxt = NULL, *peh_hdr = NULL, *pdyn = NULL; + unw_word_t addr, eh_frame_start, fde_count, load_base; + unw_word_t max_load_addr = 0; + unw_word_t start_ip = (unw_word_t) -1; + unw_word_t end_ip = 0; + struct dwarf_eh_frame_hdr *hdr; + unw_proc_info_t pi; + unw_accessors_t *a; + Elf_W(Ehdr) *ehdr; +#if UNW_TARGET_ARM + const Elf_W(Phdr) *parm_exidx = NULL; +#endif + int i, ret, found = 0; + + /* XXX: Much of this code is Linux/LSB-specific. */ + + if (!elf_w(valid_object) (&edi->ei)) + return -UNW_ENOINFO; + + ehdr = edi->ei.image; + phdr = (Elf_W(Phdr) *) ((char *) edi->ei.image + ehdr->e_phoff); + + for (i = 0; i < ehdr->e_phnum; ++i) + { + switch (phdr[i].p_type) + { + case PT_LOAD: + if (phdr[i].p_vaddr < start_ip) + start_ip = phdr[i].p_vaddr; + + if (phdr[i].p_vaddr + phdr[i].p_memsz > end_ip) + end_ip = phdr[i].p_vaddr + phdr[i].p_memsz; + + if (phdr[i].p_offset == mapoff) + ptxt = phdr + i; + if ((uintptr_t) edi->ei.image + phdr->p_filesz > max_load_addr) + max_load_addr = (uintptr_t) edi->ei.image + phdr->p_filesz; + break; + + case PT_GNU_EH_FRAME: + peh_hdr = phdr + i; + break; + + case PT_DYNAMIC: + pdyn = phdr + i; + break; + +#if UNW_TARGET_ARM + case PT_ARM_EXIDX: + parm_exidx = phdr + i; + break; +#endif + + default: + break; + } + } + + if (!ptxt) + return 0; + + load_base = segbase - ptxt->p_vaddr; + start_ip += load_base; + end_ip += load_base; + + if (peh_hdr) + { + if (pdyn) + { + /* For dynamicly linked executables and shared libraries, + DT_PLTGOT is the value that data-relative addresses are + relative to for that object. We call this the "gp". */ + Elf_W(Dyn) *dyn = (Elf_W(Dyn) *)(pdyn->p_offset + + (char *) edi->ei.image); + for (; dyn->d_tag != DT_NULL; ++dyn) + if (dyn->d_tag == DT_PLTGOT) + { + /* Assume that _DYNAMIC is writable and GLIBC has + relocated it (true for x86 at least). */ + edi->di_cache.gp = dyn->d_un.d_ptr; + break; + } + } + else + /* Otherwise this is a static executable with no _DYNAMIC. Assume + that data-relative addresses are relative to 0, i.e., + absolute. */ + edi->di_cache.gp = 0; + + hdr = (struct dwarf_eh_frame_hdr *) (peh_hdr->p_offset + + (char *) edi->ei.image); + if (hdr->version != DW_EH_VERSION) + { + Debug (1, "table `%s' has unexpected version %d\n", + path, hdr->version); + return -UNW_ENOINFO; + } + + a = unw_get_accessors (unw_local_addr_space); + addr = (unw_word_t) (hdr + 1); + + /* Fill in a dummy proc_info structure. We just need to fill in + enough to ensure that dwarf_read_encoded_pointer() can do it's + job. Since we don't have a procedure-context at this point, all + we have to do is fill in the global-pointer. */ + memset (&pi, 0, sizeof (pi)); + pi.gp = edi->di_cache.gp; + + /* (Optionally) read eh_frame_ptr: */ + if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, + &addr, hdr->eh_frame_ptr_enc, &pi, + &eh_frame_start, NULL)) < 0) + return -UNW_ENOINFO; + + /* (Optionally) read fde_count: */ + if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, + &addr, hdr->fde_count_enc, &pi, + &fde_count, NULL)) < 0) + return -UNW_ENOINFO; + + if (hdr->table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4)) + { + #if 1 + abort (); + #else + unw_word_t eh_frame_end; + + /* If there is no search table or it has an unsupported + encoding, fall back on linear search. */ + if (hdr->table_enc == DW_EH_PE_omit) + Debug (4, "EH lacks search table; doing linear search\n"); + else + Debug (4, "EH table has encoding 0x%x; doing linear search\n", + hdr->table_enc); + + eh_frame_end = max_load_addr; /* XXX can we do better? */ + + if (hdr->fde_count_enc == DW_EH_PE_omit) + fde_count = ~0UL; + if (hdr->eh_frame_ptr_enc == DW_EH_PE_omit) + abort (); + + return linear_search (unw_local_addr_space, ip, + eh_frame_start, eh_frame_end, fde_count, + pi, need_unwind_info, NULL); + #endif + } + + edi->di_cache.start_ip = start_ip; + edi->di_cache.end_ip = end_ip; + edi->di_cache.format = UNW_INFO_FORMAT_REMOTE_TABLE; + edi->di_cache.u.rti.name_ptr = 0; + /* two 32-bit values (ip_offset/fde_offset) per table-entry: */ + edi->di_cache.u.rti.table_len = (fde_count * 8) / sizeof (unw_word_t); + edi->di_cache.u.rti.table_data = ((load_base + peh_hdr->p_vaddr) + + (addr - (unw_word_t) edi->ei.image + - peh_hdr->p_offset)); + + /* For the binary-search table in the eh_frame_hdr, data-relative + means relative to the start of that section... */ + edi->di_cache.u.rti.segbase = ((load_base + peh_hdr->p_vaddr) + + ((unw_word_t) hdr - (unw_word_t) edi->ei.image + - peh_hdr->p_offset)); + found = 1; + } + +#if UNW_TARGET_ARM + if (parm_exidx) + { + edi->di_arm.format = UNW_INFO_FORMAT_ARM_EXIDX; + edi->di_arm.start_ip = start_ip; + edi->di_arm.end_ip = end_ip; + edi->di_arm.u.rti.name_ptr = (unw_word_t) path; + edi->di_arm.u.rti.table_data = load_base + parm_exidx->p_vaddr; + edi->di_arm.u.rti.table_len = parm_exidx->p_memsz; + found = 1; + } +#endif + +#ifdef CONFIG_DEBUG_FRAME + /* Try .debug_frame. */ + found = dwarf_find_debug_frame (found, &edi->edi.di_debug, ip, segbase, path, + start_ip, end_ip); +#endif + + return found; +} + +#endif /* UNW_TARGET_X86 || UNW_TARGET_X86_64 || UNW_TARGET_HPPA*/ diff --git a/src/mi/Lfind_unwind_table.c b/src/mi/Lfind_unwind_table.c new file mode 100644 index 0000000..68e269f --- /dev/null +++ b/src/mi/Lfind_unwind_table.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gfind_unwind_table.c" +#endif diff --git a/src/ptrace/_UPT_find_proc_info.c b/src/ptrace/_UPT_find_proc_info.c index 93b3f22..a999766 100644 --- a/src/ptrace/_UPT_find_proc_info.c +++ b/src/ptrace/_UPT_find_proc_info.c @@ -65,7 +65,7 @@ get_unwind_info (struct elf_dyn_info *edi, pid_t pid, unw_addr_space_t as, unw_w /* Here, SEGBASE is the starting-address of the (mmap'ped) segment which covers the IP we're looking for. */ - if (dwarf_find_unwind_table (edi, as, path, segbase, mapoff, ip) < 0) + if (unwi_find_unwind_table (edi, as, path, segbase, mapoff, ip) < 0) return -UNW_ENOINFO; /* This can happen in corner cases where dynamically generated diff --git a/src/ptrace/_UPT_get_dyn_info_list_addr.c b/src/ptrace/_UPT_get_dyn_info_list_addr.c index 60286ac..9ceb5ce 100644 --- a/src/ptrace/_UPT_get_dyn_info_list_addr.c +++ b/src/ptrace/_UPT_get_dyn_info_list_addr.c @@ -54,7 +54,7 @@ get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, Debug (16, "checking object %s\n", path); - if (dwarf_find_unwind_table (&ui->edi, as, path, lo, off, 0) > 0) + if (unwi_find_unwind_table (&ui->edi, as, path, lo, off, 0) > 0) { res = _Uia64_find_dyn_list (as, &ui->edi.di_cache, arg); if (res && count++ == 0) --------------090707080600050304030400-- From MAILER-DAEMON Thu Mar 29 14:41:52 2012 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1SDKIC-0007AO-H4 for mharc-libunwind-devel@gnu.org; Thu, 29 Mar 2012 14:41:52 -0400 Received: from eggs.gnu.org ([208.118.235.92]:33903) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SDKI8-00078s-9d for libunwind-devel@nongnu.org; Thu, 29 Mar 2012 14:41:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SDKI5-0007PY-Pu for libunwind-devel@nongnu.org; Thu, 29 Mar 2012 14:41:47 -0400 Received: from mail-qa0-f45.google.com ([209.85.216.45]:58330) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SDKI5-0007P8-Jk for libunwind-devel@nongnu.org; Thu, 29 Mar 2012 14:41:45 -0400 Received: by qaeb19 with SMTP id b19so425117qae.11 for ; Thu, 29 Mar 2012 11:41:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type; bh=NNTSlNTPb2T9mF0df3xg8il+Up6RXnL4oZ3ysAX6dic=; b=YTOADf7Qc9bPxaYanqU+DyXoh5DNhAewfwdRUnW2f5ElteuDrByHMh/pfYHAw0L0HH CHrZ/wqzFxiE29AMShGNrVtwdJhZ48WLqTmpQlmF4bABuHUXYcjO4EfHC15tzo73/yTF aD+pXd+FeeEN+Tah50P5lhnV76IJFXEMmqX+kCMDCdPJodz1bFRSMPLDN064Wpf7M2C3 QfJnGrImFDiVO7WQTt1ay/8nGh7yUjCbJBVcLEYhQ+rR6iDAT+JTXC7rzUStcnAZF9T7 KvPbnOudRulsSyta4Izetj3NwUhA0IHUn2CpHq5YE1reF/SIAAG2Fhq/U/i8paguq4Vm StWg== MIME-Version: 1.0 Received: by 10.229.136.208 with SMTP id s16mr13482701qct.35.1333046503831; Thu, 29 Mar 2012 11:41:43 -0700 (PDT) Sender: arun.sharma@gmail.com Received: by 10.229.124.200 with HTTP; Thu, 29 Mar 2012 11:41:43 -0700 (PDT) In-Reply-To: <4F748F77.6050907@redhat.com> References: <4F4BA6FD.6000503@redhat.com> <4F4BA743.4030405@redhat.com> <4F57579B.5060003@redhat.com> <4F622D73.7050400@redhat.com> <4F6337E7.2080105@redhat.com> <4F748F77.6050907@redhat.com> Date: Thu, 29 Mar 2012 11:41:43 -0700 X-Google-Sender-Auth: VsiihDDqLzH-ZfRtWOY7GxRZSpw Message-ID: From: Arun Sharma To: Denys Vlasenko Content-Type: text/plain; charset=UTF-8 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.216.45 Cc: Karel Klic , Jiri Moskovcak , mtoman@redhat.com, Petr Machata , libunwind-devel@nongnu.org, Jan Kratochvil Subject: Re: [Libunwind-devel] [PATCHv3 1/4] Add core dump unwinding support to libunwind X-BeenThere: libunwind-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Developer's mailing list for libunwind List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 29 Mar 2012 18:41:50 -0000 On Thu, Mar 29, 2012 at 9:36 AM, Denys Vlasenko wrote: >> The code is also ia64 specific. I don't have any objections to putting >> it under ia64. > > > It isn't. > > Please take a look at src/ptrace/_UPT_find_proc_info.c > (before patching. Current git, for example). > > [..] > Thus, find_unwind_table exists for all architectures, not only for IA64. > It just has two different implementations: one for IA64, and another for e What I meant to say is that for dwarf architectures, having this code in src/dwarf is just fine. Was suggesting moving just the #ifdef ia64 code to src/ia64. Like so: https://github.com/adsharma/libunwind/commit/9507a9b5018b8be16d2b62531715f1d1e2999f4a It'd be great if somone with access to ia64 boxes can fix up compilation and get src/coredump to call dwarf_find_unwind_table vs ia64_find_unwind_table depending on the architecture (either via tdep_* macros or a direct ifdef). -Arun