aboutsummaryrefslogtreecommitdiff
path: root/libgo
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2013-12-01 01:40:16 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2013-12-01 01:40:16 +0000
commit2583109c81b60c64d5ed38e61622c39c1530805f (patch)
tree65d707a5cf1d78dd3fd10b552aad7a0bb4d2e983 /libgo
parent2d7930e5e3876af6cca4c823e03fb75d0f92f9ad (diff)
downloadgcc-2583109c81b60c64d5ed38e61622c39c1530805f.zip
gcc-2583109c81b60c64d5ed38e61622c39c1530805f.tar.gz
gcc-2583109c81b60c64d5ed38e61622c39c1530805f.tar.bz2
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
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 291dfd0..ae411d9 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 de2a54b..47a472b 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 e82e832..b9a1686 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);