From: Alexandre Oliva <aoliva@redhat.com>
To: gdb-patches@sources.redhat.com
Subject: add support for `S´ augmentation in dwarf2 debug info
Date: Fri, 03 Mar 2006 17:41:00 -0000 [thread overview]
Message-ID: <orbqwnpne4.fsf@free.oliva.athome.lsd.ic.unicamp.br> (raw)
[-- Attachment #1: Type: text/plain, Size: 894 bytes --]
Jakub Jelinek has recently introduced support in GCC for unwinding
frames with the `S´ augmentation, used to denote signal stack frames.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26208
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.
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.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: gdb-augmS.patch --]
[-- Type: text/x-patch, Size: 15117 bytes --]
for gdb/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* 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 <aoliva@redhat.com>
* 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 <unwind.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <sys/syscall.h>
+
+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 <aoliva@redhat.com>
+
+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
+
[-- Attachment #3: Type: text/plain, Size: 249 bytes --]
--
Alexandre Oliva http://www.lsd.ic.unicamp.br/~oliva/
Secretary for FSF Latin America http://www.fsfla.org/
Red Hat Compiler Engineer aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist oliva@{lsd.ic.unicamp.br, gnu.org}
next reply other threads:[~2006-03-03 15:19 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-03-03 17:41 Alexandre Oliva [this message]
2006-03-04 12:05 ` Mark Kettenis
2006-03-04 14:54 ` Alexandre Oliva
2006-03-04 18:01 ` Daniel Jacobowitz
2006-03-06 15:18 ` Daniel Jacobowitz
2006-03-07 14:21 ` Alexandre Oliva
2006-03-29 0:04 ` Daniel Jacobowitz
2006-05-28 6:42 ` Alexandre Oliva
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=orbqwnpne4.fsf@free.oliva.athome.lsd.ic.unicamp.br \
--to=aoliva@redhat.com \
--cc=gdb-patches@sources.redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox