Index: Makefile.def
===================================================================
--- Makefile.def	(revision 226823)
+++ Makefile.def	(working copy)
@@ -597,6 +597,7 @@ dependencies = { module=all-target-winsu
 dependencies = { module=configure-target-newlib; on=all-binutils; };
 dependencies = { module=configure-target-newlib; on=all-ld; };
 dependencies = { module=configure-target-libgfortran; on=all-target-libquadmath; };
+dependencies = { module=configure-target-libgfortran; on=all-target-libbacktrace; };
 
 languages = { language=c;	gcc-check-target=check-gcc; };
 languages = { language=c++;	gcc-check-target=check-c++;
Index: gcc/fortran/config-lang.in
===================================================================
--- gcc/fortran/config-lang.in	(revision 226823)
+++ gcc/fortran/config-lang.in	(working copy)
@@ -27,7 +27,7 @@ language="fortran"
 
 compilers="f951\$(exeext)"
 
-target_libs=target-libgfortran
+target_libs="target-libgfortran target-libbacktrace"
 
 gtfiles="\$(srcdir)/fortran/f95-lang.c \$(srcdir)/fortran/trans-decl.c \$(srcdir)/fortran/trans-intrinsic.c \$(srcdir)/fortran/trans-io.c \$(srcdir)/fortran/trans-stmt.c \$(srcdir)/fortran/trans-types.c \$(srcdir)/fortran/trans-types.h \$(srcdir)/fortran/trans.h \$(srcdir)/fortran/trans-const.h"
 
Index: libgfortran/Makefile.am
===================================================================
--- libgfortran/Makefile.am	(revision 226823)
+++ libgfortran/Makefile.am	(working copy)
@@ -37,7 +37,8 @@ toolexeclib_LTLIBRARIES = libgfortran.la
 toolexeclib_DATA = libgfortran.spec
 libgfortran_la_LINK = $(LINK) $(libgfortran_la_LDFLAGS)
 libgfortran_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \
-	$(LTLDFLAGS) $(LIBQUADLIB) -lm $(extra_ldflags_libgfortran) \
+	$(LTLDFLAGS) $(LIBQUADLIB) ../libbacktrace/libbacktrace.la \
+	-lm $(extra_ldflags_libgfortran) \
 	$(version_arg) -Wc,-shared-libgcc
 libgfortran_la_DEPENDENCIES = $(version_dep) libgfortran.spec $(LIBQUADLIB_DEP)
 
@@ -59,7 +60,10 @@ AM_CPPFLAGS = -iquote$(srcdir)/io -I$(sr
 	      -I$(srcdir)/$(MULTISRCTOP)../gcc/config $(LIBQUADINCLUDE) \
 	      -I$(MULTIBUILDTOP)../../$(host_subdir)/gcc \
 	      -I$(srcdir)/$(MULTISRCTOP)../libgcc \
-	      -I$(MULTIBUILDTOP)../libgcc
+	      -I$(MULTIBUILDTOP)../libgcc \
+	      -I$(srcdir)/$(MULTISRCTOP)../libbacktrace \
+	      -I$(MULTIBUILDTOP)../libbacktrace \
+	      -I../libbacktrace
 
 # Fortran rules for complex multiplication and division
 AM_CFLAGS += -fcx-fortran-rules
Index: libgfortran/configure.ac
===================================================================
--- libgfortran/configure.ac	(revision 226823)
+++ libgfortran/configure.ac	(working copy)
@@ -287,7 +287,6 @@ if test "x${with_newlib}" = "xyes"; then
    AC_DEFINE(HAVE_GMTIME_R, 1, [Define if you have gmtime_r.])
    AC_DEFINE(HAVE_STRNLEN, 1, [Define if you have strnlen.])
    AC_DEFINE(HAVE_STRNDUP, 1, [Define if you have strndup.])
-   AC_DEFINE(HAVE_STRTOK_R, 1, [Define if you have strtok_r.])
 
    # At some point, we should differentiate between architectures
    # like x86, which have long double versions, and alpha/powerpc/etc.,
@@ -298,11 +297,11 @@ if test "x${with_newlib}" = "xyes"; then
 else
    AC_CHECK_FUNCS_ONCE(getrusage times mkstemp strtof strtold snprintf \
    ftruncate chsize chdir getlogin gethostname kill link symlink sleep ttyname \
-   alarm access fork execl wait setmode execve pipe dup2 close fcntl \
+   alarm access fork execl setmode close fcntl \
    strcasestr getrlimit gettimeofday stat fstat lstat getpwuid vsnprintf dup \
    getcwd localtime_r gmtime_r getpwuid_r ttyname_r clock_gettime \
    readlink getgid getpid getppid getuid geteuid umask getegid \
-   secure_getenv __secure_getenv mkostemp strnlen strndup strtok_r newlocale \
+   secure_getenv __secure_getenv mkostemp strnlen strndup newlocale \
    freelocale uselocale strerror_l)
 fi
 
@@ -610,9 +609,6 @@ LIBGFOR_CHECK_UNLINK_OPEN_FILE
 # Check whether line terminator is LF or CRLF
 LIBGFOR_CHECK_CRLF
 
-# Check whether we have _Unwind_GetIPInfo for backtrace
-GCC_CHECK_UNWIND_GETIPINFO
-
 AC_CACHE_SAVE
 
 if test ${multilib} = yes; then
Index: libgfortran/libgfortran.h
===================================================================
--- libgfortran/libgfortran.h	(revision 226823)
+++ libgfortran/libgfortran.h	(working copy)
@@ -649,16 +649,11 @@ internal_proto(get_args);
 extern void store_exe_path (const char *);
 export_proto(store_exe_path);
 
-extern char * full_exe_path (void);
-internal_proto(full_exe_path);
-
-extern void find_addr2line (void);
-internal_proto(find_addr2line);
-
 /* backtrace.c */
 
-extern void backtrace (void);
-iexport_proto(backtrace);
+extern void show_backtrace (int);
+internal_proto(show_backtrace);
+
 
 /* error.c */
 
Index: libgfortran/runtime/backtrace.c
===================================================================
--- libgfortran/runtime/backtrace.c	(revision 226823)
+++ libgfortran/runtime/backtrace.c	(working copy)
@@ -31,249 +31,122 @@ see the files COPYING3 and COPYING.RUNTI
 #include <unistd.h>
 #endif
 
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
+#include "backtrace-supported.h"
+#include "backtrace.h"
 
-#include <limits.h>
 
-#include "unwind.h"
+/* Store our own state while backtracing.  */
+struct mystate
+{
+  int try_simple;
+  int frame;
+};
 
 
-/* Macros for common sets of capabilities: can we fork and exec, and
-   can we use pipes to communicate with the subprocess.  */
-#define CAN_FORK (defined(HAVE_FORK) && defined(HAVE_EXECVE) \
-		  && defined(HAVE_WAIT))
-#define CAN_PIPE (CAN_FORK && defined(HAVE_PIPE) \
-		  && defined(HAVE_DUP2) && defined(HAVE_CLOSE))
+/* Does a function name have "_gfortran_" or "_gfortrani_" prefix, possibly
+   with additional underscore(s) at the beginning?  Cannot use strncmp()
+   because we might be called from a signal handler.  */
 
-#ifndef PATH_MAX
-#define PATH_MAX 4096
-#endif
+static int
+has_gfortran_prefix (const char *s)
+{
+  if (!s)
+    return 0;
 
+  while (*s == '_')
+    s++;
 
-/* GDB style #NUM index for each stack frame.  */
+  return (s[0] == 'g' && s[1] == 'f' && s[2] == 'o' && s[3] == 'r'
+	  && s[4] == 't' && s[5] == 'r' && s[6] == 'a' && s[7] == 'n'
+	  && (s[8] == '_' || (s[8] == 'i' && s[9] == '_')));
+}
 
-static void 
-bt_header (int num)
+static void
+error_callback (void *data, const char *msg, int errnum)
 {
-  st_printf ("#%d  ", num);
-}
+  struct mystate *state = (struct mystate *) data;
+  if (errnum < 0)
+    {
+      state->try_simple = 1;
+      return;
+    }
 
+  estr_write ("\nSomething went wrong while printing the backtrace: ");
+  estr_write (msg);
+  estr_write ("\n");
+}
 
