public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [gfortran,patch] Allow backtracing non-library errors
@ 2007-08-04 21:56 FX Coudert
  2007-08-05  9:20 ` Thomas Koenig
  0 siblings, 1 reply; 9+ messages in thread
From: FX Coudert @ 2007-08-04 21:56 UTC (permalink / raw)
  To: Fortran List, gcc-patches list

[-- Attachment #1: Type: text/plain, Size: 1637 bytes --]

Attached patch allows the library, when asked to backtrace by use of  
the -fbacktrace option, to setup signal handlers on the common deadly  
signals SIG{SEGV,ILL,BUG,FPE}, and to emit backtrace information from  
these signal handlers. This allows the following type of debugging:

$ cat u.f90
   integer, pointer :: i
   i = 5
   end

$ gfortran -g u.f90 -fbacktrace && ./a.out

Program received signal 11 (SIGSEGV): Segmentation fault.

Backtrace for this error:
   + function __restore_rt (0x417830)
     from file libgcc2.c
   + in the main program
     at line 2 of file u.f90
   + function __libc_start_main (0x412DB8)

$ cat u2.f90
   integer :: i
   i = 0
   i = 2 / i
   print *, i
   end

$ gfortran -g u2.f90 -fbacktrace && ./a.out

Program received signal 8 (SIGFPE): Floating-point exception.

Backtrace for this error:
   + function __restore_rt (0x4178A0)
     from file libgcc2.c
   + in the main program
     at line 3 of file u2.f90
   + function __libc_start_main (0x412E28)

$ cat u3.f90
   real :: x
   x = -1
   x = sqrt(x)
   print *, x
   end

$ gfortran -g u3.f90 -fbacktrace && ./a.out
             NaN

$ gfortran -g u3.f90 -fbacktrace -ffpe-trap=invalid && ./a.out

Program received signal 8 (SIGFPE): Floating-point exception.

Backtrace for this error:
   + function __restore_rt (0x4178B0)
     from file libgcc2.c
   + in the main program
     at line 3 of file u3.f90
   + function __libc_start_main (0x412E38)




Bootstrapped and regtested on x86_64-linux, no testcase because of  
the nature of the patch, documentation adjusted to describe the new  
behaviour. OK to commit?
FX


:ADDPATCH fortran:

[-- Attachment #2: backtrace.ChangeLog --]
[-- Type: application/octet-stream, Size: 524 bytes --]

2007-08-04  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
	    Tobias Burnus  <burnus@gcc.gnu.org>

	PR fortran/31189
	* runtime/backtrace.c (show_backtrace): Skip _gfortrani_handler
	when displaying backtrace.
	* runtime/compile_options.c: Include <signal.h>.
	(handler): New function.
	(set_options): Set signal handlers for backtrace.
	* libgfortran.h (handler): Add prototype.


2007-08-04  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>

	PR fortran/31189
	* invoke.texi (-fbacktrace): Document the new behaviour.

[-- Attachment #3: backtrace.diff --]
[-- Type: application/octet-stream, Size: 3820 bytes --]

Index: libgfortran/runtime/backtrace.c
===================================================================
--- libgfortran/runtime/backtrace.c	(revision 127211)
+++ libgfortran/runtime/backtrace.c	(working copy)
@@ -223,7 +223,8 @@ show_backtrace (void)
 	    /* Try to recognize the internal libgfortran functions.  */
 	    if (strncasecmp (func, "*_gfortran", 10) == 0
 		|| strncasecmp (func, "_gfortran", 9) == 0
-		|| strcmp (func, "main") == 0 || strcmp (func, "_start") == 0)
+		|| strcmp (func, "main") == 0 || strcmp (func, "_start") == 0
+		|| strcmp (func, "_gfortrani_handler") == 0)
 	      continue;
 
 	    if (local_strcasestr (str[i], "libgfortran.so") != NULL
Index: libgfortran/runtime/compile_options.c
===================================================================
--- libgfortran/runtime/compile_options.c	(revision 127211)
+++ libgfortran/runtime/compile_options.c	(working copy)
@@ -31,10 +31,61 @@ Boston, MA 02110-1301, USA.  */
 
 #include "libgfortran.h"
 
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
 
 /* Useful compile-time options will be stored in here.  */
 compile_options_t compile_options;
 
+
+/* A signal handler to allow us to output a backtrace.  */
+void
+handler (int signum)
+{
+  const char * name = NULL, * desc = NULL;
+
+  switch (signum)
+    {
+#if defined(SIGSEGV)
+      case SIGSEGV:
+	name = "SIGSEGV";
+	desc = "Segmentation fault";
+	break;
+#endif
+
+#if defined(SIGBUS)
+      case SIGBUS:
+	name = "SIGBUS";
+	desc = "Bus error";
+	break;
+#endif
+
+#if defined(SIGILL)
+      case SIGILL:
+	name = "SIGILL";
+	desc = "Illegal instruction";
+	break;
+#endif
+
+#if defined(SIGFPE)
+      case SIGFPE:
+	name = "SIGFPE";
+	desc = "Floating-point exception";
+	break;
+#endif
+    }
+
+  if (name)
+    st_printf ("\nProgram received signal %d (%s): %s.\n", signum, name, desc);
+  else
+    st_printf ("\nProgram received signal %d.\n", signum);
+
+  sys_exit (5);
+}
+
+
 /* Set the usual compile-time options.  */
 extern void set_options (int , int []);
 export_proto(set_options);
@@ -56,6 +107,31 @@ set_options (int num, int options[])
     compile_options.sign_zero = options[5];
   if (num >= 7)
     compile_options.bounds_check = options[6];
+
+  /* If backtrace is required, we set signal handlers on most common
+     signals.  */
+#if defined(HAVE_SIGNAL_H) && (defined(SIGSEGV) || defined(SIGBUS) \
+			       || defined(SIGILL) || defined(SIGFPE))
+  if (compile_options.backtrace)
+    {
+#if defined(SIGSEGV)
+      signal (SIGSEGV, handler);
+#endif
+
+#if defined(SIGBUS)
+      signal (SIGBUS, handler);
+#endif
+
+#if defined(SIGILL)
+      signal (SIGILL, handler);
+#endif
+
+#if defined(SIGFPE)
+      signal (SIGFPE, handler);
+#endif
+    }
+#endif
+
 }
 
 
Index: libgfortran/libgfortran.h
===================================================================
--- libgfortran/libgfortran.h	(revision 127211)
+++ libgfortran/libgfortran.h	(working copy)
@@ -373,6 +373,9 @@ options_t;
 extern options_t options;
 internal_proto(options);
 
+extern void handler (int);
+internal_proto(handler);
+
 
 /* Compile-time options that will influence the library.  */
 
Index: invoke.texi
===================================================================
--- invoke.texi	(revision 127211)
+++ invoke.texi	(working copy)
@@ -542,7 +542,9 @@ zero), @samp{overflow} (overflow in a fl
 @opindex @code{fbacktrace}
 @cindex backtrace
 @cindex trace
-Specify that, when a runtime error is encountered, the Fortran runtime
+Specify that, when a runtime error is encountered or a deadly signal is
+emitted (segmentation fault, illegal instruction, bus error or
+floating-point exception), the Fortran runtime
 library should output a backtrace of the error.  This option
 only has influence for compilation of the Fortran main program.
 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [gfortran,patch] Allow backtracing non-library errors
  2007-08-04 21:56 [gfortran,patch] Allow backtracing non-library errors FX Coudert
@ 2007-08-05  9:20 ` Thomas Koenig
  2007-08-05  9:38   ` FX Coudert
                     ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Thomas Koenig @ 2007-08-05  9:20 UTC (permalink / raw)
  To: FX Coudert; +Cc: Fortran List, gcc-patches list

On Sat, 2007-08-04 at 22:55 +0100, FX Coudert wrote:

:REVIEWMAIL:

> Bootstrapped and regtested on x86_64-linux, no testcase because of  
> the nature of the patch, documentation adjusted to describe the new  
> behaviour. OK to commit?
> FX

Hi FX,

the patch compiles and regtests ok on i686-pc-linux-gnu (Debian
testing).

I can't get it to produce meaningful backtraces, though:

$ cat u3.f90 
   real :: x
   x = -1
   x = sqrt(x)
   print *, x
   end
$ gfortran -g  -fbacktrace -ffpe-trap=invalid u3.f90 && ./a.out

Program received signal 8 (SIGFPE): Floating-point exception.

Backtrace for this error:
  + /lib/i686/cmov/libc.so.6 [0xb7ce1208]
  + /lib/i686/cmov/libc.so.6(__libc_start_main+0xe0) [0xb7ccd030]

Backtracing from a normal library function works:

$ cat matmul.f90 
program main
  real, dimension (3,3) :: a
  real, allocatable :: b(:)
  allocate(b(2))
  call random_number(a)
  call random_number(b)
  print *,matmul(a,b)
end program main
$ gfortran -g -fbacktrace matmul.f90 && ./a.out
Fortran runtime error: dimension of array B incorrect in MATMUL
intrinsic

Backtrace for this error:
  + in the main program
    at line 7 of file matmul.f90
  + /lib/i686/cmov/libc.so.6(__libc_start_main+0xe0) [0xb7db4030]

Any ideas?

	Thomas

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [gfortran,patch] Allow backtracing non-library errors
  2007-08-05  9:20 ` Thomas Koenig
