diff options
author | mmentovai <mmentovai@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2006-10-23 19:24:58 +0000 |
---|---|---|
committer | mmentovai <mmentovai@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2006-10-23 19:24:58 +0000 |
commit | d119a921ea611dc38cfcb7411759ddf2c688603f (patch) | |
tree | 392d79dada82458d74b010a4974ca09cb204211c /src/processor/source_line_resolver.cc | |
parent | Update comments to reflect HTTPS support, r=mark. (diff) | |
download | breakpad-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.cc | 87 |
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; } |