-/* fgets()-like function that reads a line from a fd, without
-   needing to malloc() a buffer, and does not use locks, hence should
-   be async-signal-safe.  */
+static int
+simple_callback (void *data, uintptr_t pc)
+{
+  struct mystate *state = (struct mystate *) data;
+  st_printf ("#%d  0x%lx\n", state->frame, (unsigned long) pc);
+  (state->frame)++;
+  return 0;
+}
 
-static char *
-fd_gets (char *s, int size, int fd)
+static int
+full_callback (void *data, uintptr_t pc, const char *filename,
+	       int lineno, const char *function)
 {
-  for (int i = 0; i < size; i++)
-    {
-      char c;
-      ssize_t nread = read (fd, &c, 1);
-      if (nread == 1)
-	{
-	  s[i] = c;
-	  if (c == '\n')
-	    {
-	      if (i + 1 < size)
-		s[i+1] = '\0';
-	      else
-		s[i] = '\0';
-	      break;
-	    }
-	}
-      else
-	{
-	  s[i] = '\0';
-	  if (i == 0)
-	    return NULL;
-	  break;
-	}
-    }
-  return s;
+  struct mystate *state = (struct mystate *) data;
+
+  if (has_gfortran_prefix (function))
+    return 0;
+
+  st_printf ("#%d  0x%lx %s\n", state->frame,
+	     (unsigned long) pc, function == NULL ? "???" : function);
+  if (filename || lineno != 0)
+    st_printf ("\t%s:%d\n", filename == NULL ? "???" : filename, lineno);
+  (state->frame)++;
+
+  if (function != NULL && strcmp (function, "main") == 0)
+    return 1;
+
+  return 0;
 }
 
 
