Use atomic load/store to access static backtrace state pointer
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>
Backport from trunk
PR libfortran/88137
* runtime/backtrace.c (show_backtrace): Use atomic load/store to
access the static lbstate pointer.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-8-branch@266725 138bc75d-0d04-0410-961f-82ee72b054a4
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 71e9863..bced736 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,10 @@
+2018-12-02 Janne Blomqvist <jb@gcc.gnu.org>
+
+ Backport from trunk
+ 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>
Backport from trunk
diff --git a/libgfortran/runtime/backtrace.c b/libgfortran/runtime/backtrace.c
index 481f51c..474c100 100644
--- a/libgfortran/runtime/backtrace.c
+++ b/libgfortran/runtime/backtrace.c
@@ -138,15 +138,20 @@
/* 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))
{