diff options
author | mmentovai <mmentovai@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2006-10-20 01:46:38 +0000 |
---|---|---|
committer | mmentovai <mmentovai@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2006-10-20 01:46:38 +0000 |
commit | 246f4068280b5b191303ff13671e43a0522987de (patch) | |
tree | 9de2b66c7d8f0241de53669de045318d6283da7e /src/processor/stackwalker.cc | |
parent | Improvements for Windows client/tool-side code. r=bryner (diff) | |
download | breakpad-246f4068280b5b191303ff13671e43a0522987de.tar.xz |
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
Diffstat (limited to 'src/processor/stackwalker.cc')
-rw-r--r-- | src/processor/stackwalker.cc | 35 |
1 files changed, 18 insertions, 17 deletions
diff --git a/src/processor/stackwalker.cc b/src/processor/stackwalker.cc index e5c79cc2..13bb2040 100644 --- a/src/processor/stackwalker.cc +++ b/src/processor/stackwalker.cc @@ -37,6 +37,8 @@ #include <memory> #include "processor/stackwalker.h" +#include "google/call_stack.h" +#include "google/stack_frame.h" #include "google/symbol_supplier.h" #include "processor/minidump.h" #include "processor/source_line_resolver.h" @@ -55,22 +57,23 @@ Stackwalker::Stackwalker(MemoryRegion *memory, MinidumpModuleList *modules, } -void Stackwalker::Walk(StackFrames *frames) { - frames->clear(); +void Stackwalker::Walk(CallStack *stack) { stack_frame_info_.clear(); SourceLineResolver resolver; // Begin with the context frame, and keep getting callers until there are // no more. - auto_ptr<StackFrame> frame(new StackFrame()); - auto_ptr<StackFrameInfo> frame_info(new StackFrameInfo()); - bool valid = GetContextFrame(frame.get()); - while (valid) { + // Take ownership of the pointer returned by GetContextFrame. + auto_ptr<StackFrame> frame(GetContextFrame()); + + while (frame.get()) { // frame already contains a good frame with properly set instruction and // frame_pointer fields. The frame structure comes from either the // context frame (above) or a caller frame (below). + StackFrameInfo frame_info; + // Resolve the module information, if a module map was provided. if (modules_) { MinidumpModule *module = @@ -84,22 +87,20 @@ void Stackwalker::Walk(StackFrames *frames) { resolver.LoadModule(frame->module_name, symbol_file); } } - resolver.FillSourceLineInfo(frame.get(), frame_info.get()); + resolver.FillSourceLineInfo(frame.get(), &frame_info); } } - // Copy the frame into the frames vector. - frames->push_back(*frame); - stack_frame_info_.push_back(*frame_info); + // Add the frame to the call stack. Relinquish the ownership claim + // over the frame, because the stack now owns it. + stack->frames_.push_back(frame.release()); - // Use a new object for the next frame, even though the old object was - // copied. If StackFrame provided some sort of Clear() method, then - // the same frame could be reused. - frame.reset(new StackFrame()); - frame_info.reset(new StackFrameInfo()); + // Copy the frame info. + stack_frame_info_.push_back(frame_info); + frame_info.Clear(); - // Get the next frame. - valid = GetCallerFrame(frame.get(), frames); + // Get the next frame and take ownership. + frame.reset(GetCallerFrame(stack)); } } |