-extern char *addr2line_path;
+/* Display the backtrace.  */
 
-/* Struct containing backtrace state.  */
-typedef struct
+void
+show_backtrace (int in_signal_handler)
 {
-  int frame_number;
-  int direct_output;
-  int outfd;
-  int infd;
-  int error;
-}
-bt_state;
-
-static _Unwind_Reason_Code
-trace_function (struct _Unwind_Context *context, void *state_ptr)
-{
-  bt_state* state = (bt_state*) state_ptr;
-  _Unwind_Ptr ip;
-#ifdef HAVE_GETIPINFO
-  int ip_before_insn = 0;
-  ip = _Unwind_GetIPInfo (context, &ip_before_insn);
-  
-  /* If the unwinder gave us a 'return' address, roll it back a little
-     to ensure we get the correct line number for the call itself.  */
-  if (! ip_before_insn)
-    --ip;
-#else  
-  ip = _Unwind_GetIP (context);
-#endif
+  struct backtrace_state *lbstate;
+  struct mystate state = { 0, 0 };
+ 
+  lbstate = backtrace_create_state (NULL, 1, error_callback, NULL);
 
-  if (state->direct_output)
+  if (!BACKTRACE_SUPPORTED || (in_signal_handler && BACKTRACE_USES_MALLOC))
     {
-      bt_header(state->frame_number);
-      st_printf ("%p\n", (void*) ip);
+      /* If symbolic backtrace is not supported on this target, or would
+	 require malloc() and we are in a signal handler, go with a
+	 simple backtrace.  */
+
+      backtrace_simple (lbstate, 0, simple_callback, error_callback, &state);
     }
   else
     {
-      char addr_buf[GFC_XTOA_BUF_SIZE], func[1024], file[PATH_MAX];
-      char *p;
-      const char* addr = gfc_xtoa (ip, addr_buf, sizeof (addr_buf));
-      write (state->outfd, addr, strlen (addr));
-      write (state->outfd, "\n", 1);
-
-      if (! fd_gets (func, sizeof(func), state->infd))
-	{
-	  state->error = 1;
-	  goto done;
-	}
-      if (! fd_gets (file, sizeof(file), state->infd))
-	{
-	  state->error = 1;
-	  goto done;
-	}
-	    
-	for (p = func; *p != '\n' && *p != '\r'; p++)
-	  ;
-	*p = '\0';
-	
-	/* _start is a setup routine that calls main(), and main() is
-	   the frontend routine that calls some setup stuff and then
-	   calls MAIN__, so at this point we should stop.  */
-	if (strcmp (func, "_start") == 0 || strcmp (func, "main") == 0)
-	  return _URC_END_OF_STACK;
-	
-	bt_header (state->frame_number);
-	estr_write ("0x");
-	estr_write (addr);
-
-	if (func[0] != '?' && func[1] != '?')
-	  {
-	    estr_write (" in ");
-	    estr_write (func);
-	  }
-	
-	if (strncmp (file, "??", 2) == 0)
-	  estr_write ("\n");
-	else
-	  {
-	    estr_write (" at ");
-	    estr_write (file);
-	  }
+      /* libbacktrace uses mmap, which is safe to call from a signal handler
+	 (in practice, if not in theory).  Thus we can generate a symbolic
+	 backtrace, if debug symbols are available.  */
+
+      backtrace_full (lbstate, 0, full_callback, error_callback, &state);
+      if (state.try_simple)
+	backtrace_simple (lbstate, 0, simple_callback, error_callback, &state);
     }
+}
 
