runtime: don't use runtime_lock in __go_get_backtrace_state
If getSiginfo does not know how to determine the PC, it will call runtime_callers. That can happen in a thread that was started by non-Go code, in which case the TLS variable g will not be set, in which case runtime_lock will crash. Avoid the problem by using atomic operations for the lock. This is OK since creating a backtrace state is fast and never blocks. The test case is TestCgoExternalThreadSIGPROF in the runtime package on a system that getSiginfo doesn't handle specially. Updates golang/go#20931 Reviewed-on: https://go-review.googlesource.com/50650 From-SVN: r250439
This commit is contained in:
parent
2401ffc3fe
commit
df206c6e77
@ -1,4 +1,4 @@
|
|||||||
a9f1aeced86691de891fbf2a8c97e848faf1962e
|
b712bacd939466e66972337744983e180849c535
|
||||||
|
|
||||||
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.
|
||||||
|
@ -74,7 +74,7 @@ static void *back_state;
|
|||||||
|
|
||||||
/* A lock to control creating back_state. */
|
/* A lock to control creating back_state. */
|
||||||
|
|
||||||
static Lock back_state_lock;
|
static uint32 back_state_lock;
|
||||||
|
|
||||||
/* The program arguments. */
|
/* The program arguments. */
|
||||||
|
|
||||||
@ -85,7 +85,15 @@ extern Slice runtime_get_args(void);
|
|||||||
struct backtrace_state *
|
struct backtrace_state *
|
||||||
__go_get_backtrace_state ()
|
__go_get_backtrace_state ()
|
||||||
{
|
{
|
||||||
runtime_lock (&back_state_lock);
|
uint32 set;
|
||||||
|
|
||||||
|
/* We may not have a g here, so we can't use runtime_lock. */
|
||||||
|
set = 0;
|
||||||
|
while (!__atomic_compare_exchange_n (&back_state_lock, &set, 1, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED))
|
||||||
|
{
|
||||||
|
runtime_osyield ();
|
||||||
|
set = 0;
|
||||||
|
}
|
||||||
if (back_state == NULL)
|
if (back_state == NULL)
|
||||||
{
|
{
|
||||||
Slice args;
|
Slice args;
|
||||||
@ -113,7 +121,7 @@ __go_get_backtrace_state ()
|
|||||||
|
|
||||||
back_state = backtrace_create_state (filename, 1, error_callback, NULL);
|
back_state = backtrace_create_state (filename, 1, error_callback, NULL);
|
||||||
}
|
}
|
||||||
runtime_unlock (&back_state_lock);
|
__atomic_store_n (&back_state_lock, 0, __ATOMIC_RELEASE);
|
||||||
return back_state;
|
return back_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user