diff mbox series

libgo patch committed: Avoid deadlock if SIGPROF arrives during traceback

Message ID CAOyqgcVXLTjEvp_+Ge6LoM_nGTSwEugC7er9r+TjPRd+e7eChQ@mail.gmail.com
State New
Headers show
Series libgo patch committed: Avoid deadlock if SIGPROF arrives during traceback | expand

Commit Message

Ian Lance Taylor Jan. 5, 2019, 12:40 a.m. UTC
This libgo patch by Cherry Zhang prevent deadlock when a profiling
signal arrives during traceback.  Traceback routines, e.g. callers and
funcentry, may call __go_get_backtrace_state.  If a profiling signal
arrives while we are in the critical section of
__go_get_backtrace_state, it tries to do a traceback, which also calls
__go_get_backtrace_state, which tries to enter the same critical
section and will deadlock.  Prevent this deadlock by setting up
runtime_in_callers before calling __go_get_backtrace_state.  This was
found while investigating https://golang.org/29448.  Bootstrapped and
ran Go testsuite on x86_64-pc-linux-gnu.  Committed to mainline.

Ian
diff mbox series

Patch

Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE	(revision 267580)
+++ gcc/go/gofrontend/MERGE	(working copy)
@@ -1,4 +1,4 @@ 
-0e482bef69d73b9381dbc543e200a1fe57275e81
+2ce291eaee427799bfcde256929dab89e0ab61eb
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: libgo/runtime/go-caller.c
===================================================================
--- libgo/runtime/go-caller.c	(revision 267580)
+++ libgo/runtime/go-caller.c	(working copy)
@@ -137,7 +137,9 @@  __go_file_line (uintptr pc, int index, S
 
   runtime_memclr (&c, sizeof c);
   c.index = index;
+  runtime_xadd (&__go_runtime_in_callers, 1);
   state = __go_get_backtrace_state ();
+  runtime_xadd (&__go_runtime_in_callers, -1);
   backtrace_pcinfo (state, pc, callback, error_callback, &c);
   *fn = c.fn;
   *file = c.file;
@@ -169,8 +171,13 @@  syminfo_callback (void *data, uintptr_t
 static _Bool
 __go_symbol_value (uintptr pc, uintptr *val)
 {
+  struct backtrace_state *state;
+
   *val = 0;
-  backtrace_syminfo (__go_get_backtrace_state (), pc, syminfo_callback,
+  runtime_xadd (&__go_runtime_in_callers, 1);
+  state = __go_get_backtrace_state ();
+  runtime_xadd (&__go_runtime_in_callers, -1);
+  backtrace_syminfo (state, pc, syminfo_callback,
 		     error_callback, val);
   return *val != 0;
 }
Index: libgo/runtime/go-callers.c
===================================================================
--- libgo/runtime/go-callers.c	(revision 267580)
+++ libgo/runtime/go-callers.c	(working copy)
@@ -202,8 +202,8 @@  runtime_callers (int32 skip, Location *l
   data.index = 0;
   data.max = m;
   data.keep_thunks = keep_thunks;
-  state = __go_get_backtrace_state ();
   runtime_xadd (&__go_runtime_in_callers, 1);
+  state = __go_get_backtrace_state ();
   backtrace_full (state, 0, callback, error_callback, &data);
   runtime_xadd (&__go_runtime_in_callers, -1);