Bug 36044 - user-requested backtrace
Summary: user-requested backtrace
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libfortran (show other bugs)
Version: 4.4.0
: P3 enhancement
Target Milestone: ---
Assignee: janus
URL: http://gcc.gnu.org/ml/fortran/2012-03...
Keywords: patch
Depends on:
Blocks:
 
Reported: 2008-04-25 12:19 UTC by Janus Weil
Modified: 2012-12-20 19:35 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2008-04-28 21:36:17


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Janus Weil 2008-04-25 12:19:19 UTC
It would be nice to have an intrinsic function to generate a user-requested backtrace, like ifort's TRACEBACKQQ. Of course this would be a non-standard extension, but a useful one which many other compilers also provide.

There has already been some discussion on this in PR30498, with suggested workarounds like producing an FPE with "1.0/0.0" or calling 'kill' via ISO_C_BINDING to generate a backtrace. But these of course terminate the program.

For debugging purposes it can be helpful to generate a backtrace at some point while keeping the program running, which is what e.g. TRACEBACKQQ does.
Comment 1 Francois-Xavier Coudert 2008-04-27 18:43:25 UTC
I think compiling with -fbacktrace and calling the STOP intrinsic should emit a backtrace. Maybe not enough, but still useful.
Comment 2 Janus Weil 2008-04-28 15:44:47 UTC
(In reply to comment #1)
> I think compiling with -fbacktrace and calling the STOP intrinsic should emit a
> backtrace. 

I don't think it does. Anyway I'm looking for a solution that keeps the program running after the backtrace.
Comment 3 Tobias Burnus 2008-04-28 16:41:56 UTC
> > I think compiling with -fbacktrace and calling the STOP intrinsic should
> > emit a backtrace.

I think it should not. For abort(), I think a backtrace is ok, but for STOP there should be no backtrace. Using stop is a quite normal way to stop a program because a condition has not be met, e.g

  stop 'Could not file "inp"'

If one finds afterwards dozens of lines of backtrace the actual message is no longer visible. In my opinion, ifort shows too often a backtrace.

> I don't think it does.
Try abort(). (Though I do not recall whether it works, I think it does.)

> Anyway I'm looking for a solution that keeps the
> program running after the backtrace.

This can be sometimes indeed be handy, though I have never used it.
Comment 4 Thomas Koenig 2008-04-28 21:36:17 UTC
Confirmed, this would indeed be useful.
Comment 5 Francois-Xavier Coudert 2009-02-22 22:33:39 UTC
(In reply to comment #3)
> Try abort(). (Though I do not recall whether it works, I think it does.)

Does not work. abort() raises a SIGABRT, and we only catch SIGSEGV, SIGBUS, SIGILL and SIGFPE.

>> Anyway I'm looking for a solution that keeps the
>> program running after the backtrace.

One such solution that I can see (other than adding a new intrinsic) is to modify the library to also catch SIGUSR2 and generate a backtrace when it's received (untested patch below); that way, a backtrace can be emitted without the code stopping, either

  -- programmaticaly by calling the KILL and GETPID intrinsics, or the POSIX functions via ISO_C_BINDING
  -- by the user sending the signal from another terminal, to know where his program is stuck

The only issue I see with that is that SIGUSR2 is a symbolic constant, not available in Fortran code, so that the user needs to know what (potentialy nonportable) signal number it corresponds to.





diff -rpu libgfortran/runtime/compile_options.c libgfortran.new/runtime/compile_options.c
--- libgfortran/runtime/compile_options.c	2009-02-22 23:25:25.000000000 +0100
+++ libgfortran.new/runtime/compile_options.c	2009-02-22 23:30:20.000000000 +0100
@@ -73,6 +73,13 @@ handler (int signum)
 	desc = "Floating-point exception";
 	break;
 #endif
+
+#if defined(SIGUSR2)
+      case SIGUSR2:
+	name = "SIGUSR2";
+	desc = "User-defined signal";
+	break;
+#endif
     }
 
   if (name)
@@ -80,6 +87,16 @@ handler (int signum)
   else
     st_printf ("\nProgram received signal %d.\n", signum);
 
+#if defined(SIGUSR2)
+  if (signum == SIGUSR2
+      && (options.backtrace == 1
+	  || (options.backtrace == -1 && compile_options.backtrace == 1)))
+  {
+    show_backtrace ();
+    return;
+  }
+#endif
+
   sys_exit (5);
 }
 
Comment 6 Jerry DeLisle 2009-02-23 04:37:23 UTC
If anyone is looking into this, please let me know if there are any specific posix calls needed that I should put into the gfc_posix module. ( Priority wise.)
Comment 7 Francois-Xavier Coudert 2012-03-03 07:45:51 UTC
Patch was proposed at http://gcc.gnu.org/ml/fortran/2012-03/msg00015.html
Comment 8 janus 2012-12-19 16:30:20 UTC
Taking this one. Latest patch:

http://gcc.gnu.org/ml/fortran/2012-12/msg00126.html
Comment 9 janus 2012-12-20 18:15:19 UTC
Author: janus
Date: Thu Dec 20 18:15:13 2012
New Revision: 194648

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=194648
Log:
2012-12-20  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/36044
	* gfortran.h (gfc_isym_id): Add GFC_ISYM_BACKTRACE.
	* intrinsic.c (add_subroutines): Add "backtrace".
	* intrinsic.texi (BACKTRACE): Document BACKTRACE intrinsic.


2012-12-20  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/36044
	* gfortran.map: Add _gfortran_backtrace.
	* libgfortran.h: Rename 'show_backtrace' and export.
	* runtime/backtrace.c (show_backtrace): Rename to 'backtrace'.
	Don't show message. Close file descriptor. Export.
	* runtime/compile_options.c (backtrace_handler): Renamed
	'show_backtrace'. Move message outside.
	* runtime/error.c (sys_abort): Ditto.

Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/gfortran.h
    trunk/gcc/fortran/intrinsic.c
    trunk/gcc/fortran/intrinsic.texi
    trunk/libgfortran/ChangeLog
    trunk/libgfortran/gfortran.map
    trunk/libgfortran/libgfortran.h
    trunk/libgfortran/runtime/backtrace.c
    trunk/libgfortran/runtime/compile_options.c
    trunk/libgfortran/runtime/error.c
Comment 10 janus 2012-12-20 19:35:54 UTC
r194648 implements an intrinsic BACKTRACE routine. Closing as fixed.