Handle frame pointer omission, (#21), part 4 (final part!): FPO stackwalker.

r=bryner
 - This change allows Airbag to properly walk win32 stacks produced by code
   built with MSVC's frame pointer omission optimization (/Oy).  This
   optimization is enabled at /O1 and /O2.
 - There too many interface and file format changes to list here.

http://groups.google.com/group/airbag-dev/browse_thread/thread/85ce85bfa8457ece


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@42 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
mmentovai 2006-10-20 01:46:38 +00:00
parent 5afd60b067
commit 246f406828
33 changed files with 2643 additions and 1744 deletions

View file

@ -31,13 +31,15 @@
// corresponding symbol file, and checks the stack frames for correctness.
#include <string>
#include "google/call_stack.h"
#include "google/minidump_processor.h"
#include "google/stack_frame.h"
#include "google/symbol_supplier.h"
#include "processor/minidump.h"
using std::string;
using google_airbag::CallStack;
using google_airbag::MinidumpProcessor;
using google_airbag::StackFrames;
#define ASSERT_TRUE(cond) \
if (!(cond)) { \
@ -72,40 +74,40 @@ static bool RunTests() {
TestSymbolSupplier supplier;
MinidumpProcessor processor(&supplier);
StackFrames stack_frames;
CallStack stack;
string minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") +
"/src/processor/testdata/minidump2.dmp";
ASSERT_TRUE(processor.Process(minidump_file, &stack_frames));
ASSERT_EQ(stack_frames.size(), 4);
ASSERT_TRUE(processor.Process(minidump_file, &stack));
ASSERT_EQ(stack.frames()->size(), 4);
ASSERT_EQ(stack_frames[0].module_base, 0x400000);
ASSERT_EQ(stack_frames[0].module_name, "c:\\test_app.exe");
ASSERT_EQ(stack_frames[0].function_name, "CrashFunction");
ASSERT_EQ(stack_frames[0].source_file_name, "c:\\test_app.cc");
ASSERT_EQ(stack_frames[0].source_line, 36);
ASSERT_EQ(stack.frames()->at(0)->module_base, 0x400000);
ASSERT_EQ(stack.frames()->at(0)->module_name, "c:\\test_app.exe");
ASSERT_EQ(stack.frames()->at(0)->function_name, "CrashFunction()");
ASSERT_EQ(stack.frames()->at(0)->source_file_name, "c:\\test_app.cc");
ASSERT_EQ(stack.frames()->at(0)->source_line, 65);
ASSERT_EQ(stack_frames[1].module_base, 0x400000);
ASSERT_EQ(stack_frames[1].module_name, "c:\\test_app.exe");
ASSERT_EQ(stack_frames[1].function_name, "main");
ASSERT_EQ(stack_frames[1].source_file_name, "c:\\test_app.cc");
ASSERT_EQ(stack_frames[1].source_line, 42);
ASSERT_EQ(stack.frames()->at(1)->module_base, 0x400000);
ASSERT_EQ(stack.frames()->at(1)->module_name, "c:\\test_app.exe");
ASSERT_EQ(stack.frames()->at(1)->function_name, "main");
ASSERT_EQ(stack.frames()->at(1)->source_file_name, "c:\\test_app.cc");
ASSERT_EQ(stack.frames()->at(1)->source_line, 70);
// This comes from the CRT
ASSERT_EQ(stack_frames[2].module_base, 0x400000);
ASSERT_EQ(stack_frames[2].module_name, "c:\\test_app.exe");
ASSERT_EQ(stack_frames[2].function_name, "__tmainCRTStartup");
ASSERT_EQ(stack_frames[2].source_file_name,
ASSERT_EQ(stack.frames()->at(2)->module_base, 0x400000);
ASSERT_EQ(stack.frames()->at(2)->module_name, "c:\\test_app.exe");
ASSERT_EQ(stack.frames()->at(2)->function_name, "__tmainCRTStartup");
ASSERT_EQ(stack.frames()->at(2)->source_file_name,
"f:\\rtm\\vctools\\crt_bld\\self_x86\\crt\\src\\crt0.c");
ASSERT_EQ(stack_frames[2].source_line, 318);
ASSERT_EQ(stack.frames()->at(2)->source_line, 318);
// No debug info available for kernel32.dll
ASSERT_EQ(stack_frames[3].module_base, 0x7c800000);
ASSERT_EQ(stack_frames[3].module_name,
ASSERT_EQ(stack.frames()->at(3)->module_base, 0x7c800000);
ASSERT_EQ(stack.frames()->at(3)->module_name,
"C:\\WINDOWS\\system32\\kernel32.dll");
ASSERT_TRUE(stack_frames[3].function_name.empty());
ASSERT_TRUE(stack_frames[3].source_file_name.empty());
ASSERT_EQ(stack_frames[3].source_line, 0);
ASSERT_TRUE(stack.frames()->at(3)->function_name.empty());
ASSERT_TRUE(stack.frames()->at(3)->source_file_name.empty());
ASSERT_EQ(stack.frames()->at(3)->source_line, 0);
return true;
}