- done:
 
-  state->frame_number++;
-  
-  return _URC_NO_REASON;
-}
 
+/* Function called by the front-end translating the BACKTRACE intrinsic.  */
 
-/* Display the backtrace.  */
+extern void backtrace (void);
+export_proto (backtrace);
 
 void
 backtrace (void)
 {
-  bt_state state;
-  state.frame_number = 0;
-  state.error = 0;
-
-#if CAN_PIPE
-
-  if (addr2line_path == NULL)
-    goto fallback_noerr;
-
-  /* We attempt to extract file and line information from addr2line.  */
-  do
-  {
-    /* Local variables.  */
-    int f[2], pid, inp[2];
-
-    /* Don't output an error message if something goes wrong, we'll simply
-       fall back to printing the addresses.  */
-    if (pipe (f) != 0)
-      break;
-    if (pipe (inp) != 0)
-      break;
-    if ((pid = fork ()) == -1)
-      break;
-
-    if (pid == 0)
-      {
-	/* Child process.  */
-#define NUM_FIXEDARGS 7
-	char *arg[NUM_FIXEDARGS];
-	char *newenv[] = { NULL };
-
-	close (f[0]);
-
-	close (inp[1]);
-	if (dup2 (inp[0], STDIN_FILENO) == -1)
-	  _exit (1);
-	close (inp[0]);
-
-	close (STDERR_FILENO);
-
-	if (dup2 (f[1], STDOUT_FILENO) == -1)
-	  _exit (1);
-	close (f[1]);
-
-	arg[0] = addr2line_path;
-	arg[1] = (char *) "-e";
-	arg[2] = full_exe_path ();
-	arg[3] = (char *) "-f";
-	arg[4] = (char *) "-s";
-	arg[5] = (char *) "-C";
-	arg[6] = NULL;
-	execve (addr2line_path, arg, newenv);
-	_exit (1);
-#undef NUM_FIXEDARGS
-      }
-
-    /* Father process.  */
-    close (f[1]);
-    close (inp[0]);
-
-    state.outfd = inp[1];
-    state.infd = f[0];
-    state.direct_output = 0;
-    _Unwind_Backtrace (trace_function, &state);
-    if (state.error)
-      goto fallback;
-    close (inp[1]);
-    close (f[0]);
-    wait (NULL);
-    return;
-
-fallback:
-    estr_write ("** Something went wrong while running addr2line. **\n"
-		"** Falling back to a simpler backtrace scheme. **\n");
-  }
-  while (0);
-
-fallback_noerr:
-#endif /* CAN_PIPE */
-
-  /* Fallback to the simple backtrace without addr2line.  */
-  state.direct_output = 1;
-  _Unwind_Backtrace (trace_function, &state);
+  show_backtrace (0);
 }
-iexport(backtrace);
+
Index: libgfortran/runtime/compile_options.c
===================================================================
--- libgfortran/runtime/compile_options.c	(revision 226823)
+++ libgfortran/runtime/compile_options.c	(working copy)
@@ -30,7 +30,7 @@ see the files COPYING3 and COPYING.RUNTI
 compile_options_t compile_options;
 
 #ifndef LIBGFOR_MINIMAL