@ 2007-08-05  9:38   ` FX Coudert
  2007-08-05 11:46     ` Thomas Koenig
  2007-08-05  9:54   ` Tobias Burnus
  2007-08-11 10:35   ` FX Coudert
  2 siblings, 1 reply; 9+ messages in thread
From: FX Coudert @ 2007-08-05  9:38 UTC (permalink / raw)
  To: Thomas Koenig; +Cc: Fortran List, gcc-patches list

> $ gfortran -g  -fbacktrace -ffpe-trap=invalid u3.f90 && ./a.out
>
> Program received signal 8 (SIGFPE): Floating-point exception.
>
> Backtrace for this error:
>   + /lib/i686/cmov/libc.so.6 [0xb7ce1208]
>   + /lib/i686/cmov/libc.so.6(__libc_start_main+0xe0) [0xb7ccd030]

If you remove -fbacktrace and catch the SIGFPE with gdb, what is the  
gdb backtrace?

FX

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [gfortran,patch] Allow backtracing non-library errors
  2007-08-05  9:20 ` Thomas Koenig
  2007-08-05  9:38   ` FX Coudert
@ 2007-08-05  9:54   ` Tobias Burnus
  2007-08-11 10:35   ` FX Coudert
  2 siblings, 0 replies; 9+ messages in thread
From: Tobias Burnus @ 2007-08-05  9:54 UTC (permalink / raw)
  To: Thomas Koenig; +Cc: FX Coudert, Fortran List, gcc-patches list

Hi Thomas,

Thomas Koenig wrote:
> I can't get it to produce meaningful backtraces, though:
>    x = sqrt(x)
> $ gfortran -g  -fbacktrace -ffpe-trap=invalid u3.f90 && ./a.out
>
> Program received signal 8 (SIGFPE): Floating-point exception.
> Backtrace for this error:
>   + /lib/i686/cmov/libc.so.6 [0xb7ce1208]
>   + /lib/i686/cmov/libc.so.6(__libc_start_main+0xe0) [0xb7ccd030]
>   
For your test case I get:

Program received signal 8 (SIGFPE): Floating-point exception.
Backtrace for this error:
  + /lib64/libc.so.6 [0x2aefddcf1b20]
  + in the main program
    at line 3 of file a.f90
  + /lib64/libc.so.6(__libc_start_main+0xf4) [0x2aefddcdeb54]

However, using
  integer, pointer :: x
  x = 5
  end

I also don't get a useful backtrace:
Program received signal 11 (SIGSEGV): Segmentation fault.
Backtrace for this error:
  + /lib64/libc.so.6 [0x2ab873638b20]
  + function _fini (0x400850)

