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
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;