-volatile sig_atomic_t fatal_error_in_progress = 0;
+static volatile sig_atomic_t fatal_error_in_progress = 0;
 
 
 /* Helper function for backtrace_handler to write information about the
@@ -126,7 +126,7 @@ backtrace_handler (int signum)
 
   show_signal (signum);
   estr_write ("\nBacktrace for this error:\n");
-  backtrace ();
+  show_backtrace (1);
 
   /* Now reraise the signal.  We reactivate the signal's
      default handling, which is to terminate the process.
@@ -136,16 +136,6 @@ backtrace_handler (int signum)
   signal (signum, SIG_DFL);
   raise (signum);
 }
-
-
-/* Helper function for set_options because we need to access the
-   global variable options which is not seen in set_options.  */
-static void
-maybe_find_addr2line (void)
-{
-  if (options.backtrace == -1)
-    find_addr2line ();
-}
 #endif
 
 /* Set the usual compile-time options.  */
@@ -211,8 +201,6 @@ set_options (int num, int options[])
 #if defined(SIGXFSZ)
       signal (SIGXFSZ, backtrace_handler);
 #endif
-
-      maybe_find_addr2line ();
     }
 #endif
 }
Index: libgfortran/runtime/error.c
===================================================================
--- libgfortran/runtime/error.c	(revision 226823)
+++ libgfortran/runtime/error.c	(working copy)
@@ -173,7 +173,7 @@ sys_abort (void)
       || (options.backtrace == -1 && compile_options.backtrace == 1))
     {
       estr_write ("\nProgram aborted. Backtrace:\n");
-      backtrace ();
+      show_backtrace (0);
       signal (SIGABRT, SIG_DFL);
     }
 
Index: libgfortran/runtime/main.c
===================================================================
--- libgfortran/runtime/main.c	(revision 226823)
+++ libgfortran/runtime/main.c	(working copy)
@@ -70,162 +70,13 @@ determine_endianness (void)
 static int argc_save;
 static char **argv_save;
 
-static const char *exe_path;
-static bool please_free_exe_path_when_done;
 
-/* Save the path under which the program was called, for use in the
-   backtrace routines.  */
 void
-store_exe_path (const char * argv0)
+store_exe_path (const char * argv0 __attribute__ ((unused)))
 {
-#ifndef DIR_SEPARATOR   
-#define DIR_SEPARATOR '/'
-#endif
-
-  char *cwd, *path;
-
-  /* This can only happen if store_exe_path is called multiple times.  */
-  if (please_free_exe_path_when_done)
-    free ((char *) exe_path);
-
-  /* Reading the /proc/self/exe symlink is Linux-specific(?), but if
-     it works it gives the correct answer.  */
-#ifdef HAVE_READLINK
-  ssize_t len, psize = 256;
-  while (1)
-    {
-      path = xmalloc (psize);
-      len = readlink ("/proc/self/exe", path, psize);
-      if (len < 0)
-	{
-	  free (path);
-	  break;
-	}
-      else if (len < psize)
-	{
-	  path[len] = '\0';
-	  exe_path = strdup (path);
-	  free (path);
-	  please_free_exe_path_when_done = true;
-	  return;
-	}
-      /* The remaining option is len == psize.  */
-      free (path);
-      psize *= 4;
-    }
-#endif
-
-  /* If the path is absolute or on a simulator where argv is not set.  */
-#ifdef __MINGW32__
-  if (argv0 == NULL
-      || ('A' <= argv0[0] && argv0[0] <= 'Z' && argv0[1] == ':')
-      || ('a' <= argv0[0] && argv0[0] <= 'z' && argv0[1] == ':')
-      || (argv0[0] == '/' && argv0[1] == '/')
-      || (argv0[0] == '\\' && argv0[1] == '\\'))
-#else
-  if (argv0 == NULL || argv0[0] == DIR_SEPARATOR)
-#endif
-    {
-      exe_path = argv0;
-      please_free_exe_path_when_done = false;
-      return;
-    }
-
-#ifdef HAVE_GETCWD
-  size_t cwdsize = 256;
-  while (1)
-    {
-      cwd = xmalloc (cwdsize);
-      if (getcwd (cwd, cwdsize))
-	break;
-      else if (errno == ERANGE)
-	{
-	  free (cwd);
-	  cwdsize *= 4;
-	}
-      else
-	{
-	  free (cwd);
-	  cwd = NULL;
-	  break;
-	}
-    }
-#else
-  cwd = NULL;
-#endif
-
-  if (!cwd)
-    {
-      exe_path = argv0;
-      please_free_exe_path_when_done = false;
-      return;
-    }
-
-  /* exe_path will be cwd + "/" + argv[0] + "\0".  This will not work
-     if the executable is not in the cwd, but at this point we're out
-     of better ideas.  */
-  size_t pathlen = strlen (cwd) + 1 + strlen (argv0) + 1;
-  path = xmalloc (pathlen);
-  snprintf (path, pathlen, "%s%c%s", cwd, DIR_SEPARATOR, argv0);
-  free (cwd);
-  exe_path = path;
-  please_free_exe_path_when_done = true;
-}
-
-
-/* Return the full path of the executable.  */
-char *
-full_exe_path (void)
-{
-  return (char *) exe_path;
-}
-
-
-#ifndef HAVE_STRTOK_R
-static char*
-gfstrtok_r (char *str, const char *delim, 
-	    char **saveptr __attribute__ ((unused)))
-{
-  return strtok (str, delim);
-}
-#define strtok_r gfstrtok_r
-#endif
-
-char *addr2line_path;
-
-/* Find addr2line and store the path.  */
-
-void
-find_addr2line (void)
-{
-#ifdef HAVE_ACCESS
-#define A2L_LEN 11
-  char *path = secure_getenv ("PATH");
-  if (!path)
-    return;
-  char *tp = strdup (path);
-  if (!tp)
-    return;
-  size_t n = strlen (path);
-  char *ap = xmalloc (n + A2L_LEN);
-  char *saveptr;
-  for (char *str = tp;; str = NULL)
-    {
-      char *token = strtok_r (str, ":", &saveptr);
-      if (!token)
-	break;
-      size_t toklen = strlen (token);
-      memcpy (ap, token, toklen);
-      memcpy (ap + toklen, "/addr2line", A2L_LEN);
-      if (access (ap, R_OK|X_OK) == 0)
-	{
-	  addr2line_path = strdup (ap);
-	  break;
-	}
-    }
-  free (tp);
-  free (ap);
-#endif
+  /* This function is now useless, but is retained due to ABI compatibility.
+    Remove when bumping the library ABI.  */
+  ;
 }
 
 
