summaryrefslogtreecommitdiff
path: root/libgo
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2013-12-01 01:40:16 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2013-12-01 01:40:16 +0000
commitebabd272702b9ee6b27c517790745b86d45beac4 (patch)
tree65d707a5cf1d78dd3fd10b552aad7a0bb4d2e983 /libgo
parentec2e11f50d21bcb18c789b8bed2cb60cb3a0d1f0 (diff)
downloadgcc-ebabd272702b9ee6b27c517790745b86d45beac4.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@205561 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo')
-rw-r--r--libgo/runtime/go-callers.c9
-rw-r--r--libgo/runtime/proc.c9
-rw-r--r--libgo/runtime/runtime.h1
3 files changed, 19 insertions, 0 deletions
diff --git a/libgo/runtime/go-callers.c b/libgo/runtime/go-callers.c
index 291dfd0d666..ae411d9c83a 100644
--- a/libgo/runtime/go-callers.c
+++ b/libgo/runtime/go-callers.c
@@ -11,6 +11,13 @@
#include "runtime.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. */
struct callers_data
@@ -111,8 +118,10 @@ runtime_callers (int32 skip, Location *locbuf, int32 m)
data.skip = skip + 1;
data.index = 0;
data.max = m;
+ runtime_xadd (&runtime_in_callers, 1);
backtrace_full (__go_get_backtrace_state (), 0, callback, error_callback,
&data);
+ runtime_xadd (&runtime_in_callers, -1);
return data.index;
}
diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c
index de2a54bfa5e..47a472b6d0a 100644
--- a/libgo/runtime/proc.c
+++ b/libgo/runtime/proc.c
@@ -2454,6 +2454,15 @@ runtime_sigprof()
return;
}
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) {
n = runtime_callers(0, prof.locbuf, nelem(prof.locbuf));
for(i = 0; i < n; i++)
diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h
index e82e83231e6..b9a1686d385 100644
--- a/libgo/runtime/runtime.h
+++ b/libgo/runtime/runtime.h
@@ -776,6 +776,7 @@ extern struct backtrace_state *__go_get_backtrace_state(void);
extern _Bool __go_file_line(uintptr, String*, String*, intgo *);
extern byte* runtime_progname();
extern void runtime_main(void*);
+extern uint32 runtime_in_callers;
int32 getproccount(void);