aboutsummaryrefslogtreecommitdiff
path: root/src/processor/source_line_resolver.cc
diff options
context:
space:
mode:
authormmentovai <mmentovai@4c0a9323-5329-0410-9bdc-e9ce6186880e>2006-10-23 19:24:58 +0000
committermmentovai <mmentovai@4c0a9323-5329-0410-9bdc-e9ce6186880e>2006-10-23 19:24:58 +0000
commitd119a921ea611dc38cfcb7411759ddf2c688603f (patch)
tree392d79dada82458d74b010a4974ca09cb204211c /src/processor/source_line_resolver.cc
parentUpdate comments to reflect HTTPS support, r=mark. (diff)
downloadbreakpad-d119a921ea611dc38cfcb7411759ddf2c688603f.tar.xz
Make stack_frame_info vector hold linked_ptrs instead of objects;
make Stackwalker::Walk create and return a CallStack instead of filling a caller-supplied one (#54). r=bryner Interface change: Stackwalker::Walk and MinidumpProcessor::Process now return a new CallStack*. http://groups.google.com/group/airbag-dev/browse_thread/thread/d2bad5d7c115c3fe git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@45 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/processor/source_line_resolver.cc')
-rw-r--r--src/processor/source_line_resolver.cc87
1 files changed, 48 insertions, 39 deletions
diff --git a/src/processor/source_line_resolver.cc b/src/processor/source_line_resolver.cc
index e2e884ce..8a6fad16 100644
--- a/src/processor/source_line_resolver.cc
+++ b/src/processor/source_line_resolver.cc
@@ -28,18 +28,20 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdio.h>
-#include <map>
#include <string.h>
+#include <map>
+#include <memory>
#include <vector>
#include <utility>
#include "processor/source_line_resolver.h"
#include "google/stack_frame.h"
+#include "processor/linked_ptr.h"
#include "processor/address_map-inl.h"
#include "processor/contained_range_map-inl.h"
-#include "processor/linked_ptr.h"
#include "processor/range_map-inl.h"
#include "processor/stack_frame_info.h"
+using std::auto_ptr;
using std::map;
using std::vector;
using std::make_pair;
@@ -104,9 +106,10 @@ class SourceLineResolver::Module {
// Looks up the given relative address, and fills the StackFrame struct
// with the result. Additional debugging information, if available, is
- // placed in frame_info.
- void LookupAddress(MemAddr address,
- StackFrame *frame, StackFrameInfo *frame_info) const;
+ // returned. If no additional information is available, returns NULL.
+ // A NULL return value is not an error. The caller takes ownership of
+ // any returned StackFrameInfo object.
+ StackFrameInfo* LookupAddress(MemAddr address, StackFrame *frame) const;
private:
friend class SourceLineResolver;
@@ -163,7 +166,8 @@ class SourceLineResolver::Module {
// StackInfoTypes. These are split by type because there may be overlaps
// between maps of different types, but some information is only available
// as certain types.
- ContainedRangeMap<MemAddr, StackFrameInfo> stack_info_[STACK_INFO_LAST];
+ ContainedRangeMap< MemAddr, linked_ptr<StackFrameInfo> >
+ stack_info_[STACK_INFO_LAST];
};
SourceLineResolver::SourceLineResolver() : modules_(new ModuleMap) {
@@ -198,13 +202,14 @@ bool SourceLineResolver::HasModule(const string &module_name) const {
return modules_->find(module_name) != modules_->end();
}
-void SourceLineResolver::FillSourceLineInfo(StackFrame *frame,
- StackFrameInfo *frame_info) const {
+StackFrameInfo* SourceLineResolver::FillSourceLineInfo(
+ StackFrame *frame) const {
ModuleMap::const_iterator it = modules_->find(frame->module_name);
if (it != modules_->end()) {
- it->second->LookupAddress(frame->instruction - frame->module_base,
- frame, frame_info);
+ return it->second->LookupAddress(frame->instruction - frame->module_base,
+ frame);
}
+ return NULL;
}
bool SourceLineResolver::Module::LoadMap(const string &map_file) {
@@ -259,23 +264,24 @@ bool SourceLineResolver::Module::LoadMap(const string &map_file) {
return true;
}
-void SourceLineResolver::Module::LookupAddress(
- MemAddr address, StackFrame *frame, StackFrameInfo *frame_info) const {
- if (frame_info) {
- frame_info->valid = StackFrameInfo::VALID_NONE;
-
- // Check for debugging info first, before any possible early returns.
- // The caller will know that frame_info was filled in by checking its
- // valid field.
- //
- // We only know about STACK_INFO_FRAME_DATA and STACK_INFO_FPO. Prefer
- // them in this order. STACK_INFO_FRAME_DATA is the newer type that
- // includes its own program string. STACK_INFO_FPO is the older type
- // corresponding to the FPO_DATA struct. See stackwalker_x86.cc.
- if (!stack_info_[STACK_INFO_FRAME_DATA].RetrieveRange(address,
- frame_info)) {
- stack_info_[STACK_INFO_FPO].RetrieveRange(address, frame_info);
- }
+StackFrameInfo* SourceLineResolver::Module::LookupAddress(
+ MemAddr address, StackFrame *frame) const {
+ linked_ptr<StackFrameInfo> retrieved_info;
+ // Check for debugging info first, before any possible early returns.
+ //
+ // We only know about STACK_INFO_FRAME_DATA and STACK_INFO_FPO. Prefer
+ // them in this order. STACK_INFO_FRAME_DATA is the newer type that
+ // includes its own program string. STACK_INFO_FPO is the older type
+ // corresponding to the FPO_DATA struct. See stackwalker_x86.cc.
+ if (!stack_info_[STACK_INFO_FRAME_DATA].RetrieveRange(address,
+ &retrieved_info)) {
+ stack_info_[STACK_INFO_FPO].RetrieveRange(address, &retrieved_info);
+ }
+
+ auto_ptr<StackFrameInfo> frame_info;
+ if (retrieved_info.get()) {
+ frame_info.reset(new StackFrameInfo());
+ frame_info->CopyFrom(*retrieved_info.get());
}
// First, look for a matching FUNC range. Use RetrieveNearestRange instead
@@ -324,18 +330,20 @@ void SourceLineResolver::Module::LookupAddress(
frame->function_base = frame->module_base + public_address;
} else {
// No FUNC or PUBLIC data available.
- return;
+ return frame_info.release();
}
- if (frame_info &&
- !(frame_info->valid & StackFrameInfo::VALID_PARAMETER_SIZE)) {
+ if (!frame_info.get()) {
// Even without a relevant STACK line, many functions contain information
// about how much space their parameters consume on the stack. Prefer
// the STACK stuff (above), but if it's not present, take the
// information from the FUNC or PUBLIC line.
+ frame_info.reset(new StackFrameInfo());
frame_info->parameter_size = parameter_size;
frame_info->valid |= StackFrameInfo::VALID_PARAMETER_SIZE;
}
+
+ return frame_info.release();
}
// static
@@ -518,15 +526,16 @@ bool SourceLineResolver::Module::ParseStackInfo(char *stack_info_line) {
// if ContainedRangeMap were modified to allow replacement of
// already-stored values.
- stack_info_[type].StoreRange(rva, code_size,
- StackFrameInfo(prolog_size,
- epilog_size,
- parameter_size,
- saved_register_size,
- local_size,
- max_stack_size,
- allocates_base_pointer,
- program_string));
+ linked_ptr<StackFrameInfo> stack_frame_info(
+ new StackFrameInfo(prolog_size,
+ epilog_size,
+ parameter_size,
+ saved_register_size,
+ local_size,
+ max_stack_size,
+ allocates_base_pointer,
+ program_string));
+ stack_info_[type].StoreRange(rva, code_size, stack_frame_info);
return true;
}