| Index: base/profiler/native_stack_sampler_win.cc
|
| diff --git a/base/profiler/native_stack_sampler_win.cc b/base/profiler/native_stack_sampler_win.cc
|
| index e1605109fe960d769523733b2a1190700b250d28..b1b5f4a38ea23b2170ca8f531602cffd32675d33 100644
|
| --- a/base/profiler/native_stack_sampler_win.cc
|
| +++ b/base/profiler/native_stack_sampler_win.cc
|
| @@ -326,7 +326,7 @@ bool PointsToGuardPage(uintptr_t stack_pointer) {
|
| // ScopedSuspendThread scope, including indirectly via use of DCHECK/CHECK or
|
| // other logging statements. Otherwise this code can deadlock on heap locks in
|
| // the default heap acquired by the target thread before it was suspended.
|
| -void SuspendThreadAndRecordStack(
|
| +NativeStackSampler::ThreadState SuspendThreadAndRecordStack(
|
| HANDLE thread_handle,
|
| const void* base_address,
|
| void* stack_copy_buffer,
|
| @@ -349,10 +349,11 @@ void SuspendThreadAndRecordStack(
|
| ScopedSuspendThread suspend_thread(thread_handle);
|
|
|
| if (!suspend_thread.was_successful())
|
| - return;
|
| + return NativeStackSampler::THREAD_UNSUSPENDABLE;
|
|
|
| if (!::GetThreadContext(thread_handle, &thread_context))
|
| - return;
|
| + return NativeStackSampler::THREAD_NO_INFO;
|
| +
|
| #if defined(_WIN64)
|
| bottom = thread_context.Rsp;
|
| #else
|
| @@ -360,13 +361,13 @@ void SuspendThreadAndRecordStack(
|
| #endif
|
|
|
| if ((top - bottom) > stack_copy_buffer_size)
|
| - return;
|
| + return NativeStackSampler::THREAD_STACK_TOO_BIG;
|
|
|
| // Dereferencing a pointer in the guard page in a thread that doesn't own
|
| // the stack results in a STATUS_GUARD_PAGE_VIOLATION exception and a crash.
|
| // This occurs very rarely, but reliably over the population.
|
| if (PointsToGuardPage(bottom))
|
| - return;
|
| + return NativeStackSampler::THREAD_INACCESSIBLE;
|
|
|
| (*annotator)(sample);
|
|
|
| @@ -380,6 +381,7 @@ void SuspendThreadAndRecordStack(
|
| RewritePointersToStackMemory(top, bottom, &thread_context, stack_copy_buffer);
|
|
|
| RecordStack(&thread_context, stack);
|
| + return NativeStackSampler::THREAD_RUNNING;
|
| }
|
|
|
| // NativeStackSamplerWin ------------------------------------------------------
|
| @@ -477,11 +479,18 @@ void NativeStackSamplerWin::RecordStackSample(
|
| if (!stack_copy_buffer_)
|
| return;
|
|
|
| + if (thread_state() == THREAD_EXITED)
|
| + return;
|
| +
|
| std::vector<RecordedFrame> stack;
|
| - SuspendThreadAndRecordStack(thread_handle_.Get(), thread_stack_base_address_,
|
| - stack_copy_buffer_.get(), kStackCopyBufferSize,
|
| - &stack, annotator_, sample, test_delegate_);
|
| + set_thread_state(SuspendThreadAndRecordStack(
|
| + thread_handle_.Get(), thread_stack_base_address_,
|
| + stack_copy_buffer_.get(), kStackCopyBufferSize, &stack, annotator_,
|
| + sample, test_delegate_));
|
| CopyToSample(stack, sample, current_modules_);
|
| +
|
| + if (test_delegate_)
|
| + test_delegate_->OnPostRecordSample(thread_state());
|
| }
|
|
|
| void NativeStackSamplerWin::ProfileRecordingStopped() {
|
|
|