https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84439

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |iant at google dot com
            Version|4.8.5                       |7.3.1

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
Confirmed.  With glibc 2.22 I get into

99999 calls to backtrace()

Could not print backtrace: mmap: Cannot allocate memory
#0  0x7f7a4717268a
#1  0x4008c8
#2  0x40082f
#3  0x400814
#4  0x4007f9
#5  0x4007de
#6  0x400907
#7  0x40094a
#8  0x7f7a466816d4
#9  0x400718
#10  0xffffffffffffffff
***** calls to backtrace()

Could not print backtrace: mmap: Cannot allocate memory
#0  0x7f7a4717268a
#1  0x4008c8
#2  0x40082f
#3  0x400814
#4  0x4007f9
#5  0x4007de
#6  0x400907
#7  0x40094a
#8  0x7f7a466816d4
#9  0x400718
#10  0xffffffffffffffff

while with glibc 2.26 I get

...
Could not print backtrace: mmap: Cannot allocate memory
#0  0x7f928d0a750a
#1  0x4008a8
#2  0x40080f
#3  0x4007f4
#4  0x4007d9
#5  0x4007be
#6  0x4008e4
#7  0x400927
#8  0x7f928c54ff49
#9  0x4006f9
#10  0xffffffffffffffff
 4857 calls to backtrace()

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.


I think the issue lies within libgfortran show_backtrace which does

  lbstate = backtrace_create_state (NULL, __gthread_active_p (),
                                    error_callback, NULL);

for each call to backtrace ().  There doesn't seem to be a corresponding
backtrace_free_state API so we leak whatever is allocated here.  Ian?

I suppose a workaround would be to make lbstate static and only initialize
it if NULL.

Index: libgfortran/runtime/backtrace.c
===================================================================
--- libgfortran/runtime/backtrace.c     (revision 258030)
+++ libgfortran/runtime/backtrace.c     (working copy)
@@ -135,11 +135,12 @@ full_callback (void *data, uintptr_t pc,
 void
 show_backtrace (bool in_signal_handler)
 {
-  struct backtrace_state *lbstate;
+  static struct backtrace_state *lbstate;
   struct mystate state = { 0, false, in_signal_handler };

-  lbstate = backtrace_create_state (NULL, __gthread_active_p (),
-                                   error_callback, NULL);
+  if (!lbstate)
+    lbstate = backtrace_create_state (NULL, __gthread_active_p (),
+                                     error_callback, NULL);

   if (lbstate == NULL)
     return;

note the above is wrong when the __gthread_active_p () state changes.

Ian, I suppose there should be an API to deallocate the state?

Reply via email to