@@ -236,7 +87,6 @@ set_args (int argc, char **argv)
 {
   argc_save = argc;
   argv_save = argv;
-  store_exe_path (argv[0]);
 }
 iexport(set_args);
 
@@ -279,9 +129,6 @@ init (void)
   /* if (argc > 1 && strcmp(argv[1], "--resume") == 0) resume();  */
 #endif
 
-  if (options.backtrace == 1)
-    find_addr2line ();
-
   random_seed_i4 (NULL, NULL, NULL);
 }
 
@@ -292,9 +139,4 @@ static void __attribute__((destructor))
 cleanup (void)
 {
   close_units ();
-  
-  if (please_free_exe_path_when_done)
-    free ((char *) exe_path);
-
-  free (addr2line_path);
 }
Index: libgfortran/runtime/minimal.c
===================================================================
--- libgfortran/runtime/minimal.c	(revision 226823)
+++ libgfortran/runtime/minimal.c	(working copy)
@@ -53,8 +53,6 @@ int big_endian = 0;
 static int argc_save;
 static char **argv_save;
 
-static const char *exe_path;
-
 /* recursion_check()-- It's possible for additional errors to occur
  * during fatal error processing.  We detect this condition here and
  * exit with code 4 immediately. */
@@ -163,14 +161,6 @@ internal_error (st_parameter_common *cmp
 }
 
 
-/* Return the full path of the executable.  */
-char *
-full_exe_path (void)
-{
-  return (char *) exe_path;
-}
-
-
 /* Set the saved values of the command line arguments.  */
 
 void
@@ -178,7 +168,6 @@ set_args (int argc, char **argv)
 {
   argc_save = argc;
   argv_save = argv;
-  exe_path = argv[0];
 }
 iexport(set_args);
 
Index: gcc/testsuite/gfortran.dg/backtrace_1.f90
===================================================================
--- gcc/testsuite/gfortran.dg/backtrace_1.f90	(revision 0)
+++ gcc/testsuite/gfortran.dg/backtrace_1.f90	(working copy)
@@ -0,0 +1,10 @@
+! { dg-do run }
+! 
+! Check that BACKTRACE is available on all targets. We cannot actually
+! check its output, but we should at least be able to call it, then exit
+! normally.
+!
+program test
+  call backtrace
+  stop
+end program test
