347 lines
12 KiB
Plaintext
347 lines
12 KiB
Plaintext
#! /bin/sh -e
|
|
|
|
# DP: - Enable support for symbolic tracebacks in exceptions (delete the dummy
|
|
# DP: convert_addresses from adaint.c, and provide a real one separately.)
|
|
|
|
dir=
|
|
if [ $# -eq 3 -a "$2" = '-d' ]; then
|
|
pdir="-d $3"
|
|
dir="$3/"
|
|
elif [ $# -ne 1 ]; then
|
|
echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
|
|
exit 1
|
|
fi
|
|
case "$1" in
|
|
-patch)
|
|
patch $pdir -f --no-backup-if-mismatch -p0 < $0
|
|
;;
|
|
-unpatch)
|
|
patch $pdir -f --no-backup-if-mismatch -R -p0 < $0
|
|
;;
|
|
*)
|
|
echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
|
|
exit 1
|
|
esac
|
|
exit 0
|
|
|
|
Ported Jürgen Pfeifer's patch to enable symbolic tracebacks on Debian
|
|
GNU/Linux.
|
|
|
|
The binary distribution of GNAT 3.15p comes with an old version of
|
|
binutils that includes a library, libaddr2line.a. This library does
|
|
not exist in recent versions of binutils. The patch works around this
|
|
by calling /usr/bin/addr2line (still part of binutils) and parsing the
|
|
output. See debian/convert_addresses.c for the gory details.
|
|
|
|
I have modified convert_addresses.c to not use a shell script anymore;
|
|
Debian controls the version of binutils which is installed. Also, I
|
|
use execve instead of execle.
|
|
|
|
--
|
|
Ludovic Brenta.
|
|
|
|
# ' make emacs highlighting happy
|
|
|
|
Index: gcc/ada/Makefile.in
|
|
===================================================================
|
|
--- gcc/ada/Makefile.in.orig 2008-01-13 22:19:26.000000000 +0100
|
|
+++ gcc/ada/Makefile.in 2008-01-29 11:56:42.178635045 +0100
|
|
@@ -1655,7 +1655,7 @@
|
|
a-nucoar.o a-nurear.o i-forbla.o i-forlap.o s-gearop.o
|
|
|
|
GNATRTL_OBJS = $(GNATRTL_NONTASKING_OBJS) $(GNATRTL_TASKING_OBJS) \
|
|
- $(GNATRTL_LINEARALGEBRA_OBJS) g-trasym.o memtrack.o
|
|
+ $(GNATRTL_LINEARALGEBRA_OBJS) g-trasym.o memtrack.o convert_addresses.o
|
|
|
|
# Default run time files
|
|
|
|
@@ -1810,7 +1810,6 @@
|
|
for file in rts/*.ali; do \
|
|
$(INSTALL_DATA_DATE) $$file $(DESTDIR)$(ADA_RTL_OBJ_DIR); \
|
|
done
|
|
- -$(INSTALL_DATA) rts/g-trasym$(objext) $(DESTDIR)$(ADA_RTL_OBJ_DIR)
|
|
-cd rts; for file in *$(arext);do \
|
|
$(INSTALL_DATA) $$file $(DESTDIR)$(ADA_RTL_OBJ_DIR); \
|
|
$(RANLIB_FOR_TARGET) $(DESTDIR)$(ADA_RTL_OBJ_DIR)/$$file; \
|
|
@@ -1907,7 +1906,7 @@
|
|
$(GNATRTL_OBJS)
|
|
$(RM) rts/libgnat$(arext) rts/libgnarl$(arext)
|
|
$(AR_FOR_TARGET) $(AR_FLAGS) rts/libgnat$(arext) \
|
|
- $(addprefix rts/,$(GNATRTL_NONTASKING_OBJS) $(LIBGNAT_OBJS))
|
|
+ $(addprefix rts/,$(GNATRTL_NONTASKING_OBJS) $(LIBGNAT_OBJS) g-trasym.o convert_addresses.o)
|
|
ifneq ($(PREFIX_OBJS),)
|
|
$(AR_FOR_TARGET) $(AR_FLAGS) rts/libgccprefix$(arext) \
|
|
$(PREFIX_OBJS);
|
|
@@ -1940,6 +1939,7 @@
|
|
$(TARGET_LIBGCC2_CFLAGS) \
|
|
-o libgnat$(hyphen)$(LIBRARY_VERSION)$(soext) \
|
|
$(GNATRTL_NONTASKING_OBJS) $(LIBGNAT_OBJS) \
|
|
+ g-trasym.o convert_addresses.o \
|
|
$(SO_OPTS)libgnat$(hyphen)$(LIBRARY_VERSION)$(soext) \
|
|
$(MISCLIB) -lm
|
|
cd rts; ../../xgcc -B../../ -shared $(GNATLIBCFLAGS) \
|
|
@@ -2183,6 +2183,7 @@
|
|
sysdep.o : sysdep.c
|
|
raise-gcc.o : raise-gcc.c raise.h
|
|
raise.o : raise.c raise.h
|
|
+convert_addresses.o : convert_addresses.c
|
|
vx_stack_info.o : vx_stack_info.c
|
|
|
|
gen-soccon: gen-soccon.c gsocket.h
|
|
Index: gcc/ada/adaint.c
|
|
===================================================================
|
|
--- gcc/ada/adaint.c.orig 2008-01-13 22:19:26.000000000 +0100
|
|
+++ gcc/ada/adaint.c 2008-01-29 11:56:06.614450462 +0100
|
|
@@ -2852,35 +2852,6 @@
|
|
}
|
|
#endif
|
|
|
|
-#if defined (CROSS_DIRECTORY_STRUCTURE) \
|
|
- || (! ((defined (sparc) || defined (i386)) && defined (sun) \
|
|
- && defined (__SVR4)) \
|
|
- && ! (defined (linux) && (defined (i386) || defined (__x86_64__))) \
|
|
- && ! (defined (linux) && defined (__ia64__)) \
|
|
- && ! defined (__FreeBSD__) \
|
|
- && ! defined (__hpux__) \
|
|
- && ! defined (__APPLE__) \
|
|
- && ! defined (_AIX) \
|
|
- && ! (defined (__alpha__) && defined (__osf__)) \
|
|
- && ! defined (VMS) \
|
|
- && ! defined (__MINGW32__) \
|
|
- && ! (defined (__mips) && defined (__sgi)))
|
|
-
|
|
-/* Dummy function to satisfy g-trasym.o. See the preprocessor conditional
|
|
- just above for a list of native platforms that provide a non-dummy
|
|
- version of this procedure in libaddr2line.a. */
|
|
-
|
|
-void
|
|
-convert_addresses (const char *file_name ATTRIBUTE_UNUSED,
|
|
- void *addrs ATTRIBUTE_UNUSED,
|
|
- int n_addr ATTRIBUTE_UNUSED,
|
|
- void *buf ATTRIBUTE_UNUSED,
|
|
- int *len ATTRIBUTE_UNUSED)
|
|
-{
|
|
- *len = 0;
|
|
-}
|
|
-#endif
|
|
-
|
|
#if defined (_WIN32)
|
|
int __gnat_argument_needs_quote = 1;
|
|
#else
|
|
Index: gcc/ada/convert_addresses.c
|
|
===================================================================
|
|
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
|
+++ gcc/ada/convert_addresses.c 2008-01-29 11:56:06.614450462 +0100
|
|
@@ -0,0 +1,157 @@
|
|
+/*
|
|
+ Copyright (C) 1999 by Juergen Pfeifer <juergen.pfeifer@gmx.net>
|
|
+ Ada for Linux Team (ALT)
|
|
+
|
|
+ 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, distribute with modifications, 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 ABOVE 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.
|
|
+
|
|
+ Except as contained in this notice, the name(s) of the above copyright
|
|
+ holders shall not be used in advertising or otherwise to promote the
|
|
+ sale, use or other dealings in this Software without prior written
|
|
+ authorization.
|
|
+*/
|
|
+#include <sys/types.h>
|
|
+#include <stdlib.h>
|
|
+#include <stdio.h>
|
|
+#include <unistd.h>
|
|
+#include <string.h>
|
|
+#include <signal.h>
|
|
+
|
|
+#define STDIN_FILENO 0
|
|
+#define STDOUT_FILENO 1
|
|
+#define MAX_LINE 1024
|
|
+
|
|
+#define CLOSE1 close(fd1[0]); close(fd1[1])
|
|
+#define CLOSE2 close(fd2[0]); close(fd2[1])
|
|
+#define RESTSIG sigaction(SIGPIPE,&oact,NULL)
|
|
+
|
|
+void convert_addresses
|
|
+( void* addrs[],
|
|
+ int n_addr,
|
|
+ char* buf,
|
|
+ int* len)
|
|
+{
|
|
+ int max_len = *len;
|
|
+ pid_t pid = getpid();
|
|
+ pid_t child;
|
|
+
|
|
+ struct sigaction act, oact;
|
|
+
|
|
+ int fd1[2], fd2[2];
|
|
+ char exe_name[128];
|
|
+
|
|
+ *buf = 0; *len = 0;
|
|
+ /* Thanx to the /proc filesystem we can very easily reference our own
|
|
+ executable image:-)*/
|
|
+ snprintf(exe_name,sizeof(exe_name),"--exe=/proc/%ld/exe", (long)pid);
|
|
+
|
|
+ act.sa_handler = SIG_IGN;
|
|
+ sigemptyset(&act.sa_mask);
|
|
+ act.sa_flags = 0;
|
|
+ if (sigaction(SIGPIPE,&act,&oact) < 0)
|
|
+ return;
|
|
+
|
|
+ if (pipe(fd1) >= 0) {
|
|
+ if (pipe(fd2)>=0) {
|
|
+ if ((child = fork()) < 0) {
|
|
+ CLOSE1; CLOSE2; RESTSIG;
|
|
+ return;
|
|
+ }
|
|
+ else {
|
|
+ if (0==child) {
|
|
+ close(fd1[1]);
|
|
+ close(fd2[0]);
|
|
+ if (fd1[0] != STDIN_FILENO) {
|
|
+ if (dup2(fd1[0],STDIN_FILENO) != STDIN_FILENO) {
|
|
+ CLOSE1; CLOSE2;
|
|
+ }
|
|
+ close(fd1[0]);
|
|
+ }
|
|
+ if (fd2[1] != STDOUT_FILENO) {
|
|
+ if (dup2(fd2[1],STDOUT_FILENO) != STDOUT_FILENO) {
|
|
+ CLOSE1; CLOSE2;
|
|
+ }
|
|
+ close(fd2[1]);
|
|
+ }
|
|
+ {
|
|
+ /* As pointed out by Florian Weimer to me, it is a
|
|
+ security threat to call the script with a user defined
|
|
+ environment and using the path. That would be Trojans
|
|
+ pleasure. Therefore we use the absolute path to
|
|
+ addr2line and an empty environment. That should be
|
|
+ safe.
|
|
+ */
|
|
+ char *const argv[] = { "addr2line",
|
|
+ exe_name,
|
|
+ "--demangle=gnat",
|
|
+ "--functions",
|
|
+ "--basenames",
|
|
+ NULL };
|
|
+ char *const envp[] = { NULL };
|
|
+ if (execve("/usr/bin/addr2line", argv, envp) < 0) {
|
|
+ CLOSE1; CLOSE2;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ int i, n;
|
|
+ char hex[16];
|
|
+ char line[MAX_LINE + 1];
|
|
+ char *p;
|
|
+ char *s = buf;
|
|
+
|
|
+ /* Parent context */
|
|
+ close(fd1[0]);
|
|
+ close(fd2[1]);
|
|
+
|
|
+ for(i=0; i < n_addr; i++) {
|
|
+ snprintf(hex,sizeof(hex),"%p\n",addrs[i]);
|
|
+ write(fd1[1],hex,strlen(hex));
|
|
+ n = read(fd2[0],line,MAX_LINE);
|
|
+ if (n<=0)
|
|
+ break;
|
|
+ line[n]=0;
|
|
+ /* We have approx. 16 additional chars for "%p in " clause.
|
|
+ We use this info to prevent a buffer overrun.
|
|
+ */
|
|
+ if (n + 16 + (*len) > max_len)
|
|
+ break;
|
|
+ p = strchr(line,'\n');
|
|
+ if (p) {
|
|
+ if (*(p+1)) {
|
|
+ *p = 0;
|
|
+ *len += snprintf(s, (max_len - (*len)), "%p in %s at %s",addrs[i], line, p+1);
|
|
+ }
|
|
+ else {
|
|
+ *len += snprintf(s, (max_len - (*len)), "%p at %s",addrs[i], line);
|
|
+ }
|
|
+ s = buf + (*len);
|
|
+ }
|
|
+ }
|
|
+ close(fd1[1]);
|
|
+ close(fd2[0]);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ CLOSE1;
|
|
+ }
|
|
+ }
|
|
+ RESTSIG;
|
|
+}
|
|
Index: gcc/ada/g-trasym.adb
|
|
===================================================================
|
|
--- gcc/ada/g-trasym.adb.orig 2007-04-11 10:18:15.000000000 +0200
|
|
+++ gcc/ada/g-trasym.adb 2008-01-29 11:56:06.614450462 +0100
|
|
@@ -32,16 +32,16 @@
|
|
------------------------------------------------------------------------------
|
|
|
|
-- Run-time symbolic traceback support
|
|
+-- This file has been modified by Juergen Pfeifer (31-Dec-1999) for
|
|
+-- the purpose to support the Ada for Linux Team implementation of
|
|
+-- convert_addresses. This implementation has the advantage to run
|
|
+-- on the binutils as they are deployed on Linux.
|
|
|
|
with System.Soft_Links;
|
|
with Ada.Exceptions.Traceback; use Ada.Exceptions.Traceback;
|
|
|
|
package body GNAT.Traceback.Symbolic is
|
|
|
|
- pragma Linker_Options ("-laddr2line");
|
|
- pragma Linker_Options ("-lbfd");
|
|
- pragma Linker_Options ("-liberty");
|
|
-
|
|
package TSL renames System.Soft_Links;
|
|
|
|
-- To perform the raw addresses to symbolic form translation we rely on a
|
|
@@ -79,9 +79,13 @@
|
|
-- raw addresses provided in ADDRS, looked up in debug information from
|
|
-- FILENAME. LEN is filled with the result length.
|
|
--
|
|
- -- This procedure is provided by libaddr2line on targets that support
|
|
- -- it. A dummy version is in adaint.c for other targets so that build
|
|
- -- of shared libraries doesn't generate unresolved symbols.
|
|
+ -- This is the ALT Linux specific version adapted to the binutils
|
|
+ -- deployed with most Linuxes. These binutils already have an
|
|
+ -- addr2line tool that demangles Ada symbolic names, but there are
|
|
+ -- version dependant variants for the option names. Therefore our
|
|
+ -- implementation spawns a shell script that does normalization of
|
|
+ -- the option and then executes addr2line and communicates with it
|
|
+ -- through a bidirectional pipe.
|
|
--
|
|
-- Note that this procedure is *not* thread-safe.
|
|
|
|
@@ -93,8 +97,9 @@
|
|
(c_exename : System.Address) return System.Address;
|
|
pragma Import (C, locate_exec_on_path, "__gnat_locate_exec_on_path");
|
|
|
|
- Res : String (1 .. 256 * Traceback'Length);
|
|
- Len : Integer;
|
|
+ B_Size : constant Integer := 256 * Traceback'Length;
|
|
+ Len : Integer := B_Size;
|
|
+ Res : String (1 .. B_Size);
|
|
|
|
use type System.Address;
|
|
|