aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorted.mielczarek@gmail.com <ted.mielczarek@gmail.com@4c0a9323-5329-0410-9bdc-e9ce6186880e>2012-09-17 14:01:28 +0000
committerted.mielczarek@gmail.com <ted.mielczarek@gmail.com@4c0a9323-5329-0410-9bdc-e9ce6186880e>2012-09-17 14:01:28 +0000
commit52935b4e812f413beaf294b24e5677c0324f98b6 (patch)
tree69bafaa55473940b8568f001ea068fde445a5452 /src
parentMake my_str_len/my_itos take uintmax_t (diff)
downloadbreakpad-52935b4e812f413beaf294b24e5677c0324f98b6.tar.xz
Add a GetInstructionPointer method to MinidumpException
R=mark at https://breakpad.appspot.com/444003/ git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1039 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src')
-rw-r--r--src/client/linux/handler/exception_handler_unittest.cc45
-rw-r--r--src/client/mac/tests/exception_handler_test.cc45
-rw-r--r--src/client/windows/unittests/exception_handler_death_test.cc36
-rw-r--r--src/google_breakpad/processor/minidump.h4
-rw-r--r--src/processor/minidump.cc35
-rw-r--r--src/processor/minidump_unittest.cc10
6 files changed, 56 insertions, 119 deletions
diff --git a/src/client/linux/handler/exception_handler_unittest.cc b/src/client/linux/handler/exception_handler_unittest.cc
index 83af35d5..6de9b8d4 100644
--- a/src/client/linux/handler/exception_handler_unittest.cc
+++ b/src/client/linux/handler/exception_handler_unittest.cc
@@ -450,20 +450,7 @@ TEST(ExceptionHandlerTest, InstructionPointerMemory) {
ASSERT_TRUE(context);
u_int64_t instruction_pointer;
- switch (context->GetContextCPU()) {
- case MD_CONTEXT_X86:
- instruction_pointer = context->GetContextX86()->eip;
- break;
- case MD_CONTEXT_AMD64:
- instruction_pointer = context->GetContextAMD64()->rip;
- break;
- case MD_CONTEXT_ARM:
- instruction_pointer = context->GetContextARM()->iregs[15];
- break;
- default:
- FAIL() << "Unknown context CPU: " << context->GetContextCPU();
- break;
- }
+ ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer));
MinidumpMemoryRegion* region =
memory_list->GetMemoryRegionForAddress(instruction_pointer);
@@ -555,20 +542,7 @@ TEST(ExceptionHandlerTest, InstructionPointerMemoryMinBound) {
ASSERT_TRUE(context);
u_int64_t instruction_pointer;
- switch (context->GetContextCPU()) {
- case MD_CONTEXT_X86:
- instruction_pointer = context->GetContextX86()->eip;
- break;
- case MD_CONTEXT_AMD64:
- instruction_pointer = context->GetContextAMD64()->rip;
- break;
- case MD_CONTEXT_ARM:
- instruction_pointer = context->GetContextARM()->iregs[15];
- break;
- default:
- FAIL() << "Unknown context CPU: " << context->GetContextCPU();
- break;
- }
+ ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer));
MinidumpMemoryRegion* region =
memory_list->GetMemoryRegionForAddress(instruction_pointer);
@@ -658,20 +632,7 @@ TEST(ExceptionHandlerTest, InstructionPointerMemoryMaxBound) {
ASSERT_TRUE(context);
u_int64_t instruction_pointer;
- switch (context->GetContextCPU()) {
- case MD_CONTEXT_X86:
- instruction_pointer = context->GetContextX86()->eip;
- break;
- case MD_CONTEXT_AMD64:
- instruction_pointer = context->GetContextAMD64()->rip;
- break;
- case MD_CONTEXT_ARM:
- instruction_pointer = context->GetContextARM()->iregs[15];
- break;
- default:
- FAIL() << "Unknown context CPU: " << context->GetContextCPU();
- break;
- }
+ ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer));
MinidumpMemoryRegion* region =
memory_list->GetMemoryRegionForAddress(instruction_pointer);
diff --git a/src/client/mac/tests/exception_handler_test.cc b/src/client/mac/tests/exception_handler_test.cc
index ee3ffa5b..8325d44e 100644
--- a/src/client/mac/tests/exception_handler_test.cc
+++ b/src/client/mac/tests/exception_handler_test.cc
@@ -347,20 +347,7 @@ TEST_F(ExceptionHandlerTest, InstructionPointerMemory) {
ASSERT_TRUE(context);
u_int64_t instruction_pointer;
- switch (context->GetContextCPU()) {
- case MD_CONTEXT_X86:
- instruction_pointer = context->GetContextX86()->eip;
- break;
- case MD_CONTEXT_AMD64:
- instruction_pointer = context->GetContextAMD64()->rip;
- break;
- case MD_CONTEXT_ARM:
- instruction_pointer = context->GetContextARM()->iregs[15];
- break;
- default:
- FAIL() << "Unknown context CPU: " << context->GetContextCPU();
- break;
- }
+ ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer));
MinidumpMemoryRegion* region =
memory_list->GetMemoryRegionForAddress(instruction_pointer);
@@ -459,20 +446,7 @@ TEST_F(ExceptionHandlerTest, InstructionPointerMemoryMinBound) {
ASSERT_TRUE(context);
u_int64_t instruction_pointer;
- switch (context->GetContextCPU()) {
- case MD_CONTEXT_X86:
- instruction_pointer = context->GetContextX86()->eip;
- break;
- case MD_CONTEXT_AMD64:
- instruction_pointer = context->GetContextAMD64()->rip;
- break;
- case MD_CONTEXT_ARM:
- instruction_pointer = context->GetContextARM()->iregs[15];
- break;
- default:
- FAIL() << "Unknown context CPU: " << context->GetContextCPU();
- break;
- }
+ ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer));
MinidumpMemoryRegion* region =
memory_list->GetMemoryRegionForAddress(instruction_pointer);
@@ -571,20 +545,7 @@ TEST_F(ExceptionHandlerTest, InstructionPointerMemoryMaxBound) {
ASSERT_TRUE(context);
u_int64_t instruction_pointer;
- switch (context->GetContextCPU()) {
- case MD_CONTEXT_X86:
- instruction_pointer = context->GetContextX86()->eip;
- break;
- case MD_CONTEXT_AMD64:
- instruction_pointer = context->GetContextAMD64()->rip;
- break;
- case MD_CONTEXT_ARM:
- instruction_pointer = context->GetContextARM()->iregs[15];
- break;
- default:
- FAIL() << "Unknown context CPU: " << context->GetContextCPU();
- break;
- }
+ ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer));
MinidumpMemoryRegion* region =
memory_list->GetMemoryRegionForAddress(instruction_pointer);
diff --git a/src/client/windows/unittests/exception_handler_death_test.cc b/src/client/windows/unittests/exception_handler_death_test.cc
index 514ee72a..a50f9134 100644
--- a/src/client/windows/unittests/exception_handler_death_test.cc
+++ b/src/client/windows/unittests/exception_handler_death_test.cc
@@ -303,17 +303,7 @@ TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemory) {
ASSERT_TRUE(context);
u_int64_t instruction_pointer;
- switch (context->GetContextCPU()) {
- case MD_CONTEXT_X86:
- instruction_pointer = context->GetContextX86()->eip;
- break;
- case MD_CONTEXT_AMD64:
- instruction_pointer = context->GetContextAMD64()->rip;
- break;
- default:
- FAIL() << "Unknown context CPU: " << context->GetContextCPU();
- break;
- }
+ ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer));
MinidumpMemoryRegion* region =
memory_list->GetMemoryRegionForAddress(instruction_pointer);
@@ -403,17 +393,7 @@ TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemoryMinBound) {
ASSERT_TRUE(context);
u_int64_t instruction_pointer;
- switch (context->GetContextCPU()) {
- case MD_CONTEXT_X86:
- instruction_pointer = context->GetContextX86()->eip;
- break;
- case MD_CONTEXT_AMD64:
- instruction_pointer = context->GetContextAMD64()->rip;
- break;
- default:
- FAIL() << "Unknown context CPU: " << context->GetContextCPU();
- break;
- }
+ ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer));
MinidumpMemoryRegion* region =
memory_list->GetMemoryRegionForAddress(instruction_pointer);
@@ -495,17 +475,7 @@ TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemoryMaxBound) {
ASSERT_TRUE(context);
u_int64_t instruction_pointer;
- switch (context->GetContextCPU()) {
- case MD_CONTEXT_X86:
- instruction_pointer = context->GetContextX86()->eip;
- break;
- case MD_CONTEXT_AMD64:
- instruction_pointer = context->GetContextAMD64()->rip;
- break;
- default:
- FAIL() << "Unknown context CPU: " << context->GetContextCPU();
- break;
- }
+ ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer));
MinidumpMemoryRegion* region =
memory_list->GetMemoryRegionForAddress(instruction_pointer);
diff --git a/src/google_breakpad/processor/minidump.h b/src/google_breakpad/processor/minidump.h
index 3dfbef2b..03337796 100644
--- a/src/google_breakpad/processor/minidump.h
+++ b/src/google_breakpad/processor/minidump.h
@@ -178,6 +178,10 @@ class MinidumpContext : public MinidumpStream {
// MD_CONTEXT_* bits masked out. Returns 0 on failure.
u_int32_t GetContextCPU() const;
+ // A convenience method to get the instruction pointer out of the
+ // MDRawContext, since it varies per-CPU architecture.
+ bool GetInstructionPointer(u_int64_t* ip) const;
+
// Returns raw CPU-specific context data for the named CPU type. If the
// context data does not match the CPU type or does not exist, returns
// NULL.
diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc
index d88101f6..19ba0354 100644
--- a/src/processor/minidump.cc
+++ b/src/processor/minidump.cc
@@ -714,6 +714,41 @@ u_int32_t MinidumpContext::GetContextCPU() const {
return context_flags_ & MD_CONTEXT_CPU_MASK;
}
+bool MinidumpContext::GetInstructionPointer(u_int64_t* ip) const {
+ BPLOG_IF(ERROR, !ip) << "MinidumpContext::GetInstructionPointer "
+ "requires |ip|";
+ assert(ip);
+ *ip = 0;
+
+ if (!valid_) {
+ BPLOG(ERROR) << "Invalid MinidumpContext for GetInstructionPointer";
+ return false;
+ }
+
+ switch (context_flags_ & MD_CONTEXT_CPU_MASK) {
+ case MD_CONTEXT_AMD64:
+ *ip = context_.amd64->rip;
+ break;
+ case MD_CONTEXT_ARM:
+ *ip = context_.arm->iregs[MD_CONTEXT_ARM_REG_PC];
+ break;
+ case MD_CONTEXT_PPC:
+ *ip = context_.ppc->srr0;
+ break;
+ case MD_CONTEXT_SPARC:
+ *ip = context_.ctx_sparc->pc;
+ break;
+ case MD_CONTEXT_X86:
+ *ip = context_.x86->eip;
+ break;
+ default:
+ // This should never happen.
+ BPLOG(ERROR) << "Unknown CPU architecture in GetInstructionPointer";
+ return false;
+ }
+ return true;
+}
+
const MDRawContextX86* MinidumpContext::GetContextX86() const {
if (GetContextCPU() != MD_CONTEXT_X86) {
diff --git a/src/processor/minidump_unittest.cc b/src/processor/minidump_unittest.cc
index ce142300..60cb37a6 100644
--- a/src/processor/minidump_unittest.cc
+++ b/src/processor/minidump_unittest.cc
@@ -213,6 +213,7 @@ TEST(Dump, OneThread) {
stack.Append("stack for thread");
MDRawContextX86 raw_context;
+ const u_int32_t kExpectedEIP = 0x6913f540;
raw_context.context_flags = MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL;
raw_context.edi = 0x3ecba80d;
raw_context.esi = 0x382583b9;
@@ -221,7 +222,7 @@ TEST(Dump, OneThread) {
raw_context.ecx = 0x46a6a6a8;
raw_context.eax = 0x6a5025e2;
raw_context.ebp = 0xd9fabb4a;
- raw_context.eip = 0x6913f540;
+ raw_context.eip = kExpectedEIP;
raw_context.cs = 0xbffe6eda;
raw_context.eflags = 0xb2ce1e2d;
raw_context.esp = 0x659caaa4;
@@ -273,6 +274,11 @@ TEST(Dump, OneThread) {
MinidumpContext *md_context = md_thread->GetContext();
ASSERT_TRUE(md_context != NULL);
ASSERT_EQ((u_int32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
+
+ u_int64_t eip;
+ ASSERT_TRUE(md_context->GetInstructionPointer(&eip));
+ EXPECT_EQ(kExpectedEIP, eip);
+
const MDRawContextX86 *md_raw_context = md_context->GetContextX86();
ASSERT_TRUE(md_raw_context != NULL);
ASSERT_EQ((u_int32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL),
@@ -285,7 +291,7 @@ TEST(Dump, OneThread) {
EXPECT_EQ(0x46a6a6a8U, raw_context.ecx);
EXPECT_EQ(0x6a5025e2U, raw_context.eax);
EXPECT_EQ(0xd9fabb4aU, raw_context.ebp);
- EXPECT_EQ(0x6913f540U, raw_context.eip);
+ EXPECT_EQ(kExpectedEIP, raw_context.eip);
EXPECT_EQ(0xbffe6edaU, raw_context.cs);
EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags);
EXPECT_EQ(0x659caaa4U, raw_context.esp);