aboutsummaryrefslogtreecommitdiff
path: root/src/processor/stackwalker.cc
diff options
context:
space:
mode:
authormmentovai <mmentovai@4c0a9323-5329-0410-9bdc-e9ce6186880e>2006-10-20 01:46:38 +0000
committermmentovai <mmentovai@4c0a9323-5329-0410-9bdc-e9ce6186880e>2006-10-20 01:46:38 +0000
commit246f4068280b5b191303ff13671e43a0522987de (patch)
tree9de2b66c7d8f0241de53669de045318d6283da7e /src/processor/stackwalker.cc
parent5afd60b067a65920ba2e4705ccea71b880cc1607 (diff)
downloadgoogle-breakpad-246f4068280b5b191303ff13671e43a0522987de.tar.gz
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.cc35
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));
}
}