Use atomic load/store to access static backtrace state pointer
authorJanne Blomqvist <jb@gcc.gnu.org>
Sun, 2 Dec 2018 15:12:44 +0000 (17:12 +0200)
committerJanne Blomqvist <jb@gcc.gnu.org>
Sun, 2 Dec 2018 15:12:44 +0000 (17:12 +0200)
As the static backtrace state pointer can be accessed from multiple
threads, use atomics to access it.

Regtested on x86_64-pc-linux-gnu.

libgfortran/ChangeLog:

2018-12-02  Janne Blomqvist  <jb@gcc.gnu.org>

PR libfortran/88137
* runtime/backtrace.c (show_backtrace): Use atomic load/store to
access the static lbstate pointer.

From-SVN: r266724

libgfortran/ChangeLog
libgfortran/runtime/backtrace.c

index f1f7cbe..42dbc80 100644 (file)
@@ -1,3 +1,9 @@
+2018-12-02  Janne Blomqvist  <jb@gcc.gnu.org>
+
+       PR libfortran/88137
+       * runtime/backtrace.c (show_backtrace): Use atomic load/store to
+       access the static lbstate pointer.
+
 2018-11-30  Janne Blomqvist  <jb@gcc.gnu.org>
 
        PR libfortran/88137
index 3fc973a..93ea14a 100644 (file)
@@ -149,15 +149,20 @@ show_backtrace (bool in_signal_handler)
   /* Note that libbacktrace allows the state to be accessed from
      multiple threads, so we don't need to use a TLS variable for the
      state here.  */
-  static struct backtrace_state *lbstate;
+  static struct backtrace_state *lbstate_saved;
+  struct backtrace_state *lbstate;
   struct mystate state = { 0, false, in_signal_handler };
 
+  lbstate = __atomic_load_n (&lbstate_saved, __ATOMIC_RELAXED);
   if (!lbstate)
-    lbstate = backtrace_create_state (NULL, __gthread_active_p (),
-                                     error_callback, NULL);
-
-  if (lbstate == NULL)
-    return;
+    {
+      lbstate = backtrace_create_state (NULL, __gthread_active_p (),
+                                       error_callback, NULL);
+      if (lbstate)
+       __atomic_store_n (&lbstate_saved, lbstate, __ATOMIC_RELAXED);
+      else
+       return;
+    }
 
   if (!BACKTRACE_SUPPORTED || (in_signal_handler && BACKTRACE_USES_MALLOC))
     {