Commit f6be1179 by Ian Lance Taylor

runtime: prevent deadlock when profiling signal arrives during traceback

    
    Traceback routines, e.g. callers and funcentry, may call
    __go_get_backtrace_state. If a profiling signal arrives while we
    are in the critical section of __go_get_backtrace_state, it tries
    to do a traceback, which also calls __go_get_backtrace_state,
    which tries to enter the same critical section and will deadlock.
    Prevent this deadlock by setting up runtime_in_callers before
    calling __go_get_backtrace_state.
    
    Found while investigating golang/go#29448. Will add a test in the
    next CL.
    
    Updates golang/go#29448.
    
    Reviewed-on: https://go-review.googlesource.com/c/156037

From-SVN: r267590
parent 869fbd35
0e482bef69d73b9381dbc543e200a1fe57275e81 2ce291eaee427799bfcde256929dab89e0ab61eb
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -137,7 +137,9 @@ __go_file_line (uintptr pc, int index, String *fn, String *file, intgo *line) ...@@ -137,7 +137,9 @@ __go_file_line (uintptr pc, int index, String *fn, String *file, intgo *line)
runtime_memclr (&c, sizeof c); runtime_memclr (&c, sizeof c);
c.index = index; c.index = index;
runtime_xadd (&__go_runtime_in_callers, 1);
state = __go_get_backtrace_state (); state = __go_get_backtrace_state ();
runtime_xadd (&__go_runtime_in_callers, -1);
backtrace_pcinfo (state, pc, callback, error_callback, &c); backtrace_pcinfo (state, pc, callback, error_callback, &c);
*fn = c.fn; *fn = c.fn;
*file = c.file; *file = c.file;
...@@ -169,8 +171,13 @@ syminfo_callback (void *data, uintptr_t pc __attribute__ ((unused)), ...@@ -169,8 +171,13 @@ syminfo_callback (void *data, uintptr_t pc __attribute__ ((unused)),
static _Bool static _Bool
__go_symbol_value (uintptr pc, uintptr *val) __go_symbol_value (uintptr pc, uintptr *val)
{ {
struct backtrace_state *state;
*val = 0; *val = 0;
backtrace_syminfo (__go_get_backtrace_state (), pc, syminfo_callback, runtime_xadd (&__go_runtime_in_callers, 1);
state = __go_get_backtrace_state ();
runtime_xadd (&__go_runtime_in_callers, -1);
backtrace_syminfo (state, pc, syminfo_callback,
error_callback, val); error_callback, val);
return *val != 0; return *val != 0;
} }
......
...@@ -202,8 +202,8 @@ runtime_callers (int32 skip, Location *locbuf, int32 m, bool keep_thunks) ...@@ -202,8 +202,8 @@ runtime_callers (int32 skip, Location *locbuf, int32 m, bool keep_thunks)
data.index = 0; data.index = 0;
data.max = m; data.max = m;
data.keep_thunks = keep_thunks; data.keep_thunks = keep_thunks;
state = __go_get_backtrace_state ();
runtime_xadd (&__go_runtime_in_callers, 1); runtime_xadd (&__go_runtime_in_callers, 1);
state = __go_get_backtrace_state ();
backtrace_full (state, 0, callback, error_callback, &data); backtrace_full (state, 0, callback, error_callback, &data);
runtime_xadd (&__go_runtime_in_callers, -1); runtime_xadd (&__go_runtime_in_callers, -1);
......
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