From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31195 invoked by alias); 4 Mar 2006 10:39:28 -0000 Received: (qmail 31177 invoked by uid 22791); 4 Mar 2006 10:39:26 -0000 X-Spam-Check-By: sourceware.org Received: from sibelius.xs4all.nl (HELO sibelius.xs4all.nl) (82.92.89.47) by sourceware.org (qpsmtpd/0.31) with ESMTP; Sat, 04 Mar 2006 10:39:23 +0000 Received: from elgar.sibelius.xs4all.nl (root@elgar.sibelius.xs4all.nl [192.168.0.2]) by sibelius.xs4all.nl (8.13.4/8.13.4) with ESMTP id k24AdDRA029318; Sat, 4 Mar 2006 11:39:13 +0100 (CET) Received: from elgar.sibelius.xs4all.nl (kettenis@localhost.sibelius.xs4all.nl [127.0.0.1]) by elgar.sibelius.xs4all.nl (8.13.4/8.13.3) with ESMTP id k24AdDCF001577; Sat, 4 Mar 2006 11:39:13 +0100 (CET) Received: (from kettenis@localhost) by elgar.sibelius.xs4all.nl (8.13.4/8.13.4/Submit) id k24AdDib021986; Sat, 4 Mar 2006 11:39:13 +0100 (CET) Date: Sat, 04 Mar 2006 12:05:00 -0000 Message-Id: <200603041039.k24AdDib021986@elgar.sibelius.xs4all.nl> From: Mark Kettenis To: aoliva@redhat.com CC: gdb-patches@sources.redhat.com In-reply-to: (message from Alexandre Oliva on Fri, 03 Mar 2006 12:18:43 -0300) Subject: Re: add support for =?iso-8859-1?Q?`S=B4?= augmentation in dwarf2 debug info References: Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2006-03/txt/msg00093.txt.bz2 > From: Alexandre Oliva > Date: Fri, 03 Mar 2006 12:18:43 -0300 > > --=-=-= > Content-Type: text/plain; charset=iso-8859-1 > Content-Transfer-Encoding: quoted-printable > > Jakub Jelinek has recently introduced support in GCC for unwinding > frames with the `S=B4 augmentation, used to denote signal stack frames. > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D26208 > > Although GDB already does a lot of grunt work in recognizing signal > stack frames to avoid the same kind of unwinding problem, it could > take advantage of this to (a) remove machine-specific code that does > so, when the augmentation is widely available, and (b) speed up > recognizing such frames when it is only partially available. Hmm, removing the machine-specific code won't be possible for quite a long time I think, but it certainly isolates us from changes made to the signal trampolines in glibc. > This patch introduces code to recognize and take advantage of the "S" > augmentation, but makes no effort to remove existing machine-specific > code. The testcase probably already worked without the change, but > it's good to have it there to avoid regressions when someone decides > to experiment with taking code out. > > Ok to install? Tested on amd64-linux-gnu. Hmm, I'm wondering whether we should give saw_z_augmentation a more meaningful name too (not sure if there is one though). Here it the testcases are really Linux-specific (and yuck, that i386 sigaction hack is ugly). Hopefully they're not too fragile. Could you please change bug-gdb@prep.ai.mit.edu into bug-gdb@gnu.org before checking this in? Thanks, Mark > for gdb/ChangeLog > from Alexandre Oliva > > * dwarf2-frame.c (struct dwarf2_cie): Add signal_frame field. > (dwarf2_frame_sniffer): Use it. > (decode_frame_entry_1): Set it according to augmentation "S". > > for gdb/testsuite/ChangeLog > from Alexandre Oliva > > * gdb.dwarf2/signal-augm.exp: New test. > * gdb.dwarf2/signal-augm.c, gdb.dwarf2/signal-augm.S: Its sources. > > Index: gdb/dwarf2-frame.c > =================================================================== > --- gdb/dwarf2-frame.c.orig 2006-03-03 11:51:41.000000000 -0300 > +++ gdb/dwarf2-frame.c 2006-03-03 11:57:45.000000000 -0300 > @@ -69,6 +69,9 @@ struct dwarf2_cie > /* True if a 'z' augmentation existed. */ > unsigned char saw_z_augmentation; > > + /* True if an 'S' augmentation existed. */ > + unsigned char signal_frame; > + > struct dwarf2_cie *next; > }; > > @@ -1032,15 +1035,17 @@ dwarf2_frame_sniffer (struct frame_info > function. frame_pc_unwind(), for a no-return next function, can > end up returning something past the end of this function's body. */ > CORE_ADDR block_addr = frame_unwind_address_in_block (next_frame); > - if (!dwarf2_frame_find_fde (&block_addr)) > + struct dwarf2_fde *fde = dwarf2_frame_find_fde (&block_addr); > + if (!fde) > return NULL; > > /* On some targets, signal trampolines may have unwind information. > We need to recognize them so that we set the frame type > correctly. */ > > - if (dwarf2_frame_signal_frame_p (get_frame_arch (next_frame), > - next_frame)) > + if (fde->cie->signal_frame > + || dwarf2_frame_signal_frame_p (get_frame_arch (next_frame), > + next_frame)) > return &dwarf2_signal_frame_unwind; > > return &dwarf2_frame_unwind; > @@ -1500,6 +1505,10 @@ decode_frame_entry_1 (struct comp_unit * > depends on the target address size. */ > cie->encoding = DW_EH_PE_absptr; > > + /* We'll determine the final value later, but we need to > + initialize it conservatively. */ > + cie->signal_frame = 0; > + > /* Check version number. */ > cie_version = read_1_byte (unit->abfd, buf); > if (cie_version != 1 && cie_version != 3) > @@ -1578,6 +1587,17 @@ decode_frame_entry_1 (struct comp_unit * > augmentation++; > } > > + /* "S" indicates a signal frame, such that the return > + address must not be decremented to locate the call frame > + info for the previous frame; it might even be the first > + instruction of a function, so decrementing it would take > + us to a different function. */ > + else if (*augmentation == 'S') > + { > + cie->signal_frame = 1; > + augmentation++; > + } > + > /* Otherwise we have an unknown augmentation. > Bail out unless we saw a 'z' prefix. */ > else > Index: gdb/testsuite/gdb.dwarf2/signal-augm.S > =================================================================== > --- /dev/null 1970-01-01 00:00:00.000000000 +0000 > +++ gdb/testsuite/gdb.dwarf2/signal-augm.S 2006-03-03 11:57:45.000000000 -0300 > @@ -0,0 +1,207 @@ > +/* This testcase is part of GDB, the GNU debugger. > + > + Copyright 2006 Free Software Foundation, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. > + > + Written by Jakub Jelinek, as testcase for GCC PR 26208. */ > + > + .globl fn3 > + .type fn3, @function > +#ifdef __powerpc64__ > + .section ".opd","aw" > + .align 3 > +fn3: > + .quad .L.fn3,.TOC.@tocbase,0 > + .text > +.L.fn3: > +#else > + .text > + .p2align 4,,15 > +fn3: > +#endif > + .cfi_startproc > +#if defined __x86_64__ > + movl $10, %eax > + movl $11, %ecx > +1: pushq %rax > + .cfi_adjust_cfa_offset 8 > + pushq %rcx > + .cfi_adjust_cfa_offset 8 > + popq %rax > + .cfi_adjust_cfa_offset -8 > + popq %rcx > + .cfi_adjust_cfa_offset -8 > + pushq %rax > + .cfi_adjust_cfa_offset 8 > + pushq %rcx > + .cfi_adjust_cfa_offset 8 > + popq %rax > + .cfi_adjust_cfa_offset -8 > + popq %rcx > + .cfi_adjust_cfa_offset -8 > + pushq %rax > + .cfi_adjust_cfa_offset 8 > + pushq %rcx > + .cfi_adjust_cfa_offset 8 > + popq %rax > + .cfi_adjust_cfa_offset -8 > + popq %rcx > + .cfi_adjust_cfa_offset -8 > + pushq %rax > + .cfi_adjust_cfa_offset 8 > + pushq %rcx > + .cfi_adjust_cfa_offset 8 > + popq %rax > + .cfi_adjust_cfa_offset -8 > + popq %rcx > + .cfi_adjust_cfa_offset -8 > + jmp 1b > +#elif defined __i386__ > + movl $10, %eax > + movl $11, %ecx > +1: pushl %eax > + .cfi_adjust_cfa_offset 4 > + pushl %ecx > + .cfi_adjust_cfa_offset 4 > + popl %eax > + .cfi_adjust_cfa_offset -4 > + popl %ecx > + .cfi_adjust_cfa_offset -4 > + pushl %eax > + .cfi_adjust_cfa_offset 4 > + pushl %ecx > + .cfi_adjust_cfa_offset 4 > + popl %eax > + .cfi_adjust_cfa_offset -4 > + popl %ecx > + .cfi_adjust_cfa_offset -4 > + pushl %eax > + .cfi_adjust_cfa_offset 4 > + pushl %ecx > + .cfi_adjust_cfa_offset 4 > + popl %eax > + .cfi_adjust_cfa_offset -4 > + popl %ecx > + .cfi_adjust_cfa_offset -4 > + pushl %eax > + .cfi_adjust_cfa_offset 4 > + pushl %ecx > + .cfi_adjust_cfa_offset 4 > + popl %eax > + .cfi_adjust_cfa_offset -4 > + popl %ecx > + .cfi_adjust_cfa_offset -4 > + jmp 1b > +#elif defined __powerpc64__ > + mflr 0 > + mr 9,1 > + std 0,16(1) > + .cfi_offset lr, 8 > + bl 1f > +1: stdu 1,-64(1) > + .cfi_adjust_cfa_offset 64 > + stdu 9,-64(1) > + .cfi_adjust_cfa_offset 64 > + addi 1,1,64 > + .cfi_adjust_cfa_offset -64 > + addi 1,1,64 > + .cfi_adjust_cfa_offset -64 > + stdu 1,-64(1) > + .cfi_adjust_cfa_offset 64 > + stdu 9,-64(1) > + .cfi_adjust_cfa_offset 64 > + addi 1,1,64 > + .cfi_adjust_cfa_offset -64 > + addi 1,1,64 > + .cfi_adjust_cfa_offset -64 > + b 1b > +#elif defined __powerpc__ > + mflr 0 > + mr 9,1 > + stwu 1,-16(1) > + .cfi_adjust_cfa_offset 16 > + stw 0,20(1) > + .cfi_offset lr, 4 > + bl 1f > +1: stwu 9,-64(1) > + .cfi_adjust_cfa_offset 64 > + stwu 9,-64(1) > + .cfi_adjust_cfa_offset 64 > + addi 1,1,64 > + .cfi_adjust_cfa_offset -64 > + addi 1,1,64 > + .cfi_adjust_cfa_offset -64 > + stwu 9,-64(1) > + .cfi_adjust_cfa_offset 64 > + stwu 9,-64(1) > + .cfi_adjust_cfa_offset 64 > + addi 1,1,64 > + .cfi_adjust_cfa_offset -64 > + addi 1,1,64 > + .cfi_adjust_cfa_offset -64 > + b 1b > +#elif defined __s390x__ > + stmg %r14,%r15,112(%r15) > + .cfi_offset %r14, -48 > + .cfi_offset %r15, -40 > + lghi %r14,6 > +1: aghi %r15,-160 > + .cfi_adjust_cfa_offset 160 > + aghi %r15,-160 > + .cfi_adjust_cfa_offset 160 > + aghi %r15,160 > + .cfi_adjust_cfa_offset -160 > + aghi %r15,160 > + .cfi_adjust_cfa_offset -160 > + aghi %r15,-160 > + .cfi_adjust_cfa_offset 160 > + aghi %r15,-160 > + .cfi_adjust_cfa_offset 160 > + aghi %r15,160 > + .cfi_adjust_cfa_offset -160 > + aghi %r15,160 > + .cfi_adjust_cfa_offset -160 > + j 1b > +#elif defined __s390__ > + stm %r14,%r15,56(%r15) > + .cfi_offset %r14, -40 > + .cfi_offset %r15, -36 > + lgi %r14,6 > +1: ahi %r15,-96 > + .cfi_adjust_cfa_offset 96 > + ahi %r15,-96 > + .cfi_adjust_cfa_offset 96 > + ahi %r15,96 > + .cfi_adjust_cfa_offset -96 > + ahi %r15,96 > + .cfi_adjust_cfa_offset -96 > + ahi %r15,-96 > + .cfi_adjust_cfa_offset 96 > + ahi %r15,-96 > + .cfi_adjust_cfa_offset 96 > + ahi %r15,96 > + .cfi_adjust_cfa_offset -96 > + ahi %r15,96 > + .cfi_adjust_cfa_offset -96 > + j 1b > +#endif > + .cfi_endproc > +#ifdef __powerpc64__ > + .size fn3, . - .L.fn3 > +#else > + .size fn3, .-fn3 > +#endif > + .section .note.GNU-stack,"",@progbits > Index: gdb/testsuite/gdb.dwarf2/signal-augm.c > =================================================================== > --- /dev/null 1970-01-01 00:00:00.000000000 +0000 > +++ gdb/testsuite/gdb.dwarf2/signal-augm.c 2006-03-03 11:57:45.000000000 -0300 > @@ -0,0 +1,198 @@ > +/* This testcase is part of GDB, the GNU debugger. > + > + Copyright 2006 Free Software Foundation, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. > + > + Written by Jakub Jelinek, as testcase for GCC PR 26208. GDB does > + not need all of it, since all we do is to try to recognize signal > + stack frames. If the compiler does not support the S augmentation > + used to denote stack frames, and GDB does not otherwise recognize > + stack frames, the test fails. */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +static _Unwind_Reason_Code > +force_unwind_stop (int version, _Unwind_Action actions, > + _Unwind_Exception_Class exc_class, > + struct _Unwind_Exception *exc_obj, > + struct _Unwind_Context *context, > + void *stop_parameter) > +{ > + if (actions & _UA_END_OF_STACK) > + abort (); > + return _URC_NO_REASON; > +} > + > +static void > +force_unwind () > +{ > + struct _Unwind_Exception *exc = malloc (sizeof (*exc)); > + memset (&exc->exception_class, 0, sizeof (exc->exception_class)); > + exc->exception_cleanup = 0; > + > +#ifndef __USING_SJLJ_EXCEPTIONS__ > + _Unwind_ForcedUnwind (exc, force_unwind_stop, 0); > +#else > + _Unwind_SjLj_ForcedUnwind (exc, force_unwind_stop, 0); > +#endif > + > + abort (); > +} > + > +int count; > + > +static void > +counter (void *p __attribute__((unused))) > +{ > + ++count; > +} > + > +static void > +handler (void *p __attribute__((unused))) > +{ > + if (count != 2) > + abort (); > + _exit (0); > +} > + > +static int __attribute__((noinline)) > +fn5 (void) > +{ > + char dummy __attribute__((cleanup (counter))); > + force_unwind (); > + return 0; > +} > + > +static void > +fn4 (int sig, siginfo_t *info, void *ctx) > +{ > + char dummy __attribute__((cleanup (counter))); > + fn5 (); > +} > + > +extern void fn3 (long a, long b, long c, long d, long e, long f, long g); > + > +static int __attribute__((noinline)) > +fn2 (void) > +{ > + fn3 (1, 2, 3, 4, 5, 6, 7); > + return 0; > +} > + > +static int __attribute__((noinline)) > +fn1 (void) > +{ > +#if defined __i386__ && defined SIGACTION_DIRECT_SYSCALL > + struct i386_kernel_sigaction > + { > + void (*k_sa_handler) (int, siginfo_t *, void *); > + unsigned long k_sa_flags; > + void (*sa_restorer) (void); > + unsigned long long k_sa_mask; > + } s; > + extern void __cleanup12_rt_sigreturn (void); > + s.k_sa_handler = fn4; > + s.k_sa_mask = 0; > + s.k_sa_flags = 0x4000000 | SA_RESETHAND | SA_SIGINFO; > + s.sa_restorer = __cleanup12_rt_sigreturn; > + asm volatile (".subsection 1; nop; __cleanup12_rt_sigreturn:" > + "movl %0, %%eax; int $0x80; .previous" > + : : "i" (__NR_rt_sigreturn)); > + syscall (SYS_rt_sigaction, SIGUSR1, &s, NULL, 8); > +#else > + struct sigaction s; > + sigemptyset (&s.sa_mask); > + s.sa_sigaction = fn4; > + s.sa_flags = SA_RESETHAND | SA_SIGINFO; > + sigaction (SIGUSR1, &s, NULL); > +#endif > + fn2 (); > + return 0; > +} > + > +static void * > +tf (void *arg) > +{ > + char dummy __attribute__((cleanup (handler))); > + (void) arg; > + fn1 (); > + return 0; > +} > + > +void > +do_test (void) > +{ > + pthread_t th; > + struct timespec ts; > + if (pthread_create (&th, 0, tf, 0)) > + { > + fputs ("pthread_create failed\n", stderr); > + _exit (1); > + } > + ts.tv_sec = 1; > + ts.tv_nsec = 0; > + nanosleep (&ts, NULL); > + if (pthread_kill (th, SIGUSR1)) > + { > + fputs ("pthread_kill failed\n", stderr); > + _exit (1); > + } > + ts.tv_sec = 3; > + ts.tv_nsec = 0; > + nanosleep (&ts, NULL); > + _exit (1); > +} > + > +int > +main (int argc, char **argv) > +{ > + int i, failures = 0, status; > + if (argc == 2 && strcmp (argv[1], "-d") == 0) > + do_test (); > + else > + for (i = 0; i < 50; i++) > + { > + pid_t pid = fork (); > + if (pid < 0) > + { > + perror ("fork"); > + failures++; > + } > + else if (pid == 0) > + do_test (); > + else if (waitpid (pid, &status, 0) < 0) > + { > + perror ("waitpid"); > + failures++; > + } > + else if (! WIFEXITED (status) || WEXITSTATUS (status)) > + { > + fprintf (stderr, "Failure in round %d\n", i); > + failures++; > + } > + } > + if (failures) > + abort (); > + return 0; > +} > Index: gdb/testsuite/gdb.dwarf2/signal-augm.exp > =================================================================== > --- /dev/null 1970-01-01 00:00:00.000000000 +0000 > +++ gdb/testsuite/gdb.dwarf2/signal-augm.exp 2006-03-03 12:08:40.000000000 -0300 > @@ -0,0 +1,77 @@ > +# Copyright 2006 Free Software Foundation, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. > + > +# Please email any bugs, comments, and/or additions to this file to: > +# bug-gdb@prep.ai.mit.edu > + > +# This file was written by Alexandre Oliva > + > +if $tracelevel then { > + strace $tracelevel > + } > + > +set prms_id 0 > +set bug_id 0 > + > +# signal-augm.S needs hand-coded assembly > +if {![istarget i*86-*-linux*] > + && ![istarget x86_64-*-linux*] > + && ![istarget powerpc*-*-linux*] > + && ![istarget s390*-*-linux*]} { > + return -1; > +} > + > +if [get_compiler_info "ignored"] { > + return -1 > +} > + > +if {$gcc_compiled == 0} { > + return -1 > +} > + > +set testfile "signal-augm" > + > +set srcbasename ${srcdir}/${subdir}/${testfile} > +set binfile ${objdir}/${subdir}/${testfile} > +if { [gdb_compile "${srcbasename}.c ${srcbasename}.S" "${binfile}" executable [list debug "additional_flags=-pthread -fexceptions -fnon-call-exceptions -fasynchronous-unwind-tables -O2"]] != ""} { > + return -1; > +} > + > +gdb_exit > +gdb_start > +gdb_reinitialize_dir $srcdir/$subdir > +gdb_load ${binfile} > + > +if [target_info exists gdb_stub] { > + gdb_step_for_stub; > +} > + > +gdb_test "break fn5" "Breakpoint.*at.*" "breakpoint fn5" > + > +set test "stop at fn5" > +gdb_test_multiple "run -d" "$test" { > + -re "received signal" { > + send_gdb "continue\n" > + } > + -re "Breakpoint 1" { > + pass "$test" > + } > +} > + > +gdb_test "backtrace" ".*\#0 .* fn5 .*\#1 .* fn4 .*\#2 .*signal handler.*\#3 .* fn3 .*\#4 .* fn2 .*\#5 .* fn1 .*\#6 .* tf.*" "$test" > + > +return 0 > +