but gdb has also no better backtrace:
Program received signal SIGILL, Illegal instruction.
#0  0x00000000004007ed in _fini ()
#1  0x00002b154ef6eb96 in ?? () from /lib64/ld-linux-x86-64.so.2
#2  0x00002b154f9042ce in exit () from /lib64/libc.so.6
#3  0x00002b154f8eeb5b in __libc_start_main () from /lib64/libc.so.6
#4  0x00000000004005e9 in _start ()

Ifort has for whatever reason a better backtrace in this case (with
-traceback and also in gdb):

Program received signal SIGSEGV, Segmentation fault.
0x000000000040279b in main$aa_$BLK () at aa.f90:2
2       x = 5
Current language:  auto; currently fortran
#0  0x000000000040279b in main$aa_$BLK () at aa.f90:2
#1  0x000000000040276a in main ()


Tobias

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [gfortran,patch] Allow backtracing non-library errors
  2007-08-05  9:38   ` FX Coudert
@ 2007-08-05 11:46     ` Thomas Koenig
  2007-08-05 11:56       ` FX Coudert
  0 siblings, 1 reply; 9+ messages in thread
From: Thomas Koenig @ 2007-08-05 11:46 UTC (permalink / raw)
  To: FX Coudert; +Cc: Fortran List, gcc-patches list

On Sun, 2007-08-05 at 10:38 +0100, FX Coudert wrote:

Hi FX,

> If you remove -fbacktrace and catch the SIGFPE with gdb, what is the  
> gdb backtrace?

$ gfortran -g   -ffpe-trap=invalid u3.f90
$ gdb ./a.out
GNU gdb 6.4.90-debian
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you
are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for
details.
This GDB was configured as "i486-linux-gnu"...Using host libthread_db
library "/lib/i686/cmov/libthread_db.so.1".

(gdb) r
Starting program: /tmp/a.out 

Program received signal SIGFPE, Arithmetic exception.
0x080485ea in MAIN__ () at u3.f90:3
3          x = sqrt(x)
Current language:  auto; currently fortran
(gdb) bt
#0  0x080485ea in MAIN__ () at u3.f90:3
(gdb) 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [gfortran,patch] Allow backtracing non-library errors
  2007-08-05 11:46     ` Thomas Koenig
@ 2007-08-05 11:56       ` FX Coudert
  2007-08-05 12:52         ` Thomas Koenig
  0 siblings, 1 reply; 9+ messages in thread
From: FX Coudert @ 2007-08-05 11:56 UTC (permalink / raw)
  To: Thomas Koenig; +Cc: Fortran List, gcc-patches list

> Program received signal SIGFPE, Arithmetic exception.
> 0x080485ea in MAIN__ () at u3.f90:3
> 3          x = sqrt(x)
> Current language:  auto; currently fortran

It's really weird, cause it's not the same address as you had with  
your first post:

> $ cat u3.f90
>    real :: x
>    x = -1
>    x = sqrt(x)
>    print *, x
>    end
> $ gfortran -g  -fbacktrace -ffpe-trap=invalid u3.f90 && ./a.out
>
> Program received signal 8 (SIGFPE): Floating-point exception.
>
> Backtrace for this error:
>   + /lib/i686/cmov/libc.so.6 [0xb7ce1208]
>   + /lib/i686/cmov/libc.so.6(__libc_start_main+0xe0) [0xb7ccd030]

Could you try to do both tests with the same executable, setting  
GFORTRAN_ERROR_BACKTRACE=1 when run without gdb?

