diff options
author | Janne Blomqvist <jb@gcc.gnu.org> | 2018-12-02 17:12:44 +0200 |
---|---|---|
committer | Janne Blomqvist <jb@gcc.gnu.org> | 2018-12-02 17:12:44 +0200 |
commit | df996c3fd2115d8ed8f44072f00728fbe5dc2d6b (patch) | |
tree | 5b41da21c104545478a484a60a3e2e5c11ef379c /libgfortran/runtime/backtrace.c | |
parent | 4a82df9a389506e2a34aa22d9a751c2be834e238 (diff) | |
download | gcc-df996c3fd2115d8ed8f44072f00728fbe5dc2d6b.zip gcc-df996c3fd2115d8ed8f44072f00728fbe5dc2d6b.tar.gz gcc-df996c3fd2115d8ed8f44072f00728fbe5dc2d6b.tar.bz2 |
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>
PR libfortran/88137
* runtime/backtrace.c (show_backtrace): Use atomic load/store to
access the static lbstate pointer.
From-SVN: r266724
Diffstat (limited to 'libgfortran/runtime/backtrace.c')
-rw-r--r-- | libgfortran/runtime/backtrace.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/libgfortran/runtime/backtrace.c b/libgfortran/runtime/backtrace.c index 3fc973a..93ea14a 100644 --- a/libgfortran/runtime/backtrace.c +++ b/libgfortran/runtime/backtrace.c @@ -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)) { |