diff mbox series

libgo patch committed: Prevent deadlock on SIGPROF during stack scan

Message ID CAOyqgcXBBdJUNvoT3v2bLk3zXAktHwaZ++SjD4eK9idSpAXLSw@mail.gmail.com
State New
Headers show
Series libgo patch committed: Prevent deadlock on SIGPROF during stack scan | expand

Commit Message

Ian Lance Taylor Dec. 29, 2018, 12:07 a.m. UTC
This libgo patch by Cherry Zhang prevents a deadlock when a profiling
signal arrives during a stack scan.  A precise stack scan needs to
unwind the stack. When it is unwinding the stack, if a profiling
signal arrives, which also does a traceback, it may deadlock in
dl_iterate_phdr.  Prevent this deadlock by setting runtime_in_callers
before traceback.  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 267455)
+++ gcc/go/gofrontend/MERGE	(working copy)
@@ -1,4 +1,4 @@ 
-d9a30434440469c640a120fe7132057f5644d38c
+0e482bef69d73b9381dbc543e200a1fe57275e81
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: libgo/runtime/go-callers.c
===================================================================
--- libgo/runtime/go-callers.c	(revision 267433)
+++ libgo/runtime/go-callers.c	(working copy)
@@ -16,7 +16,7 @@ 
    older versions of glibc when a SIGPROF signal arrives while
    collecting a backtrace.  */
 
-static uint32 runtime_in_callers;
+uint32 __go_runtime_in_callers;
 
 /* Argument passed to callback function.  */
 
@@ -185,7 +185,7 @@  bool alreadyInCallers(void)
 bool
 alreadyInCallers()
 {
-  return runtime_atomicload(&runtime_in_callers) > 0;
+  return runtime_atomicload(&__go_runtime_in_callers) > 0;
 }
 
 /* Gather caller PC's.  */
@@ -203,9 +203,9 @@  runtime_callers (int32 skip, Location *l
   data.max = m;
   data.keep_thunks = keep_thunks;
   state = __go_get_backtrace_state ();
-  runtime_xadd (&runtime_in_callers, 1);
+  runtime_xadd (&__go_runtime_in_callers, 1);
   backtrace_full (state, 0, callback, error_callback, &data);
-  runtime_xadd (&runtime_in_callers, -1);
+  runtime_xadd (&__go_runtime_in_callers, -1);
 
   /* For some reason GCC sometimes loses the name of a thunk function
      at the top of the stack.  If we are skipping thunks, skip that
Index: libgo/runtime/go-unwind.c
===================================================================
--- libgo/runtime/go-unwind.c	(revision 267434)
+++ libgo/runtime/go-unwind.c	(working copy)
@@ -792,7 +792,9 @@  bool
 scanstackwithmap (void *gcw)
 {
   _Unwind_Reason_Code code;
+  runtime_xadd (&__go_runtime_in_callers, 1);
   code = _Unwind_Backtrace (scanstackwithmap_callback, gcw);
+  runtime_xadd (&__go_runtime_in_callers, -1);
   return code == _URC_END_OF_STACK;
 }
 
Index: libgo/runtime/runtime.h
===================================================================
--- libgo/runtime/runtime.h	(revision 267433)
+++ libgo/runtime/runtime.h	(working copy)
@@ -515,3 +515,9 @@  bool runtime_usestackmaps;
 
 bool probestackmaps(void)
   __asm__("runtime.probestackmaps");
+
+// This is set to non-zero when calling backtrace_full.  This is used
+// to avoid getting hanging on a recursive lock in dl_iterate_phdr on
+// older versions of glibc when a SIGPROF signal arrives while
+// collecting a backtrace.
+extern uint32 __go_runtime_in_callers;