Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2712)

Unified Diff: base/profiler/native_stack_sampler_win.cc

Issue 1423583002: Stack sampling profiler: handle unloaded and unloading modules (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@lkcr
Patch Set: fix gcc compile Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/profiler/native_stack_sampler_posix.cc ('k') | base/profiler/stack_sampling_profiler.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 203ab94053c5094d6ffed6863f586081cb40dbc4..167dc25e0a9364350a7c90c2336f925650382431 100644
--- a/base/profiler/native_stack_sampler_win.cc
+++ b/base/profiler/native_stack_sampler_win.cc
@@ -140,13 +140,14 @@ void RewritePointersToStackMemory(uintptr_t top, uintptr_t bottom,
// Walks the stack represented by |context| from the current frame downwards,
// recording the instruction pointers for each frame in |instruction_pointers|.
int RecordStack(CONTEXT* context, int max_stack_size,
- const void* instruction_pointers[]) {
+ const void* instruction_pointers[],
+ ScopedModuleHandle modules[]) {
#ifdef _WIN64
Win32StackFrameUnwinder frame_unwinder;
int i = 0;
for (; (i < max_stack_size) && context->Rip; ++i) {
instruction_pointers[i] = reinterpret_cast<const void*>(context->Rip);
- if (!frame_unwinder.TryUnwind(context))
+ if (!frame_unwinder.TryUnwind(context, &modules[i]))
return i + 1;
}
return i;
@@ -155,35 +156,6 @@ int RecordStack(CONTEXT* context, int max_stack_size,
#endif
}
-// Fills in |module_handles| corresponding to the pointers to code in
-// |addresses|. The module handles are returned with reference counts
-// incremented and should be freed with FreeModuleHandles. See note in
-// SuspendThreadAndRecordStack for why |addresses| and |module_handles| are
-// arrays.
-void FindModuleHandlesForAddresses(const void* const addresses[],
- HMODULE module_handles[], int stack_depth) {
- for (int i = 0; i < stack_depth; ++i) {
- HMODULE module_handle = NULL;
- if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
- reinterpret_cast<LPCTSTR>(addresses[i]),
- &module_handle)) {
- // HMODULE actually represents the base address of the module, so we can
- // use it directly as an address.
- DCHECK_LE(reinterpret_cast<const void*>(module_handle), addresses[i]);
- module_handles[i] = module_handle;
- }
- }
-}
-
-// Frees the modules handles returned by FindModuleHandlesForAddresses. See note
-// in SuspendThreadAndRecordStack for why |module_handles| is an array.
-void FreeModuleHandles(int stack_depth, HMODULE module_handles[]) {
- for (int i = 0; i < stack_depth; ++i) {
- if (module_handles[i])
- ::FreeLibrary(module_handles[i]);
- }
-}
-
// Gets the unique build ID for a module. Windows build IDs are created by a
// concatenation of a GUID and AGE fields found in the headers of a module. The
// GUID is stored in the first 16 bytes and the AGE is stored in the last 4
@@ -300,7 +272,9 @@ int SuspendThreadAndRecordStack(HANDLE thread_handle,
void* stack_copy_buffer,
size_t stack_copy_buffer_size,
int max_stack_size,
- const void* instruction_pointers[]) {
+ const void* instruction_pointers[],
+ ScopedModuleHandle modules[],
+ NativeStackSamplerTestDelegate* test_delegate) {
CONTEXT thread_context = {0};
thread_context.ContextFlags = CONTEXT_FULL;
// The stack bounds are saved to uintptr_ts for use outside
@@ -330,16 +304,21 @@ int SuspendThreadAndRecordStack(HANDLE thread_handle,
top - bottom);
}
+ if (test_delegate)
+ test_delegate->OnPreStackWalk();
+
RewritePointersToStackMemory(top, bottom, &thread_context, stack_copy_buffer);
- return RecordStack(&thread_context, max_stack_size, instruction_pointers);
+ return RecordStack(&thread_context, max_stack_size, instruction_pointers,
+ modules);
}
// NativeStackSamplerWin ------------------------------------------------------
class NativeStackSamplerWin : public NativeStackSampler {
public:
- explicit NativeStackSamplerWin(win::ScopedHandle thread_handle);
+ NativeStackSamplerWin(win::ScopedHandle thread_handle,
+ NativeStackSamplerTestDelegate* test_delegate);
~NativeStackSamplerWin() override;
// StackSamplingProfiler::NativeStackSampler:
@@ -373,13 +352,15 @@ class NativeStackSamplerWin : public NativeStackSampler {
// Copies the stack information represented by |instruction_pointers| into
// |sample| and |modules|.
void CopyToSample(const void* const instruction_pointers[],
- const HMODULE module_handles[],
+ const ScopedModuleHandle module_handles[],
int stack_depth,
StackSamplingProfiler::Sample* sample,
std::vector<StackSamplingProfiler::Module>* modules);
win::ScopedHandle thread_handle_;
+ NativeStackSamplerTestDelegate* const test_delegate_;
+
// The stack base address corresponding to |thread_handle_|.
const void* const thread_stack_base_address_;
@@ -398,8 +379,10 @@ class NativeStackSamplerWin : public NativeStackSampler {
DISALLOW_COPY_AND_ASSIGN(NativeStackSamplerWin);
};
-NativeStackSamplerWin::NativeStackSamplerWin(win::ScopedHandle thread_handle)
- : thread_handle_(thread_handle.Take()),
+NativeStackSamplerWin::NativeStackSamplerWin(
+ win::ScopedHandle thread_handle,
+ NativeStackSamplerTestDelegate* test_delegate)
+ : thread_handle_(thread_handle.Take()), test_delegate_(test_delegate),
thread_stack_base_address_(
GetThreadEnvironmentBlock(thread_handle_.Get())->Tib.StackBase),
stack_copy_buffer_(new unsigned char[kStackCopyBufferSize]) {
@@ -423,19 +406,18 @@ void NativeStackSamplerWin::RecordStackSample(
const int max_stack_size = 64;
const void* instruction_pointers[max_stack_size] = {0};
- HMODULE module_handles[max_stack_size] = {0};
+ ScopedModuleHandle modules[max_stack_size];
int stack_depth = SuspendThreadAndRecordStack(thread_handle_.Get(),
thread_stack_base_address_,
stack_copy_buffer_.get(),
kStackCopyBufferSize,
max_stack_size,
- instruction_pointers);
- FindModuleHandlesForAddresses(instruction_pointers, module_handles,
- stack_depth);
- CopyToSample(instruction_pointers, module_handles, stack_depth, sample,
+ instruction_pointers,
+ modules,
+ test_delegate_);
+ CopyToSample(instruction_pointers, modules, stack_depth, sample,
current_modules_);
- FreeModuleHandles(stack_depth, module_handles);
}
void NativeStackSamplerWin::ProfileRecordingStopped() {
@@ -484,24 +466,25 @@ size_t NativeStackSamplerWin::GetModuleIndex(
void NativeStackSamplerWin::CopyToSample(
const void* const instruction_pointers[],
- const HMODULE module_handles[],
+ const ScopedModuleHandle module_handles[],
int stack_depth,
StackSamplingProfiler::Sample* sample,
- std::vector<StackSamplingProfiler::Module>* module) {
+ std::vector<StackSamplingProfiler::Module>* modules) {
sample->clear();
sample->reserve(stack_depth);
for (int i = 0; i < stack_depth; ++i) {
sample->push_back(StackSamplingProfiler::Frame(
reinterpret_cast<uintptr_t>(instruction_pointers[i]),
- GetModuleIndex(module_handles[i], module)));
+ GetModuleIndex(module_handles[i].Get(), modules)));
}
}
} // namespace
scoped_ptr<NativeStackSampler> NativeStackSampler::Create(
- PlatformThreadId thread_id) {
+ PlatformThreadId thread_id,
+ NativeStackSamplerTestDelegate* test_delegate) {
#if _WIN64
// Get the thread's handle.
HANDLE thread_handle = ::OpenThread(
@@ -511,7 +494,8 @@ scoped_ptr<NativeStackSampler> NativeStackSampler::Create(
if (thread_handle) {
return scoped_ptr<NativeStackSampler>(new NativeStackSamplerWin(
- win::ScopedHandle(thread_handle)));
+ win::ScopedHandle(thread_handle),
+ test_delegate));
}
#endif
return scoped_ptr<NativeStackSampler>();
« no previous file with comments | « base/profiler/native_stack_sampler_posix.cc ('k') | base/profiler/stack_sampling_profiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698