aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <gingold@adacore.com>2015-11-22 19:02:05 +0100
committerTristan Gingold <gingold@adacore.com>2015-11-22 19:02:05 +0100
commit27a4852201a41e7d6f8098cc05b7b0949ebc6af4 (patch)
tree91e6effe2be75fedb2e39e2eb374975c5666f206
parent92b0b82ea32982b94eb8bf19a0b498d92053fffe (diff)
downloadghdl-27a4852201a41e7d6f8098cc05b7b0949ebc6af4.tar.gz
ghdl-27a4852201a41e7d6f8098cc05b7b0949ebc6af4.tar.bz2
ghdl-27a4852201a41e7d6f8098cc05b7b0949ebc6af4.zip
backtrace: add support for windows and for llvm (via libbacktrace).
-rw-r--r--Makefile.in18
-rw-r--r--README7
-rwxr-xr-xconfigure13
-rw-r--r--dist/gcc/Makefile.in3
-rw-r--r--dist/mcode/windows/compile.bat56
-rw-r--r--src/ghdldrv/ghdlrun.adb3
-rw-r--r--src/grt/Makefile.inc36
-rw-r--r--src/grt/config/clock.c2
-rw-r--r--src/grt/config/jumps.c18
-rw-r--r--src/grt/config/win32.c68
-rw-r--r--src/grt/grt-backtraces-gcc.adb131
-rw-r--r--src/grt/grt-backtraces-gcc.ads35
-rw-r--r--src/grt/grt-backtraces-jit.adb42
-rw-r--r--src/grt/grt-backtraces-jit.ads44
-rw-r--r--src/grt/grt-backtraces.adb12
-rw-r--r--src/grt/grt-backtraces.ads1
-rw-r--r--src/grt/grt-errors.ads10
-rw-r--r--src/ortho/mcode/binary_file-memory.adb6
-rw-r--r--src/ortho/mcode/binary_file-memory.ads9
-rw-r--r--src/ortho/mcode/ortho_jit.adb3
-rw-r--r--src/ortho/ortho_jit.ads3
-rwxr-xr-xtestsuite/gna/ticket54/testsuite.sh2
22 files changed, 462 insertions, 60 deletions
diff --git a/Makefile.in b/Makefile.in
index 93bf89299..70732b1ba 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -26,6 +26,7 @@ libdirreverse=@libdirreverse@
gcc_src_dir=@gcc_src_dir@
llvm_prefix=@llvm_prefix@
LDFLAGS=@LDFLAGS@
+LIBBACKTRACE=@backtrace_lib@
INSTALL_PROGRAM=install -m 755
INSTALL_DATA=install -m 644
@@ -91,7 +92,8 @@ all.mcode: ghdl_mcode libs.vhdl.mcode
GHDL_MCODE_INCFLAGS=$(GHDL_COMMON_INCFLAGS) -aI$(srcdir)/src/ghdldrv -aI$(srcdir)/src/grt -aI$(srcdir)/src/ortho -aI$(srcdir)/src/ortho/mcode
ghdl_mcode: GRT_FLAGS+=-DWITH_GNAT_RUN_TIME
-ghdl_mcode: $(GRT_ADD_OBJS) $(ORTHO_DEPS) memsegs_c.o chkstk.o force
+ghdl_mcode: $(GRT_ADD_OBJS) $(GRT_SRC_DEPS) $(ORTHO_DEPS) \
+ memsegs_c.o chkstk.o force
$(GNATMAKE) -o $@ $(GHDL_MCODE_INCFLAGS) $(GNATFLAGS) ghdl_jit.adb $(GNAT_BARGS) -largs memsegs_c.o chkstk.o $(GNAT_LARGS) $(GRT_ADD_OBJS) $(subst @,$(GRTSRCDIR),$(GRT_EXTRA_LIB))
memsegs_c.o: $(srcdir)/src/ortho/mcode/memsegs_c.c
@@ -156,7 +158,13 @@ ghdl_gcc: force
$(GNATFLAGS) ghdl_gcc $(GNAT_BARGS) -largs $(GNAT_LARGS)
grt.links:
- cd $(libdirsuffix); ln -sf $(libdirreverse)/grt.lst .; ln -sf $(libdirreverse)/libgrt.a .; ln -sf $(libdirreverse)/grt.ver .
+ cd $(libdirsuffix); \
+ ln -sf $(libdirreverse)/grt.lst .; \
+ ln -sf $(libdirreverse)/libgrt.a .; \
+ ln -sf $(libdirreverse)/grt.ver .; \
+ if test "x$(LIBBACKTRACE)" != x; then \
+ ln -sf $(libdirreverse)/libbacktrace.a .; \
+ fi
libs.vhdl.gcc: ghdl_gcc ghdl1-gcc
$(MAKE) GHDL=ghdl_gcc vhdl.libs.all
@@ -184,7 +192,8 @@ all.llvm: ghdl1-llvm ghdl_llvm grt-all libs.vhdl.llvm
all.llvm_jit: ghdl_llvm_jit
ghdl_llvm_jit: GRT_FLAGS+=-DWITH_GNAT_RUN_TIME
-ghdl_llvm_jit: $(GRT_ADD_OBJS) $(ORTHO_DEPS) llvm-cbindings.o force
+ghdl_llvm_jit: $(GRT_ADD_OBJS) $(GRT_SRC_DEPS) $(ORTHO_DEPS) \
+ llvm-cbindings.o force
$(GNATMAKE) -o $@ $(GHDL_LLVM_INCFLAGS) $(GNATFLAGS) ghdl_jit.adb \
$(GNAT_BARGS) -largs llvm-cbindings.o $(GNAT_LARGS) $(GRT_ADD_OBJS) \
$(subst @,$(GRTSRCDIR),$(GRT_EXTRA_LIB)) --LINK=$(CXX) \
@@ -232,7 +241,7 @@ install.llvm: install.llvm.program install.vhdllib install.grt.llvm
GHDL_SIMUL_INCFLAGS=$(GHDL_COMMON_INCFLAGS) -aI$(srcdir)/src/ghdldrv -aI$(srcdir)/src/vhdl/simulate -aI$(srcdir)/src/grt
-ghdl_simul: $(GRT_ADD_OBJS) force
+ghdl_simul: $(GRT_ADD_OBJS) $(GRT_SRC_DEPS) force
$(GNATMAKE) $(GHDL_SIMUL_INCFLAGS) $(GNATFLAGS) ghdl_simul $(GNAT_BARGS) -largs $(GNAT_LARGS) $(GRT_ADD_OBJS) $(subst @,$(GRTSRCDIR),$(GRT_EXTRA_LIB))
libs.vhdl.simul: ghdl_simul
@@ -320,6 +329,7 @@ clean: force
distclean: clean
$(RM) -f default_pathes.ads ortho_code-x86-flags.ads
+ $(RM) -f grt-backtrace-impl.ads
$(RM) -f Makefile config.status ghdl.gpr
clean-c: force
diff --git a/README b/README
index 0354db12d..16bd9a78b 100644
--- a/README
+++ b/README
@@ -132,6 +132,13 @@ First configure ghdl and specify where llvm is installed
$ ./configure --with-llvm=PREFIX
where PREFIX/bin/llvm-config is present
+If you want to have stack backtraces on errors (like assert failure or
+index of out bounds), you need to configure and build libbacktrace from gcc
+(you don't need to configure gcc), and add to configure:
+ --with-backtrace-lib=/path-to-gcc-build/libbacktrace/.libs/libbacktrace.a
+
+Then build with 'make' and install with 'make install'.
+
Notes for developpers
*********************
diff --git a/configure b/configure
index e8825439c..af0ea2978 100755
--- a/configure
+++ b/configure
@@ -14,12 +14,13 @@ libdirreverse=../..
gcc_src_dir=
gcc_version=unknown
llvm_prefix=
+backtrace_lib=
build=
show_help=no
progname=$0
-subst_vars="CC GNATMAKE CFLAGS LDFLAGS build srcdir prefix backend libdirsuffix libdirreverse gcc_src_dir llvm_prefix"
+subst_vars="CC GNATMAKE CFLAGS LDFLAGS build srcdir prefix backend libdirsuffix libdirreverse gcc_src_dir llvm_prefix backtrace_lib"
# Find srcdir
srcdir=`dirname $progname`
@@ -68,6 +69,7 @@ for opt do
--srcdir=*) srcdir="$optarg";;
--with-gcc=*) gcc_src_dir="$optarg"; backend=gcc;;
--with-llvm=*) llvm_prefix="$optarg"; backend=llvm;;
+ --with-backtrace-lib=*) backtrace_lib="$optarg";;
-h|-help|--help) show_help=yes;;
*) echo "$0: unknown option $opt; try $0 --help"
exit 1
@@ -85,6 +87,9 @@ Options [defaults in brackets]:
--srcdir=SRCDIR source code path [$srcdir]
--with-gcc=DIR use gcc backend from DIR (needs gcc $gcc_version)
--with-llvm=DIR use llvm installed in DIR (needs llvm $llvm_version)
+ --with-backtrace-lib=LIB.a
+ link with libbacktrace LIB.a to display a backtrace on
+ errors (only for llvm).
EOF
exit 0
fi
@@ -115,6 +120,10 @@ if test $backend = mcode; then
echo "WARNING: GHDL for mcode is supported only on x86 (32 bits)"
echo "continuing, but build failure expected (See the README)"
fi
+ if test "x$backtrace_lib" != x ; then
+ echo "WARNING: --with-backtrace-lib= ignored with mcode"
+ backtrace_lib=
+ fi
fi
# For gcc backend, check version
@@ -144,7 +153,7 @@ if test $backend = llvm; then
echo "Need llvm version $llvm_version"
exit 1
fi
- # For llvm, the c++ compiler isused for linking so that the standard c++
+ # For llvm, the c++ compiler is used for linking so that the standard c++
# library is included. However, the linker needs the no_compact_unwind
# flag because code generated by gcc is not compatible with compact unwind.
case "$build" in
diff --git a/dist/gcc/Makefile.in b/dist/gcc/Makefile.in
index 9430d023c..a51b2a47c 100644
--- a/dist/gcc/Makefile.in
+++ b/dist/gcc/Makefile.in
@@ -104,6 +104,8 @@ GNATMAKE = gnatmake
ADA_CFLAGS = $(CFLAGS)
GHDL_ADAFLAGS = -Wall -gnata
+LIBBACKTRACE = ../../libbacktrace/.libs/libbacktrace.a
+
objext = .o
exeext =
arext = .a
@@ -205,6 +207,7 @@ install-ghdllib:
$(INSTALL_DATA) libgrt.a $(DESTDIR)$(VHDL_LIB_DIR)/libgrt.a
$(INSTALL_DATA) grt.lst $(DESTDIR)$(VHDL_LIB_DIR)/grt.lst
$(INSTALL_DATA) $(GRTSRCDIR)/grt.ver $(DESTDIR)$(VHDL_LIB_DIR)/grt.ver
+ $(INSTALL_DATA) $(LIBBACKTRACE) $(DESTDIR)$(VHDL_LIB_DIR)/libbacktrace.a
# Install VHDL sources.
for d in $(VHDLLIB_SUBDIRS); do \
$(MKDIR) -p $(DESTDIR)$(VHDL_LIB_DIR)/$$d; \
diff --git a/dist/mcode/windows/compile.bat b/dist/mcode/windows/compile.bat
index 95e23b53b..ef9d36252 100644
--- a/dist/mcode/windows/compile.bat
+++ b/dist/mcode/windows/compile.bat
@@ -1,23 +1,33 @@
-mkdir build
-cd build
-
-rem Do the compilation
-set CFLAGS=-O -g
-gcc -c %CFLAGS% ../../../src/grt/grt-cbinding.c
-gcc -c %CFLAGS% ../../../src/grt/grt-cvpi.c
-gcc -c %CFLAGS% ../../../src/grt/config/clock.c
-gcc -c %CFLAGS% ../../../src/ortho/mcode/memsegs_c.c
-gcc -c %CFLAGS% -DWITH_GNAT_RUN_TIME ../../../src/grt/config/win32.c
-gnatmake %CFLAGS% -gnatn -aI../windows -aI../../../src -aI../../../src/ghdldrv -aI../../../src/psl -aI../../../src/grt -aI../../../src/ortho/mcode -aI../../../src/vhdl -aI../../../src/vhdl/translate ghdl_jit -aI../../../src/ortho -o ghdl.exe -largs grt-cbinding.o clock.o grt-cvpi.o memsegs_c.o win32.o -largs -Wl,--stack,8404992
-
-if errorlevel 1 goto failed
-
-strip ghdl.exe
-
-cd ..
-exit /b 0
-
-:failed
-echo "Compilation failed"
-cd ..
-exit /b 1
+mkdir build
+cd build
+
+rem Do the compilation
+set CFLAGS= -O -Wall
+
+gcc -c %CFLAGS% ../../../src/grt/grt-cbinding.c
+if errorlevel 1 goto failed
+
+gcc -c %CFLAGS% ../../../src/grt/grt-cvpi.c
+if errorlevel 1 goto failed
+
+gcc -c %CFLAGS% ../../../src/grt/config/clock.c
+if errorlevel 1 goto failed
+
+gcc -c %CFLAGS% ../../../src/ortho/mcode/memsegs_c.c
+if errorlevel 1 goto failed
+
+gcc -c %CFLAGS% -DWITH_GNAT_RUN_TIME ../../../src/grt/config/win32.c
+if errorlevel 1 goto failed
+
+gnatmake %CFLAGS% -gnatn -aI../windows -aI../../../src -aI../../../src/ghdldrv -aI../../../src/psl -aI../../../src/grt -aI../../../src/ortho/mcode -aI../../../src/vhdl -aI../../../src/vhdl/translate ghdl_jit -aI../../../src/ortho -o ghdl.exe -largs grt-cbinding.o clock.o grt-cvpi.o memsegs_c.o win32.o -ldbghelp -Wl,--stack,8404992
+if errorlevel 1 goto failed
+
+strip ghdl.exe
+
+cd ..
+exit /b 0
+
+:failed
+echo "Compilation failed"
+cd ..
+exit /b 1
diff --git a/src/ghdldrv/ghdlrun.adb b/src/ghdldrv/ghdlrun.adb
index eac070278..9249f2cfb 100644
--- a/src/ghdldrv/ghdlrun.adb
+++ b/src/ghdldrv/ghdlrun.adb
@@ -59,6 +59,7 @@ with Grt.Values;
with Grt.Names;
with Grt.Std_Logic_1164;
with Grt.Errors;
+with Grt.Backtraces.Jit;
with Ghdlcomp;
with Foreigns;
@@ -591,7 +592,7 @@ package body Ghdlrun is
Grtlink.Flag_String := Flags.Flag_String;
- Grt.Errors.Symbolizer := Ortho_Jit.Symbolize'Access;
+ Grt.Backtraces.Jit.Symbolizer_Proc := Ortho_Jit.Symbolize'Access;
Elaborate_Proc :=
Conv (Ortho_Jit.Get_Address (Trans_Decls.Ghdl_Elaborate));
diff --git a/src/grt/Makefile.inc b/src/grt/Makefile.inc
index af217e10a..f8a4d327a 100644
--- a/src/grt/Makefile.inc
+++ b/src/grt/Makefile.inc
@@ -28,6 +28,8 @@
# target: GCC target
# GRT_FLAGS: common (Ada + C + asm) compilation flags.
# GRT_ADAFLAGS: compilation flags for Ada
+#
+# LIBBACKTRACE: if set, path to libbacktrace.a (from gcc)
# Convert the target variable into a space separated list of architecture,
# manufacturer, and operating system and assign each of those to its own
@@ -69,6 +71,9 @@ GRT_FST_OBJS := fstapi.o lz4.o fastlz.o
# Additionnal object files (C or asm files).
GRT_ADD_OBJS:=$(GRT_TARGET_OBJS) grt-cbinding.o grt-cvpi.o $(GRT_FST_OBJS)
+# Source files create by grt.
+GRT_SRC_DEPS:=grt-backtraces-impl.ads
+
#GRT_USE_PTHREADS=y
ifeq ($(GRT_USE_PTHREADS),y)
GRT_CFLAGS+=-DUSE_THREADS
@@ -76,13 +81,18 @@ ifeq ($(GRT_USE_PTHREADS),y)
GRT_EXTRA_LIB+=-lpthread
endif
+GRT_LIBBACKTRACE=
+ifneq ($(LIBBACKTRACE),)
+ GRT_LIBBACKTRACE=libbacktrace.a
+endif
+
# Configuration pragmas.
GRT_PRAGMA_FLAG=-gnatec$(GRTSRCDIR)/grt.adc -gnat05
# Rule to compile an Ada file.
GRT_ADACOMPILE=$(ADAC) -c $(GRT_FLAGS) $(GRT_PRAGMA_FLAG) -o $@ $<
-grt-all: libgrt.a grt.lst
+grt-all: libgrt.a $(GRT_LIBBACKTRACE) grt.lst
libgrt.a: $(GRT_ADD_OBJS) run-bind.o main.o grt-files
$(RM) -f $@
@@ -90,7 +100,7 @@ libgrt.a: $(GRT_ADD_OBJS) run-bind.o main.o grt-files
run-bind.o main.o
$(GRT_RANLIB) $@
-run-bind.adb: grt-force
+run-bind.adb: $(GRT_SRC_DEPS) grt-force
gnatmake -c -aI$(GRTSRCDIR) $(GRT_PRAGMA_FLAG) \
ghdl_main $(GRT_ADAFLAGS) -cargs $(GRT_FLAGS)
gnatbind -Lgrt_ -o run-bind.adb -n ghdl_main.ali
@@ -142,6 +152,15 @@ fastlz.o: $(GRTSRCDIR)/fst/fastlz.c
chkstk.o: $(GRTSRCDIR)/config/chkstk.S
$(CC) -c $(GRT_FLAGS) -o $@ $<
+grt-backtraces-impl.ads:
+ifneq ($(GRT_LIBBACKTRACE),)
+ echo "with Grt.Backtraces.Gcc;" > $@
+ echo "package Grt.Backtraces.Impl renames Grt.Backtraces.Gcc;" >> $@
+else
+ echo "with Grt.Backtraces.Jit;" > $@
+ echo "package Grt.Backtraces.Impl renames Grt.Backtraces.Jit;" >> $@
+endif
+
grt-disp-config:
@echo "target: $(target)"
@echo "targ: $(targ)"
@@ -166,11 +185,22 @@ grt.lst: grt-files.in
ifdef GRT_EXTRA_LIB
for i in $(GRT_EXTRA_LIB); do echo $$i >> $@; done
endif
+ifneq ($(LIBBACKTRACE),)
+ echo "@/libbacktrace.a" >> $@
+endif
cat $< >> $@
-grt-install: libgrt.a grt.lst
+ifneq ($(GRT_LIBBACKTRACE),)
+$(GRT_LIBBACKTRACE): $(LIBBACKTRACE)
+ cp $< $@
+endif
+
+grt-install: libgrt.a $(GRT_LIBBACKTRACE) grt.lst
$(INSTALL_DATA) libgrt.a $(DESTDIR)$(grt_libdir)/libgrt.a
$(INSTALL_DATA) grt.lst $(DESTDIR)$(grt_libdir)/grt.lst
+ifneq ($(GRT_LIBBACKTRACE),)
+ $(INSTALL_DATA) $(GRT_LIBBACKTRACE) $(DESTDIR)$(grt_libdir)/libbacktrace.a
+endif
grt-force:
diff --git a/src/grt/config/clock.c b/src/grt/config/clock.c
index 242af604b..8f5d26fc9 100644
--- a/src/grt/config/clock.c
+++ b/src/grt/config/clock.c
@@ -34,8 +34,6 @@ grt_get_clk_tck (void)
void
grt_get_times (int *wall, int *user, int *sys)
{
- clock_t res;
-
*wall = clock ();
*user = 0;
*sys = 0;
diff --git a/src/grt/config/jumps.c b/src/grt/config/jumps.c
index 00e17d37d..2170943d6 100644
--- a/src/grt/config/jumps.c
+++ b/src/grt/config/jumps.c
@@ -81,10 +81,10 @@ static JMP_BUF run_env;
#define NEED_SIGBUS_HANDLER
#endif
-static struct sigaction prev_sigfpe_act;
+static struct sigaction prev_sigsegv_act;
#ifdef NEED_SIGFPE_HANDLER
-static struct sigaction prev_sigsegv_act;
+static struct sigaction prev_sigfpe_act;
#endif
#ifdef NEED_SIGBUS_HANDLER
static struct sigaction prev_sigbus_act;
@@ -105,15 +105,27 @@ get_bt_from_ucontext (void *uctxt, struct backtrace_addrs *bt)
#endif
#if defined (__linux__) && defined (__x86_64__)
- ucontext *u = (ucontext *)uctxt;
+ ucontext_t *u = (ucontext_t *)uctxt;
pc = (void *)u->uc_mcontext.gregs[REG_RIP];
#endif
+#if defined (__linux__) && defined (__i386__)
+ ucontext_t *u = (ucontext_t *)uctxt;
+ pc = (void *)u->uc_mcontext.gregs[REG_EIP];
+#endif
#if defined (__APPLE__) && defined (__i386__)
ucontext_t *u = (ucontext_t *)uctxt;
pc = (void *)u->uc_mcontext->__ss.__eip;
bt->skip = 3; /* This frame + sighandler + trampoline + marker - pc. */
bt->addrs[3] = pc;
+ return;
#endif
+
+ for (i = 0; i < bt->size; i++)
+ if (bt->addrs[i] == pc)
+ {
+ bt->skip = i;
+ break;
+ }
}
/* Handler for SIGFPE signal.
diff --git a/src/grt/config/win32.c b/src/grt/config/win32.c
index 63d11a23e..79935e6f0 100644
--- a/src/grt/config/win32.c
+++ b/src/grt/config/win32.c
@@ -25,6 +25,8 @@
*/
#include <windows.h>
+#include <winbase.h>
+#include <dbghelp.h>
#include <stdio.h>
#include <setjmp.h>
#include <assert.h>
@@ -47,19 +49,74 @@ struct exception_registration
void *handler;
};
+/* Save bactktrace from CTXT to BT, the first SKIP frames are skipped.
+ We need to use StackWalk64 as apparently CaptureStackBackTrace doesn't
+ work over JIT'ed code. I suppose it checks whether PC belongs to the text
+ section of an image. */
+
+static void
+get_bt_from_context (struct backtrace_addrs *bt, CONTEXT *ctxt, int skip)
+{
+ STACKFRAME64 frame;
+ unsigned mach;
+
+ bt->size = 0;
+ bt->skip = 0;
+ memset (&frame, 0, sizeof (frame));
+
+#ifdef __i386__
+ mach = IMAGE_FILE_MACHINE_I386;
+
+ frame.AddrPC.Offset = ctxt->Eip;
+ frame.AddrPC.Mode = AddrModeFlat;
+ frame.AddrFrame.Offset = ctxt->Ebp;
+ frame.AddrFrame.Mode = AddrModeFlat;
+ frame.AddrStack.Offset = ctxt->Esp;
+ frame.AddrStack.Mode = AddrModeFlat;
+
+#elif defined (__x86_64__)
+ mach = IMAGE_FILE_MACHINE_AMD64;
+
+ frame.AddrPC.Offset = ctxt->Rip;
+ frame.AddrPC.Mode = AddrModeFlat;
+ frame.AddrFrame.Offset = ctx->Rsp;
+ frame.AddrFrame.Mode = AddrModeFlat;
+ frame.AddrStack.Offset = ctx->Rsp;
+ frame.AddrStack.Mode = AddrModeFlat;
+
+#else
+# warning "platform not supported"
+ return;
+#endif
+
+ while (bt->size < sizeof (bt->addrs) / sizeof (bt->addrs[0]))
+ {
+ if (skip > 0)
+ skip--;
+ else
+ bt->addrs[bt->size++] = (void *) frame.AddrPC.Offset;
+
+ if (!StackWalk64 (mach, GetCurrentProcess (), GetCurrentThread (),
+ &frame, ctxt, NULL, NULL, NULL, NULL))
+ break;
+ }
+}
+
static EXCEPTION_DISPOSITION
ghdl_SEH_handler (struct _EXCEPTION_RECORD* ExceptionRecord,
void *EstablisherFrame,
struct _CONTEXT* ContextRecord,
void *DispatcherContext)
{
+ struct backtrace_addrs bt;
const char *msg = "";
switch (ExceptionRecord->ExceptionCode)
{
case EXCEPTION_ACCESS_VIOLATION:
/* Pc is ExceptionRecord->ExceptionAddress. */
- grt_null_access_error (NULL);
+ get_bt_from_context (&bt, ContextRecord, 1);
+ grt_null_access_error (&bt);
break;
case EXCEPTION_FLT_DENORMAL_OPERAND:
@@ -76,7 +133,8 @@ ghdl_SEH_handler (struct _EXCEPTION_RECORD* ExceptionRecord,
break;
case EXCEPTION_INT_OVERFLOW:
- grt_overflow_error (NULL);
+ get_bt_from_context (&bt, ContextRecord, 1);
+ grt_overflow_error (&bt);
break;
case EXCEPTION_STACK_OVERFLOW:
@@ -134,7 +192,10 @@ __ghdl_run_through_longjump (int (*func)(void))
void
grt_save_backtrace (struct backtrace_addrs *bt, int skip)
{
- bt->size = 0;
+ CONTEXT ctxt;
+
+ RtlCaptureContext (&ctxt);
+ get_bt_from_context (bt, &ctxt, skip + 1);
}
#include <math.h>
@@ -165,4 +226,3 @@ void __gnat_raise_program_error(void)
abort ();
}
#endif
-
diff --git a/src/grt/grt-backtraces-gcc.adb b/src/grt/grt-backtraces-gcc.adb
new file mode 100644
index 000000000..3ac412b41
--- /dev/null
+++ b/src/grt/grt-backtraces-gcc.adb
@@ -0,0 +1,131 @@
+-- GHDL Run Time (GRT) - Symbolization using gcc libbacktrace.
+-- Copyright (C) 2015 Tristan Gingold
+--
+-- GHDL 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, or (at your option) any later
+-- version.
+--
+-- GHDL 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 GCC; see the file COPYING. If not, write to the Free
+-- Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+-- 02111-1307, USA.
+--
+-- As a special exception, if other files instantiate generics from this
+-- unit, or you link this unit with other files to produce an executable,
+-- this unit does not by itself cause the resulting executable to be
+-- covered by the GNU General Public License. This exception does not
+-- however invalidate any other reasons why the executable file might be
+-- covered by the GNU Public License.
+
+with System; use System;
+
+package body Grt.Backtraces.Gcc is
+ -- From backtrace.h
+ type Backtrace_Error_Callback is access procedure
+ (Data : System.Address; Msg : Address; Errnum : Integer);
+ pragma Convention (C, Backtrace_Error_Callback);
+
+ type Backtrace_State is null record;
+ pragma Convention (C, Backtrace_State);
+
+ type Backtrace_State_Acc is access all Backtrace_State;
+ pragma Convention (C, Backtrace_State_Acc);
+
+ function Backtrace_Create_State (Filename : Address;
+ Threaded : Integer;
+ Error_Callback : Backtrace_Error_Callback;
+ Data : System.Address)
+ return Backtrace_State_Acc;
+ pragma Import (C, Backtrace_Create_State);
+
+ type Backtrace_Full_Callback is access function
+ (Data : System.Address;
+ Pc : Address;
+ Filename : System.Address;
+ Lineno : Integer;
+ Function_Name : System.Address)
+ return Integer;
+ pragma Convention (C, Backtrace_Full_Callback);
+
+
+ function Backtrace_Pcinfo (State : Backtrace_State_Acc;
+ Pc : Address;
+ Callback : Backtrace_Full_Callback;
+ Error_Callback : Backtrace_Error_Callback;
+ Data : System.Address)
+ return Integer;
+ pragma Import (C, Backtrace_Pcinfo);
+
+ State : Backtrace_State_Acc;
+ Initialized : Boolean := False;
+
+ Res_Filename : System.Address;
+ Res_Lineno : Natural;
+ Res_Subprg : System.Address;
+
+ procedure Error_Cb
+ (Data : Address; Msg : Address; Errnum : Integer);
+ pragma Convention (C, Error_Cb);
+
+ procedure Error_Cb
+ (Data : Address; Msg : Address; Errnum : Integer) is
+ begin
+ null;
+ end Error_Cb;
+
+ function Cb (Data : System.Address;
+ Pc : Address;
+ Filename : System.Address;
+ Lineno : Integer;
+ Function_Name : System.Address)
+ return Integer;
+ pragma Convention (C, Cb);
+
+ function Cb (Data : System.Address;
+ Pc : Address;
+ Filename : System.Address;
+ Lineno : Integer;
+ Function_Name : System.Address)
+ return Integer is
+ begin
+ if Res_Filename = Null_Address then
+ Res_Filename := Filename;
+ Res_Lineno := Lineno;
+ Res_Subprg := Function_Name;
+ end if;
+ return 0;
+ end Cb;
+
+ procedure Symbolizer (Pc : System.Address;
+ Filename : out System.Address;
+ Lineno : out Natural;
+ Subprg : out System.Address)
+ is
+ Res : Integer;
+ begin
+ if not Initialized then
+ Initialized := True;
+ State := Backtrace_Create_State
+ (Null_Address, 0, Error_Cb'Access, Null_Address);
+ end if;
+
+ Res_Filename := Null_Address;
+ Res_Lineno := 0;
+ Res_Subprg := Null_Address;
+
+ if State /= null then
+ Res := Backtrace_Pcinfo
+ (State, Pc, Cb'access, Error_Cb'Access, Null_Address);
+ end if;
+
+ Filename := Res_Filename;
+ Lineno := Res_Lineno;
+ Subprg := Res_Subprg;
+ end Symbolizer;
+end Grt.Backtraces.Gcc;
diff --git a/src/grt/grt-backtraces-gcc.ads b/src/grt/grt-backtraces-gcc.ads
new file mode 100644
index 000000000..b5b35ffd9
--- /dev/null
+++ b/src/grt/grt-backtraces-gcc.ads
@@ -0,0 +1,35 @@
+-- GHDL Run Time (GRT) - Symbolization using gcc libbacktrace.
+-- Copyright (C) 2015 Tristan Gingold
+--
+-- GHDL 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, or (at your option) any later
+-- version.
+--
+-- GHDL 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 GCC; see the file COPYING. If not, write to the Free
+-- Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+-- 02111-1307, USA.
+--
+-- As a special exception, if other files instantiate generics from this
+-- unit, or you link this unit with other files to produce an executable,
+-- this unit does not by itself cause the resulting executable to be
+-- covered by the GNU General Public License. This exception does not
+-- however invalidate any other reasons why the executable file might be
+-- covered by the GNU Public License.
+
+with System;
+
+package Grt.Backtraces.Gcc is
+ pragma Preelaborate (Grt.Backtraces.Gcc);
+
+ procedure Symbolizer (Pc : System.Address;
+ Filename : out System.Address;
+ Lineno : out Natural;
+ Subprg : out System.Address);
+end Grt.Backtraces.Gcc;
diff --git a/src/grt/grt-backtraces-jit.adb b/src/grt/grt-backtraces-jit.adb
new file mode 100644
index 000000000..dec546c25
--- /dev/null
+++ b/src/grt/grt-backtraces-jit.adb
@@ -0,0 +1,42 @@
+-- GHDL Run Time (GRT) - Symbolization using jit interface.
+-- Copyright (C) 2015 Tristan Gingold
+--
+-- GHDL 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, or (at your option) any later
+-- version.
+--
+-- GHDL 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 GCC; see the file COPYING. If not, write to the Free
+-- Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+-- 02111-1307, USA.
+--
+-- As a special exception, if other files instantiate generics from this
+-- unit, or you link this unit with other files to produce an executable,
+-- this unit does not by itself cause the resulting executable to be
+-- covered by the GNU General Public License. This exception does not
+-- however invalidate any other reasons why the executable file might be
+-- covered by the GNU Public License.
+
+with System; use System;
+
+package body Grt.Backtraces.Jit is
+ procedure Symbolizer (Pc : System.Address;
+ Filename : out Address;
+ Lineno : out Natural;
+ Subprg : out Address) is
+ begin
+ if Symbolizer_Proc = null then
+ Filename := Null_Address;
+ Lineno := 0;
+ Subprg := Null_Address;
+ else
+ Symbolizer_Proc.all (Pc, Filename, Lineno, Subprg);
+ end if;
+ end Symbolizer;
+end Grt.Backtraces.Jit;
diff --git a/src/grt/grt-backtraces-jit.ads b/src/grt/grt-backtraces-jit.ads
new file mode 100644
index 000000000..77afdfda6
--- /dev/null
+++ b/src/grt/grt-backtraces-jit.ads
@@ -0,0 +1,44 @@
+-- GHDL Run Time (GRT) - Symbolization using jit interface.
+-- Copyright (C) 2015 Tristan Gingold
+--
+-- GHDL 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, or (at your option) any later
+-- version.
+--
+-- GHDL 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 GCC; see the file COPYING. If not, write to the Free
+-- Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+-- 02111-1307, USA.
+--
+-- As a special exception, if other files instantiate generics from this
+-- unit, or you link this unit with other files to produce an executable,
+-- this unit does not by itself cause the resulting executable to be
+-- covered by the GNU General Public License. This exception does not
+-- however invalidate any other reasons why the executable file might be
+-- covered by the GNU Public License.
+
+with System;
+
+package Grt.Backtraces.Jit is
+ pragma Preelaborate (Grt.Backtraces.Jit);
+
+ procedure Symbolizer (Pc : System.Address;
+ Filename : out System.Address;
+ Lineno : out Natural;
+ Subprg : out System.Address);
+
+ -- In order to keep the package preelaborated, use an indirection.
+ type Symbolizer_Acc is access procedure (Pc : System.Address;
+ Filename : out System.Address;
+ Lineno : out Natural;
+ Subprg : out System.Address);
+
+ Symbolizer_Proc : Symbolizer_Acc;
+
+end Grt.Backtraces.Jit;
diff --git a/src/grt/grt-backtraces.adb b/src/grt/grt-backtraces.adb
index 8b779a7d8..d365adacb 100644
--- a/src/grt/grt-backtraces.adb
+++ b/src/grt/grt-backtraces.adb
@@ -26,6 +26,7 @@
with System;
with Grt.Types; use Grt.Types;
with Grt.Hooks; use Grt.Hooks;
+with Grt.Backtraces.Impl;
package body Grt.Backtraces is
-- If true, disp address in backtraces.
@@ -162,7 +163,6 @@ package body Grt.Backtraces is
begin
if Bt.Size = 0
or else Bt.Skip >= Bt.Size
- or else Symbolizer = null
then
-- No backtrace or no symbolizer.
return;
@@ -170,15 +170,21 @@ package body Grt.Backtraces is
Unknown := False;
for I in Bt.Skip .. Bt.Size loop
- Symbolizer.all (To_Address (Bt.Addrs (I)),
- Filename, Lineno, Subprg);
+ Backtraces.Impl.Symbolizer (To_Address (Bt.Addrs (I)),
+ Filename, Lineno, Subprg);
if Subprg = Null_Address
and (Filename = Null_Address or Lineno = 0)
then
Unknown := True;
+ elsif Subprg /= Null_Address
+ and then To_Ghdl_C_String (Subprg) (1 .. 5) = "grt__"
+ then
+ -- In the runtime. Stop now.
+ exit;
else
if Unknown then
Put_Err (" from: [unknown caller]");
+ Newline_Err;
Unknown := False;
end if;
Put_Err (" from:");
diff --git a/src/grt/grt-backtraces.ads b/src/grt/grt-backtraces.ads
index 697b9dd95..301131f93 100644
--- a/src/grt/grt-backtraces.ads
+++ b/src/grt/grt-backtraces.ads
@@ -28,6 +28,7 @@ with Grt.Errors; use Grt.Errors;
package Grt.Backtraces is
pragma Preelaborate (Grt.Backtraces);
+ -- Display a backtrace on standard error, or nothing if not available.
procedure Put_Err_Backtrace (Bt : Backtrace_Addrs);
procedure Register;
diff --git a/src/grt/grt-errors.ads b/src/grt/grt-errors.ads
index cd7c3dcf5..25900da69 100644
--- a/src/grt/grt-errors.ads
+++ b/src/grt/grt-errors.ads
@@ -22,7 +22,6 @@
-- covered by the GNU General Public License. This exception does not
-- however invalidate any other reasons why the executable file might be
-- covered by the GNU Public License.
-with System;
with Grt.Types; use Grt.Types;
with Grt.Hooks;
@@ -78,13 +77,8 @@ package Grt.Errors is
type Backtrace_Addrs_Acc is access Backtrace_Addrs;
- type Symbolizer_Acc is access procedure (Pc : System.Address;
- Filename : out System.Address;
- Lineno : out Natural;
- Subprg : out System.Address);
-
- Symbolizer : Symbolizer_Acc := null;
-
+ -- Save the current backtrace to BT, but skip SKIP frame. 0 means that
+ -- the caller of this procedure will be in the backtrace.
procedure Save_Backtrace (Bt : out Backtrace_Addrs; Skip : Natural);
pragma Import (C, Save_Backtrace, "grt_save_backtrace");
diff --git a/src/ortho/mcode/binary_file-memory.adb b/src/ortho/mcode/binary_file-memory.adb
index 9797cd6b9..c9bb8ae2d 100644
--- a/src/ortho/mcode/binary_file-memory.adb
+++ b/src/ortho/mcode/binary_file-memory.adb
@@ -1,5 +1,5 @@
-- Binary file execute in memory handler.
--- Copyright (C) 2006 Tristan Gingold
+-- Copyright (C) 2006 - 2015 Tristan Gingold
--
-- GHDL 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
@@ -95,10 +95,10 @@ package body Binary_File.Memory is
end loop;
end Write_Memory_Relocate;
- function Get_Section_Base (Sect : Section_Acc) return System.Address is
+ function Get_Section_Addr (Sect : Section_Acc) return System.Address is
begin
return Sect.Data (0)'Address;
- end Get_Section_Base;
+ end Get_Section_Addr;
function Get_Section_Size (Sect : Section_Acc) return Pc_Type is
begin
diff --git a/src/ortho/mcode/binary_file-memory.ads b/src/ortho/mcode/binary_file-memory.ads
index cc2b7e39b..67755021a 100644
--- a/src/ortho/mcode/binary_file-memory.ads
+++ b/src/ortho/mcode/binary_file-memory.ads
@@ -1,5 +1,5 @@
-- Binary file execute in memory handler.
--- Copyright (C) 2006 Tristan Gingold
+-- Copyright (C) 2006-2015 Tristan Gingold
--
-- GHDL 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
@@ -21,13 +21,18 @@ package Binary_File.Memory is
-- Must be called before set_symbol_address.
procedure Write_Memory_Init;
+
+ -- Give a value to an undefined or external symbol.
procedure Set_Symbol_Address (Sym : Symbol; Addr : System.Address);
+ -- Do the real work: resolve relocations.
procedure Write_Memory_Relocate (Error : out Boolean);
- function Get_Section_Base (Sect : Section_Acc) return System.Address;
+ -- Read the result: get address and size of a section.
+ function Get_Section_Addr (Sect : Section_Acc) return System.Address;
function Get_Section_Size (Sect : Section_Acc) return Pc_Type;
+ -- Helpers.
function To_Pc_Type is new Ada.Unchecked_Conversion
(Source => System.Address, Target => Pc_Type);
function To_Address is new Ada.Unchecked_Conversion
diff --git a/src/ortho/mcode/ortho_jit.adb b/src/ortho/mcode/ortho_jit.adb
index f01c8fafa..6f4fa3769 100644
--- a/src/ortho/mcode/ortho_jit.adb
+++ b/src/ortho/mcode/ortho_jit.adb
@@ -120,6 +120,7 @@ package body Ortho_Jit is
use Ada.Text_IO;
begin
Put_Line (" -g Generate debugging informations");
+ Put_Line (" -g0 Do not generate any debugging informations");
Put_Line (" --debug-be=X Set X internal debugging flags");
Put_Line (" --snap=FILE Write memory snapshot to FILE");
end Disp_Help;
@@ -145,7 +146,7 @@ package body Ortho_Jit is
if Sect = null then
return (Null_Address, 0);
else
- Addr := Get_Section_Base (Sect);
+ Addr := Get_Section_Addr (Sect);
Size := Get_Section_Size (Sect);
return (Addr, Storage_Offset (Size));
end if;
diff --git a/src/ortho/ortho_jit.ads b/src/ortho/ortho_jit.ads
index 76a3f2906..a47cdc995 100644
--- a/src/ortho/ortho_jit.ads
+++ b/src/ortho/ortho_jit.ads
@@ -40,6 +40,9 @@ package Ortho_Jit is
-- Return the name of the code generator, to be displayed by --version.
function Get_Jit_Name return String;
+ -- Symbolizer: convert PC to a filename (a NUL terminated string), line
+ -- number and subprogram name (NUL terminated).
+ -- Unresolved values are Null_Address and 0.
procedure Symbolize (Pc : Address;
Filename : out Address;
Lineno : out Natural;
diff --git a/testsuite/gna/ticket54/testsuite.sh b/testsuite/gna/ticket54/testsuite.sh
index c2af839e8..f473c0c76 100755
--- a/testsuite/gna/ticket54/testsuite.sh
+++ b/testsuite/gna/ticket54/testsuite.sh
@@ -3,7 +3,7 @@
. ../../testenv.sh
analyze test.vhdl
-elab_simulate test
+elab_simulate_failure test --assert-level=error
clean
echo "Test successful"