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

Unified Diff: base/profiler/win32_stack_frame_unwinder_unittest.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/win32_stack_frame_unwinder.cc ('k') | base/scoped_native_library.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/profiler/win32_stack_frame_unwinder_unittest.cc
diff --git a/base/profiler/win32_stack_frame_unwinder_unittest.cc b/base/profiler/win32_stack_frame_unwinder_unittest.cc
index ae5a2a6ea109edb2600914a572e32123e40cf68c..2fe34a70b333c36cf80e60afff0e36c6ec4a50d7 100644
--- a/base/profiler/win32_stack_frame_unwinder_unittest.cc
+++ b/base/profiler/win32_stack_frame_unwinder_unittest.cc
@@ -23,6 +23,11 @@ class TestUnwindFunctions : public Win32StackFrameUnwinder::UnwindFunctions {
DWORD64 program_counter,
PRUNTIME_FUNCTION runtime_function,
CONTEXT* context) override;
+ ScopedModuleHandle GetModuleForProgramCounter(
+ DWORD64 program_counter) override;
+
+ // Instructs GetModuleForProgramCounter to return null on the next call.
+ void SetUnloadedModule();
// These functions set whether the next frame will have a RUNTIME_FUNCTION,
// and allow specification of a custom image_base.
@@ -48,6 +53,7 @@ class TestUnwindFunctions : public Win32StackFrameUnwinder::UnwindFunctions {
static RUNTIME_FUNCTION* const kInvalidRuntimeFunction;
+ bool module_is_loaded_;
DWORD64 expected_program_counter_;
DWORD64 custom_image_base_;
DWORD64 next_image_base_;
@@ -62,7 +68,8 @@ RUNTIME_FUNCTION* const TestUnwindFunctions::kInvalidRuntimeFunction =
reinterpret_cast<RUNTIME_FUNCTION*>(static_cast<uintptr_t>(-1));
TestUnwindFunctions::TestUnwindFunctions()
- : expected_program_counter_(0),
+ : module_is_loaded_(true),
+ expected_program_counter_(0),
custom_image_base_(0),
next_image_base_(kImageBaseIncrement),
expected_image_base_(0),
@@ -101,6 +108,19 @@ void TestUnwindFunctions::VirtualUnwind(DWORD64 image_base,
EXPECT_EQ(&runtime_functions_.back(), runtime_function);
}
+ScopedModuleHandle TestUnwindFunctions::GetModuleForProgramCounter(
+ DWORD64 program_counter) {
+ bool return_non_null_value = module_is_loaded_;
+ module_is_loaded_ = true;
+ return ScopedModuleHandle(return_non_null_value ?
+ ModuleHandleTraits::kNonNullModuleForTesting :
+ nullptr);
+}
+
+void TestUnwindFunctions::SetUnloadedModule() {
+ module_is_loaded_ = false;
+}
+
void TestUnwindFunctions::SetHasRuntimeFunction(CONTEXT* context) {
SetNextFrameState(HAS_RUNTIME_FUNCTION, 0, context);
}
@@ -184,15 +204,31 @@ Win32StackFrameUnwinderTest::CreateUnwinder() {
TEST_F(Win32StackFrameUnwinderTest, FramesWithUnwindInfo) {
scoped_ptr<Win32StackFrameUnwinder> unwinder = CreateUnwinder();
CONTEXT context = {0};
+ ScopedModuleHandle module;
unwind_functions_->SetHasRuntimeFunction(&context);
- EXPECT_TRUE(unwinder->TryUnwind(&context));
+ EXPECT_TRUE(unwinder->TryUnwind(&context, &module));
+ EXPECT_TRUE(module.IsValid());
unwind_functions_->SetHasRuntimeFunction(&context);
- EXPECT_TRUE(unwinder->TryUnwind(&context));
+ module.Set(nullptr);
+ EXPECT_TRUE(unwinder->TryUnwind(&context, &module));
+ EXPECT_TRUE(module.IsValid());
unwind_functions_->SetHasRuntimeFunction(&context);
- EXPECT_TRUE(unwinder->TryUnwind(&context));
+ module.Set(nullptr);
+ EXPECT_TRUE(unwinder->TryUnwind(&context, &module));
+ EXPECT_TRUE(module.IsValid());
+}
+
+// Checks that an instruction pointer in an unloaded module fails to unwind.
+TEST_F(Win32StackFrameUnwinderTest, UnloadedModule) {
+ scoped_ptr<Win32StackFrameUnwinder> unwinder = CreateUnwinder();
+ CONTEXT context = {0};
+ ScopedModuleHandle module;
+
+ unwind_functions_->SetUnloadedModule();
+ EXPECT_FALSE(unwinder->TryUnwind(&context, &module));
}
// Checks that the CONTEXT's stack pointer gets popped when the top frame has no
@@ -200,19 +236,25 @@ TEST_F(Win32StackFrameUnwinderTest, FramesWithUnwindInfo) {
TEST_F(Win32StackFrameUnwinderTest, FrameAtTopWithoutUnwindInfo) {
scoped_ptr<Win32StackFrameUnwinder> unwinder = CreateUnwinder();
CONTEXT context = {0};
+ ScopedModuleHandle module;
const DWORD64 original_rsp = 128;
context.Rsp = original_rsp;
unwind_functions_->SetNoRuntimeFunction(&context);
- EXPECT_TRUE(unwinder->TryUnwind(&context));
+ EXPECT_TRUE(unwinder->TryUnwind(&context, &module));
EXPECT_EQ(original_rsp, context.Rip);
EXPECT_EQ(original_rsp + 8, context.Rsp);
+ EXPECT_TRUE(module.IsValid());
unwind_functions_->SetHasRuntimeFunction(&context);
- EXPECT_TRUE(unwinder->TryUnwind(&context));
+ module.Set(nullptr);
+ EXPECT_TRUE(unwinder->TryUnwind(&context, &module));
+ EXPECT_TRUE(module.IsValid());
unwind_functions_->SetHasRuntimeFunction(&context);
- EXPECT_TRUE(unwinder->TryUnwind(&context));
+ module.Set(nullptr);
+ EXPECT_TRUE(unwinder->TryUnwind(&context, &module));
+ EXPECT_TRUE(module.IsValid());
}
// Checks that a frame below the top of the stack with missing unwind info
@@ -223,13 +265,15 @@ TEST_F(Win32StackFrameUnwinderTest, BlacklistedModule) {
// First stack, with a bad function below the top of the stack.
scoped_ptr<Win32StackFrameUnwinder> unwinder = CreateUnwinder();
CONTEXT context = {0};
+ ScopedModuleHandle module;
unwind_functions_->SetHasRuntimeFunction(&context);
- EXPECT_TRUE(unwinder->TryUnwind(&context));
+ EXPECT_TRUE(unwinder->TryUnwind(&context, &module));
+ EXPECT_TRUE(module.IsValid());
unwind_functions_->SetNoRuntimeFunction(
image_base_for_module_with_bad_function,
&context);
- EXPECT_FALSE(unwinder->TryUnwind(&context));
+ EXPECT_FALSE(unwinder->TryUnwind(&context, &module));
}
{
@@ -237,10 +281,11 @@ TEST_F(Win32StackFrameUnwinderTest, BlacklistedModule) {
// unwind info from the previously-seen module is blacklisted.
scoped_ptr<Win32StackFrameUnwinder> unwinder = CreateUnwinder();
CONTEXT context = {0};
+ ScopedModuleHandle module;
unwind_functions_->SetNoRuntimeFunction(
image_base_for_module_with_bad_function,
&context);
- EXPECT_FALSE(unwinder->TryUnwind(&context));
+ EXPECT_FALSE(unwinder->TryUnwind(&context, &module));
}
{
@@ -251,18 +296,24 @@ TEST_F(Win32StackFrameUnwinderTest, BlacklistedModule) {
// module.
scoped_ptr<Win32StackFrameUnwinder> unwinder = CreateUnwinder();
CONTEXT context = {0};
+ ScopedModuleHandle module;
unwind_functions_->SetHasRuntimeFunction(
image_base_for_module_with_bad_function,
&context);
- EXPECT_TRUE(unwinder->TryUnwind(&context));
+ EXPECT_TRUE(unwinder->TryUnwind(&context, &module));
+ EXPECT_TRUE(module.IsValid());
unwind_functions_->SetHasRuntimeFunction(&context);
- EXPECT_TRUE(unwinder->TryUnwind(&context));
+ module.Set(nullptr);
+ EXPECT_TRUE(unwinder->TryUnwind(&context, &module));
+ EXPECT_TRUE(module.IsValid());
unwind_functions_->SetHasRuntimeFunction(
image_base_for_module_with_bad_function,
&context);
- EXPECT_TRUE(unwinder->TryUnwind(&context));
+ module.Set(nullptr);
+ EXPECT_TRUE(unwinder->TryUnwind(&context, &module));
+ EXPECT_TRUE(module.IsValid());
}
{
@@ -273,16 +324,22 @@ TEST_F(Win32StackFrameUnwinderTest, BlacklistedModule) {
// previously-seen module.
scoped_ptr<Win32StackFrameUnwinder> unwinder = CreateUnwinder();
CONTEXT context = {0};
+ ScopedModuleHandle module;
unwind_functions_->SetNoRuntimeFunction(&context);
- EXPECT_TRUE(unwinder->TryUnwind(&context));
+ EXPECT_TRUE(unwinder->TryUnwind(&context, &module));
+ EXPECT_TRUE(module.IsValid());
unwind_functions_->SetHasRuntimeFunction(&context);
- EXPECT_TRUE(unwinder->TryUnwind(&context));
+ module.Set(nullptr);
+ EXPECT_TRUE(unwinder->TryUnwind(&context, &module));
+ EXPECT_TRUE(module.IsValid());
unwind_functions_->SetHasRuntimeFunction(
image_base_for_module_with_bad_function,
&context);
- EXPECT_TRUE(unwinder->TryUnwind(&context));
+ module.Set(nullptr);
+ EXPECT_TRUE(unwinder->TryUnwind(&context, &module));
+ EXPECT_TRUE(module.IsValid());
}
}
@@ -296,21 +353,25 @@ TEST_F(Win32StackFrameUnwinderTest, ModuleFromQuestionableFrameNotBlacklisted) {
// First stack, with both the first and second frames missing unwind info.
scoped_ptr<Win32StackFrameUnwinder> unwinder = CreateUnwinder();
CONTEXT context = {0};
+ ScopedModuleHandle module;
unwind_functions_->SetNoRuntimeFunction(&context);
- EXPECT_TRUE(unwinder->TryUnwind(&context));
+ EXPECT_TRUE(unwinder->TryUnwind(&context, &module));
+ EXPECT_TRUE(module.IsValid());
unwind_functions_->SetNoRuntimeFunction(image_base_for_questionable_module,
&context);
- EXPECT_FALSE(unwinder->TryUnwind(&context));
+ EXPECT_FALSE(unwinder->TryUnwind(&context, &module));
}
{
// Second stack; check that the questionable module was not blacklisted.
scoped_ptr<Win32StackFrameUnwinder> unwinder = CreateUnwinder();
CONTEXT context = {0};
+ ScopedModuleHandle module;
unwind_functions_->SetNoRuntimeFunction(image_base_for_questionable_module,
&context);
- EXPECT_TRUE(unwinder->TryUnwind(&context));
+ EXPECT_TRUE(unwinder->TryUnwind(&context, &module));
+ EXPECT_TRUE(module.IsValid());
}
}
@@ -323,52 +384,57 @@ TEST_F(Win32StackFrameUnwinderTest, RuntimeFunctionSanityCheck) {
// instruction pointer between the two.
scoped_ptr<Win32StackFrameUnwinder> unwinder = CreateUnwinder();
CONTEXT context = {0};
+ ScopedModuleHandle module;
RUNTIME_FUNCTION runtime_function = {0};
runtime_function.BeginAddress = 128;
runtime_function.EndAddress = 512;
unwind_functions_->SetHasRuntimeFunction(image_base_for_sanity_check,
runtime_function, 256,
&context);
- EXPECT_TRUE(unwinder->TryUnwind(&context));
+ EXPECT_TRUE(unwinder->TryUnwind(&context, &module));
+ EXPECT_TRUE(module.IsValid());
}
{
// Test begin address greater than end address.
scoped_ptr<Win32StackFrameUnwinder> unwinder = CreateUnwinder();
CONTEXT context = {0};
+ ScopedModuleHandle module;
RUNTIME_FUNCTION runtime_function = {0};
runtime_function.BeginAddress = 512;
runtime_function.EndAddress = 128;
unwind_functions_->SetHasRuntimeFunction(image_base_for_sanity_check,
runtime_function, 256,
&context);
- EXPECT_FALSE(unwinder->TryUnwind(&context));
+ EXPECT_FALSE(unwinder->TryUnwind(&context, &module));
}
{
// Test instruction pointer before begin address.
scoped_ptr<Win32StackFrameUnwinder> unwinder = CreateUnwinder();
CONTEXT context = {0};
+ ScopedModuleHandle module;
RUNTIME_FUNCTION runtime_function = {0};
runtime_function.BeginAddress = 128;
runtime_function.EndAddress = 512;
unwind_functions_->SetHasRuntimeFunction(image_base_for_sanity_check,
runtime_function, 50,
&context);
- EXPECT_FALSE(unwinder->TryUnwind(&context));
+ EXPECT_FALSE(unwinder->TryUnwind(&context, &module));
}
{
// Test instruction pointer after end address.
scoped_ptr<Win32StackFrameUnwinder> unwinder = CreateUnwinder();
CONTEXT context = {0};
+ ScopedModuleHandle module;
RUNTIME_FUNCTION runtime_function = {0};
runtime_function.BeginAddress = 128;
runtime_function.EndAddress = 512;
unwind_functions_->SetHasRuntimeFunction(image_base_for_sanity_check,
runtime_function, 600,
&context);
- EXPECT_FALSE(unwinder->TryUnwind(&context));
+ EXPECT_FALSE(unwinder->TryUnwind(&context, &module));
}
}
« no previous file with comments | « base/profiler/win32_stack_frame_unwinder.cc ('k') | base/scoped_native_library.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698