Thanks,
FX

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [gfortran,patch] Allow backtracing non-library errors
  2007-08-05 11:56       ` FX Coudert
@ 2007-08-05 12:52         ` Thomas Koenig
  0 siblings, 0 replies; 9+ messages in thread
From: Thomas Koenig @ 2007-08-05 12:52 UTC (permalink / raw)
  To: FX Coudert; +Cc: Fortran List, gcc-patches list

On Sun, 2007-08-05 at 12:56 +0100, FX Coudert wrote:

> Could you try to do both tests with the same executable, setting  
> GFORTRAN_ERROR_BACKTRACE=1 when run without gdb?

$ gfortran -g   -ffpe-trap=invalid u3.f90
$ gdb ./a.out
GNU gdb 6.4.90-debian
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you
are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for
details.
This GDB was configured as "i486-linux-gnu"...Using host libthread_db
library "/lib/i686/cmov/libthread_db.so.1".

(gdb) r
Starting program: /tmp/a.out 

Program received signal SIGFPE, Arithmetic exception.
0x080485ea in MAIN__ () at u3.f90:3
3          x = sqrt(x)
Current language:  auto; currently fortran
(gdb) q
The program is running.  Exit anyway? (y or n) y
$ GFORTRAN_ERROR_BACKTRACE=1 ./a.out
Floating point exception

Looks like GFORTRAN_ERROR_BACKTRACE isn't working right...

	Thomas

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [gfortran,patch] Allow backtracing non-library errors
  2007-08-05  9:20 ` Thomas Koenig
  2007-08-05  9:38   ` FX Coudert
  2007-08-05  9:54   ` Tobias Burnus
@ 2007-08-11 10:35   ` FX Coudert
  2007-08-11 21:53     ` FX Coudert
  2 siblings, 1 reply; 9+ messages in thread
From: FX Coudert @ 2007-08-11 10:35 UTC (permalink / raw)
  To: Thomas Koenig; +Cc: Fortran List, gcc-patches list

:ADDPATCH fortran:

> the patch compiles and regtests ok on i686-pc-linux-gnu (Debian
> testing).
>
> I can't get it to produce meaningful backtraces, though

The answer I got from the glibc mailing-list is that it's a bug in  
glibc or/and the kernel, which is likely to have been fixed in later  
glibc/kernel releases. What's more, the backtrace patch gives  
meaningful backtraces except for the top frame; for our small  
testcases, it's quite unusable, but for more complex programs, where  
the backtrace can contain hundreds of frames, it's probably of less  
importance. With these reasons in mind, I'd like to ask for a review  
of that patch, in its current state. Of course, if there emerge a  
consensus that it's not the right thing to do, I'll withdraw it.

PS: Special offer for the second week-end of august: with all the  
people on vacation, consensus starts at 1 maintainer! ;-)

Bootstrapped and regtested on x86_64-linux, OK for mainline?

FX

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [gfortran,patch] Allow backtracing non-library errors
  2007-08-11 10:35   ` FX Coudert
@ 2007-08-11 21:53     ` FX Coudert
  0 siblings, 0 replies; 9+ messages in thread
From: FX Coudert @ 2007-08-11 21:53 UTC (permalink / raw)
  To: FX Coudert; +Cc: Thomas Koenig, Fortran List, gcc-patches list

:REVIEWMAIL:

Committed as rev. 127364 after Thomas OKed it on IRC.

FX

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2007-08-11 21:53 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-08-04 21:56 [gfortran,patch] Allow backtracing non-library errors FX Coudert
2007-08-05  9:20 ` Thomas Koenig
2007-08-05  9:38   ` FX Coudert
2007-08-05 11:46     ` Thomas Koenig
2007-08-05 11:56       ` FX Coudert
2007-08-05 12:52         ` Thomas Koenig
2007-08-05  9:54   ` Tobias Burnus
2007-08-11 10:35   ` FX Coudert
2007-08-11 21:53     ` FX Coudert

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).