Commit 2583109c by Ian Lance Taylor

libgo: Avoid some cases of getting callers recursively.

Avoids hanging inside older versions of glibc that do not
support recurive calls to dl_iterate_phdr.

From-SVN: r205561
parent 2d7930e5
...@@ -11,6 +11,13 @@ ...@@ -11,6 +11,13 @@
#include "runtime.h" #include "runtime.h"
#include "array.h" #include "array.h"
/* 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. */
uint32 runtime_in_callers;
/* Argument passed to callback function. */ /* Argument passed to callback function. */
struct callers_data struct callers_data
...@@ -111,8 +118,10 @@ runtime_callers (int32 skip, Location *locbuf, int32 m) ...@@ -111,8 +118,10 @@ runtime_callers (int32 skip, Location *locbuf, int32 m)
data.skip = skip + 1; data.skip = skip + 1;
data.index = 0; data.index = 0;
data.max = m; data.max = m;
runtime_xadd (&runtime_in_callers, 1);
backtrace_full (__go_get_backtrace_state (), 0, callback, error_callback, backtrace_full (__go_get_backtrace_state (), 0, callback, error_callback,
&data); &data);
runtime_xadd (&runtime_in_callers, -1);
return data.index; return data.index;
} }
......
...@@ -2454,6 +2454,15 @@ runtime_sigprof() ...@@ -2454,6 +2454,15 @@ runtime_sigprof()
return; return;
} }
n = 0; n = 0;
if(runtime_atomicload(&runtime_in_callers) > 0) {
// If SIGPROF arrived while already fetching runtime
// callers we can have trouble on older systems
// because the unwind library calls dl_iterate_phdr
// which was not recursive in the past.
traceback = false;
}
if(traceback) { if(traceback) {
n = runtime_callers(0, prof.locbuf, nelem(prof.locbuf)); n = runtime_callers(0, prof.locbuf, nelem(prof.locbuf));
for(i = 0; i < n; i++) for(i = 0; i < n; i++)
......
...@@ -776,6 +776,7 @@ extern struct backtrace_state *__go_get_backtrace_state(void); ...@@ -776,6 +776,7 @@ extern struct backtrace_state *__go_get_backtrace_state(void);
extern _Bool __go_file_line(uintptr, String*, String*, intgo *); extern _Bool __go_file_line(uintptr, String*, String*, intgo *);
extern byte* runtime_progname(); extern byte* runtime_progname();
extern void runtime_main(void*); extern void runtime_main(void*);
extern uint32 runtime_in_callers;
int32 getproccount(void); int32 getproccount(void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment