3 Commits

Author SHA1 Message Date
nealsid
3e7863fc84 Integrated revisions 378-381 into branch to prepare for re-merge.
git-svn-id: http://google-breakpad.googlecode.com/svn/branches/linux-rewrite@382 4c0a9323-5329-0410-9bdc-e9ce6186880e
2009-08-11 01:48:59 +00:00
nealsid
de8df2f34a Merging in changes from Chrome's Breakpad Linux fork
git-svn-id: http://google-breakpad.googlecode.com/svn/branches/linux-rewrite@377 4c0a9323-5329-0410-9bdc-e9ce6186880e
2009-08-06 22:05:53 +00:00
nealsid
60e5e9547a Creating a private branch for linux rewrite from Chrome.
git-svn-id: http://google-breakpad.googlecode.com/svn/branches/linux-rewrite@376 4c0a9323-5329-0410-9bdc-e9ce6186880e
2009-08-06 21:47:58 +00:00
28 changed files with 203 additions and 763 deletions

View File

@@ -133,9 +133,9 @@
F9721F380E8B0CFC00D7E813 /* dump_syms.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dump_syms.h; path = ../../../common/mac/dump_syms.h; sourceTree = SOURCE_ROOT; };
F9721F390E8B0D0D00D7E813 /* dump_syms.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = dump_syms.mm; path = ../../../common/mac/dump_syms.mm; sourceTree = SOURCE_ROOT; };
F9721F6B0E8B0D7000D7E813 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
F9721F760E8B0DC700D7E813 /* bytereader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bytereader.cc; path = ../../../common/dwarf/bytereader.cc; sourceTree = SOURCE_ROOT; };
F9721F770E8B0DC700D7E813 /* dwarf2reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf2reader.cc; path = ../../../common/dwarf/dwarf2reader.cc; sourceTree = SOURCE_ROOT; };
F9721F780E8B0DC700D7E813 /* functioninfo.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = functioninfo.cc; path = ../../../common/dwarf/functioninfo.cc; sourceTree = SOURCE_ROOT; };
F9721F760E8B0DC700D7E813 /* bytereader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bytereader.cc; path = ../../../common/mac/dwarf/bytereader.cc; sourceTree = SOURCE_ROOT; };
F9721F770E8B0DC700D7E813 /* dwarf2reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf2reader.cc; path = ../../../common/mac/dwarf/dwarf2reader.cc; sourceTree = SOURCE_ROOT; };
F9721F780E8B0DC700D7E813 /* functioninfo.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = functioninfo.cc; path = ../../../common/mac/dwarf/functioninfo.cc; sourceTree = SOURCE_ROOT; };
F9721FA10E8B0E2300D7E813 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = /System/Library/Frameworks/SenTestingKit.framework; sourceTree = "<absolute>"; };
F9721FA80E8B0E4800D7E813 /* md5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = md5.c; path = ../../../common/md5.c; sourceTree = SOURCE_ROOT; };
F982089A0DB3280D0017AECA /* breakpad_nlist_test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = breakpad_nlist_test.h; sourceTree = "<group>"; };

View File

@@ -112,12 +112,9 @@ NSString *const kDefaultServerType = @"google";
@implementation NSTextField (ResizabilityExtentions)
- (float)breakpad_adjustHeightToFit {
NSRect oldFrame = [self frame];
// Starting with the 10.5 SDK, height won't grow, so make it huge to start.
NSRect presizeFrame = oldFrame;
presizeFrame.size.height = MAXFLOAT;
// sizeToFit will blow out the width rather than making the field taller, so
// we do it manually.
NSSize newSize = [[self cell] cellSizeForBounds:presizeFrame];
NSSize newSize = [[self cell] cellSizeForBounds:oldFrame];
NSRect newFrame = NSMakeRect(oldFrame.origin.x, oldFrame.origin.y,
NSWidth(oldFrame), newSize.height);
[self setFrame:newFrame];

View File

@@ -1,171 +0,0 @@
// Copyright 2009 Google Inc. All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Implementation of dwarf2reader::DieDispatcher class.
#include <cassert>
#include "common/dwarf/dwarf2diehandler.h"
namespace dwarf2reader {
DIEDispatcher::~DIEDispatcher() {
while (! die_handlers_.empty()) {
HandlerStack &entry = die_handlers_.top();
if (entry.handler_ != root_handler_)
delete entry.handler_;
die_handlers_.pop();
}
}
bool DIEDispatcher::StartCompilationUnit(uint64 offset, uint8 address_size,
uint8 offset_size, uint64 cu_length,
uint8 dwarf_version) {
return root_handler_->StartCompilationUnit(offset, address_size,
offset_size, cu_length,
dwarf_version);
}
bool DIEDispatcher::StartDIE(uint64 offset, enum DwarfTag tag,
const AttributeList& attrs) {
// The stack entry for the parent of this DIE, if there is one.
HandlerStack *parent = die_handlers_.empty() ? NULL : &die_handlers_.top();
// Does this call indicate that we're done receiving the parent's
// attributes' values? If so, call its EndAttributes member function.
if (parent && parent->handler_ && ! parent->reported_attributes_end_) {
parent->reported_attributes_end_ = true;
if (! parent->handler_->EndAttributes()) {
// Finish off this handler now. and edit *PARENT to indicate that
// we don't want to visit any of the children.
parent->handler_->Finish();
if (parent->handler_ != root_handler_) delete parent->handler_;
parent->handler_ = NULL;
return false;
}
}
// Find a handler for this DIE.
DIEHandler *handler;
if (parent) {
if (parent->handler_)
// Ask the parent to find a handler.
handler = parent->handler_->FindChildHandler(offset, tag, attrs);
else
// No parent handler means we're not interested in any of our
// children.
handler = NULL;
} else {
// This is the root DIE. For a non-root DIE, the parent's handler
// decides whether to visit it, but the root DIE has no parent
// handler, so we have a special method on the root DIE handler
// itself to decide.
if (root_handler_->StartRootDIE(offset, tag, attrs))
handler = root_handler_;
else
handler = NULL;
}
// Push a handler stack entry for this new handler. As an
// optimization, we don't push NULL-handler entries on top of other
// NULL-handler entries; we just let the oldest such entry stand for
// the whole subtree.
if (handler || (parent && parent->handler_)) {
HandlerStack entry;
entry.offset_ = offset;
entry.handler_ = handler;
entry.reported_attributes_end_ = false;
die_handlers_.push(entry);
}
return handler != NULL;
}
void DIEDispatcher::EndDIE(uint64 offset) {
assert(! die_handlers_.empty());
HandlerStack *entry = &die_handlers_.top();
if (entry->handler_) {
// This entry had better be the handler for this DIE.
assert(entry->offset_ == offset);
// If a DIE has no children, this EndDIE call indicates that we're
// done receiving its attributes' values.
if (! entry->reported_attributes_end_)
entry->handler_->EndAttributes(); // Ignore return value: no children.
entry->handler_->Finish();
if (entry->handler_ != root_handler_) delete entry->handler_;
} else {
// If this DIE is within a tree we're ignoring, then don't pop the
// handler stack: that entry stands for the whole tree.
if (entry->offset_ != offset)
return;
}
die_handlers_.pop();
}
void DIEDispatcher::ProcessAttributeUnsigned(uint64 offset,
enum DwarfAttribute attr,
enum DwarfForm form,
uint64 data) {
HandlerStack &current = die_handlers_.top();
// This had better be an attribute of the DIE we were meant to handle.
assert(offset == current.offset_);
current.handler_->ProcessAttributeUnsigned(attr, form, data);
}
void DIEDispatcher::ProcessAttributeSigned(uint64 offset,
enum DwarfAttribute attr,
enum DwarfForm form,
int64 data) {
HandlerStack &current = die_handlers_.top();
// This had better be an attribute of the DIE we were meant to handle.
assert(offset == current.offset_);
current.handler_->ProcessAttributeSigned(attr, form, data);
}
void DIEDispatcher::ProcessAttributeBuffer(uint64 offset,
enum DwarfAttribute attr,
enum DwarfForm form,
const char* data,
uint64 len) {
HandlerStack &current = die_handlers_.top();
// This had better be an attribute of the DIE we were meant to handle.
assert(offset == current.offset_);
current.handler_->ProcessAttributeBuffer(attr, form, data, len);
}
void DIEDispatcher::ProcessAttributeString(uint64 offset,
enum DwarfAttribute attr,
enum DwarfForm form,
const string& data) {
HandlerStack &current = die_handlers_.top();
// This had better be an attribute of the DIE we were meant to handle.
assert(offset == current.offset_);
current.handler_->ProcessAttributeString(attr, form, data);
}
} // namespace dwarf2reader

View File

@@ -1,323 +0,0 @@
// Copyright 2009 Google Inc. All Rights Reserved. -*- mode: c++ -*-
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// dwarf2reader::CompilationUnit is a simple and direct parser for
// DWARF data, but its handler interface is not convenient to use. In
// particular:
//
// - CompilationUnit calls Dwarf2Handler's member functions to report
// every attribute's value, regardless of what sort of DIE it is.
// As a result, the ProcessAttributeX functions end up looking like
// this:
//
// switch (parent_die_tag) {
// case DW_TAG_x:
// switch (attribute_name) {
// case DW_AT_y:
// handle attribute y of DIE type x
// ...
// } break;
// ...
// }
//
// In C++ it's much nicer to use virtual function dispatch to find
// the right code for a given case than to switch on the DIE tag
// like this.
//
// - Processing different kinds of DIEs requires different sets of
// data. It would be nice to be able to have separate classes for
// separate kinds of DIEs, each with the members appropriate to its
// role, instead of having one handler class that needs to hold data
// for all every DIE type.
//
// - It would be nice to have separate handler objects for separate
// DIEs, instead of a single handler instance required to keep track
// of everything.
//
// - It's not convenient to take some action after all attributes have
// been seen, but before visiting any children. The only indication
// you have that a DIE's attribute list is complete is that you get
// either a StartDIE or an EndDIE call.
//
// - It's not convenient to make use of the tree structure of the
// DIEs. Skipping all the children of a given die requires
// maintaining state and returning false from StartDIE until we get
// an EndDIE call with the appropriate offset. And it's not
// convenient to maintain the stack of contexts for the DIEs we have
// decided to enter.
//
// This interface tries to take care of all that. (How'd you guess?)
//
// Using the classes here, you provide an initial handler for the root
// DIE of the compilation unit. Each handler receives its DIE's
// attributes, and provides fresh handler objects for children of
// interest, if any.
//
// You use them as follows:
//
// - Define handler classes specialized to particular DIE types of
// interest. These handler classes must inherit from the DIEHandler
// class, defined below. Thus:
//
// class My_DW_TAG_X_Handler: public DIEHandler { ... };
// class My_DW_TAG_Y_Handler: public DIEHandler { ... };
//
// DIEHandler subclasses needn't correspond exactly to single DIE
// types, as shown here; the point is that you can write different
// classes for different kinds of DIEs.
//
// - In particular, define a DIE handler class for the compilation
// unit's root DIE, that inherits from the RootDIEHandler class
//
// class My_DW_TAG_compile_unit_Handler: public RootDIEHandler { ... };
//
// RootDIEHandler inherits from DIEHandler, adding a few additional
// member functions for examining the compilation unit as a whole,
// and other quirks of rootness.
//
// - Then, create a DIEDispatcher instance, passing it an instance of
// your root DIE handler, and use that as the
// dwarf2reader::CompilationUnit's handler:
//
// My_DW_TAG_compile_unit_Handler root_die_handler(...);
// DIEDispatcher die_dispatcher(&root_die_handler);
// CompilationUnit reader(sections, offset, bytereader, &die_dispatcher);
//
// Here, 'die_dispatcher' acts as a shim between 'reader' and the
// various DIE-specific handlers.
//
// - When you call reader.Start(), die_dispatcher behaves as follows,
// starting with your root die handler and the compilation unit's
// root DIE:
//
// - It calls the handler's ProcessAttributeX member functions for
// each of the DIE's attributes.
//
// - It calls the handler's EndAttributes member function. This
// should return true if any of the DIE's children should be
// visited, in which case:
//
// - die_dispatcher calls the handler's FindChildHandler member
// function. If that returns NULL, die_dispatcher ignores that
// child and its descendants. Otherwise, FindChildHandler
// returns a pointer to a DIEHandler instance; die_dispatcher
// uses that handler to process the child, using this procedure
// recursively.
//
// - When die_dispatcher has finished processing all the DIE's
// children, it invokes the handler's Finish() member function,
// and destroys the handler. (As a special case, it doesn't
// destroy the root DIE handler.)
//
// This allows the code for handling a particular kind of DIE to be
// gathered together in a single class, makes it easy to skip all the
// children or individual children of a particular DIE, and provides
// appropriate parental context for each die.
#ifndef COMMON_DWARF_DWARF2DIEHANDLER_H__
#define COMMON_DWARF_DWARF2DIEHANDLER_H__
#include <stack>
#include "common/dwarf/types.h"
#include "common/dwarf/dwarf2enums.h"
#include "common/dwarf/dwarf2reader.h"
namespace dwarf2reader {
// A parent class for handlers for specific DIE types.
// The series of calls made on a DIE handler is as follows:
//
// - construction, by the parent DIE's handler
// - for each attribute of the DIE:
// - ProcessAttributeX()
// - EndAttributes()
// - if that returned true, then for each child:
// - FindChildHandler()
// - if that returns non-NULL:
// - this sequence inserted recursively
// - Finish()
class DIEHandler {
public:
DIEHandler() { }
virtual ~DIEHandler() { }
// When we visit a DIE, we first use these member functions to
// report the DIE's attributes and their values. These have the
// same restrictions as the corresponding member functions of
// dwarf2reader::Dwarf2Handler.
//
// The default definitions ignore the values they are passed.
virtual void ProcessAttributeUnsigned(enum DwarfAttribute attr,
enum DwarfForm form,
uint64 data) { }
virtual void ProcessAttributeSigned(enum DwarfAttribute attr,
enum DwarfForm form,
int64 data) { }
virtual void ProcessAttributeBuffer(enum DwarfAttribute attr,
enum DwarfForm form,
const char* data,
uint64 len) { }
virtual void ProcessAttributeString(enum DwarfAttribute attr,
enum DwarfForm form,
const string& data) { }
// Once we have reported all the DIE's attributes' values, we call
// this member function. If it returns false, we skip all the DIE's
// children. If it returns true, we call FindChildHandler on each
// child. If that returns a handler object, we use that to visit
// the child; otherwise, we skip it.
//
// The default definition applies FindChildHandler to all children.
virtual bool EndAttributes() { return true; }
// If EndAttributes returns true to indicate that some of the DIE's
// children might be of interest, then we apply this function to
// each of the DIE's children. If it returns a handler object, then
// we use that to visit the child. If it returns NULL, we skip that
// child (and its children).
//
// OFFSET is the offset of the child; TAG indicates what kind of DIE
// it is; and ATTRS is the list of attributes the DIE will have, and
// their forms (their values are not provided).
//
// The default definition doesn't handle any children.
virtual DIEHandler *FindChildHandler(uint64 offset, enum DwarfTag tag,
const AttributeList &attrs) {
return NULL;
}
// When we are done processing a DIE, we call this member function.
// This happens after the EndAttributes call, all FindChildHandler
// calls (if any), and all operations on the children themselves (if
// any).
virtual void Finish() { };
};
// A subclass of DIEHandler, with additional kludges for handling the
// compilation unit's root die.
class RootDIEHandler: public DIEHandler {
public:
RootDIEHandler() { }
virtual ~RootDIEHandler() { }
// We pass the values reported via StartCompilationUnit to this
// member function, and skip the entire compilation unit if it
// returns false. So the root DIE handler is actually also a
// compilation unit handler. The default definition always visits
// the compilation unit.
virtual bool StartCompilationUnit(uint64 offset, uint8 address_size,
uint8 offset_size, uint64 cu_length,
uint8 dwarf_version) { return true; }
// For the root DIE handler only, we pass the offset, tag and
// attributes of the compilation unit's root DIE. This is the only
// way the root DIE handler can find the root DIE's tag. If this
// function returns true, we will visit the root DIE using the usual
// DIEHandler methods; otherwise, we skip the entire compilation
// unit.
//
// The default definition elects to visit the root DIE.
virtual bool StartRootDIE(uint64 offset, enum DwarfTag tag,
const AttributeList& attrs) { return true; }
};
class DIEDispatcher: public Dwarf2Handler {
public:
// Create a Dwarf2Handler which uses ROOT_HANDLER as the handler for
// the compilation unit's root die, as described for the DIEHandler
// class.
DIEDispatcher(RootDIEHandler *root_handler) :
root_handler_(root_handler) { }
// Destroying a DIEDispatcher destroys all active handler objects
// except the root handler.
~DIEDispatcher();
bool StartCompilationUnit(uint64 offset, uint8 address_size,
uint8 offset_size, uint64 cu_length,
uint8 dwarf_version);
bool StartDIE(uint64 offset, enum DwarfTag tag,
const AttributeList &attrs);
void ProcessAttributeUnsigned(uint64 offset,
enum DwarfAttribute attr,
enum DwarfForm form,
uint64 data);
void ProcessAttributeSigned(uint64 offset,
enum DwarfAttribute attr,
enum DwarfForm form,
int64 data);
void ProcessAttributeBuffer(uint64 offset,
enum DwarfAttribute attr,
enum DwarfForm form,
const char* data,
uint64 len);
void ProcessAttributeString(uint64 offset,
enum DwarfAttribute attr,
enum DwarfForm form,
const string &data);
void EndDIE(uint64 offset);
private:
// The type of a handler stack entry. This includes some fields
// which don't really need to be on the stack --- they could just be
// single data members of DIEDispatcher --- but putting them here
// makes it easy to see that the code is correct.
struct HandlerStack {
// The offset of the DIE for this handler stack entry.
uint64 offset_;
// The object interested in this DIE's attributes and children.
// If NULL, we're not interested in either.
DIEHandler *handler_;
// Have we reported the end of this DIE's attributes to the handler?
bool reported_attributes_end_;
};
// Stack of DIE attribute handlers. At StartDIE(D), the top of the
// stack is the handler of D's parent, whom we may ask for a handler
// for D itself. At EndDIE(D), the top of the stack is D's handler.
// Special cases:
//
// - Before we've seen the compilation unit's root DIE, the stack is
// empty; we'll call root_handler_'s special member functions, and
// perhaps push root_handler_ on the stack to look at the root's
// immediate children.
//
// - When we decide to ignore a subtree, we only push an entry on
// the stack for the root of the tree being ignored, rather than
// pushing lots of stack entries with ignore_children_ set.
stack<HandlerStack> die_handlers_;
// The root handler. We don't push it on die_handlers_ until we
// actually get the StartDIE call for the root.
RootDIEHandler *root_handler_;
};
} // namespace dwarf2reader
#endif // COMMON_DWARF_DWARF2DIEHANDLER_H__

View File

@@ -27,12 +27,14 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <a.out.h>
#include <assert.h>
#include <cxxabi.h>
#include <elf.h>
#include <errno.h>
#include <fcntl.h>
#include <link.h>
#include <stab.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
@@ -146,7 +148,6 @@ class DumpStabsHandler: public google_breakpad::StabsHandler {
bool StartFunction(const std::string &name, uint64_t address);
bool EndFunction(uint64_t address);
bool Line(uint64_t address, const char *name, int number);
void Warning(const char *format, ...);
// Do any final processing necessary to make module_ contain all the
// data provided by the STABS reader.
@@ -268,13 +269,6 @@ bool DumpStabsHandler::Line(uint64_t address, const char *name, int number) {
return true;
}
void DumpStabsHandler::Warning(const char *format, ...) {
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
}
void DumpStabsHandler::Finalize() {
// Sort our boundary list, so we can search it quickly.
sort(boundaries_.begin(), boundaries_.end());

View File

@@ -94,13 +94,8 @@ bool StabsReader::ProcessCompilationUnit() {
if (symbol_ >= symbols_end_ || symbol_->n_type != N_SO)
return true;
const char *name = SymbolString();
if (name[0] == '\0') {
// This seems to be a stray end-of-compilation-unit marker;
// consume it, but don't report the end, since we didn't see a
// beginning.
symbol_++;
if (name[0] == '\0')
return true;
}
current_source_file_ = name;
}
@@ -112,9 +107,9 @@ bool StabsReader::ProcessCompilationUnit() {
symbol_++;
// The STABS documentation says that some compilers may emit
// additional N_SO entries with names immediately following the
// first, and that they should be ignored. However, the original
// Breakpad STABS reader doesn't ignore them, so we won't either.
// additional N_SO units with names immediately following the first,
// and that they should be ignored. However, the original Breakpad
// STABS reader doesn't ignore them, so we won't either.
// Process the body of the compilation unit, up to the next N_SO.
while (symbol_ < symbols_end_ && symbol_->n_type != N_SO) {

View File

@@ -54,8 +54,8 @@ class StabsReader {
// Create a reader for the STABS debug information whose .stab
// section is the STAB_SIZE bytes at STAB, and whose .stabstr
// section is the STABSTR_SIZE bytes at STABSTR. The reader will
// call the member functions of HANDLER to report the information it
// finds, when the reader's 'Process' member function is called.
// call the methods of HANDLER to report the information it finds,
// when the reader's 'process' method is called.
//
// Note that, in ELF, the .stabstr section should be found using the
// 'sh_link' field of the .stab section header, not by name.
@@ -63,9 +63,9 @@ class StabsReader {
const uint8_t *stabstr, size_t stabstr_size,
StabsHandler *handler);
// Process the STABS data, calling the handler's member functions to
// report what we find. While the handler functions return true,
// continue to process until we reach the end of the section. If we
// Process the STAB data, calling the handler's methods to report
// what we find. While the handler functions return true, continue
// to process until we reach the end of the section. If we
// processed the entire section and all handlers returned true,
// return true. If any handler returned false, return false.
bool Process();
@@ -101,13 +101,12 @@ class StabsReader {
const char *current_source_file_;
};
// Consumer-provided callback structure for the STABS reader. Clients
// of the STABS reader provide an instance of this structure. The
// reader then invokes the member functions of that instance to report
// the information it finds.
// Consumer-provided callback structure for the STABS reader.
// Clients of the STABS reader provide an instance of this structure.
// The reader then invokes the methods of that instance to report the
// information it finds.
//
// The default definitions of the member functions do nothing, and return
// true so processing will continue.
// The default definitions of the methods do nothing.
class StabsHandler {
public:
StabsHandler() { }
@@ -135,10 +134,9 @@ class StabsHandler {
// file names.
//
// Thus, it's safe to use (say) std::map<char *, ...>, which does
// string address comparisons, not string content comparisons.
// Since all the strings are in same array of characters --- the
// .stabstr section --- comparing their addresses produces
// predictable, if not lexicographically meaningful, results.
// address comparisons. Since all the pointers are into the array
// holding the .stabstr section's contents, comparing them produces
// predictable results.
// Begin processing a compilation unit whose main source file is
// named FILENAME, and whose base address is ADDRESS. If
@@ -149,10 +147,10 @@ class StabsHandler {
return true;
}
// Finish processing the compilation unit. If ADDRESS is non-zero,
// it is the ending address of the compilation unit. If ADDRESS is
// zero, then the compilation unit's ending address is not
// available, and the consumer must infer it by other means.
// Finish processing the compilation unit. If END_ADDRESS is
// non-zero, it is the ending address of the compilation unit. This
// information may not be available, in which case the consumer must
// infer it by other means.
virtual bool EndCompilationUnit(uint64_t address) { return true; }
// Begin processing a function named NAME, whose starting address is
@@ -163,16 +161,14 @@ class StabsHandler {
// .stabstr section; this is because the name as it appears in the
// STABS data is followed by type information. The value passed to
// StartFunction is the function name alone.
//
// In languages that use name mangling, like C++, NAME is mangled.
virtual bool StartFunction(const std::string &name, uint64_t address) {
return true;
}
// Finish processing the function. If ADDRESS is non-zero, it is
// the ending address for the function. If ADDRESS is zero, then
// the function's ending address is not available, and the consumer
// must infer it by other means.
// Finishing processing the function. If END_ADDRESS is non-zero,
// it is the ending address for the function. This information may
// not be available, in which case the consumer must infer it by
// other means.
virtual bool EndFunction(uint64_t address) { return true; }
// Report that the code at ADDRESS is attributable to line NUMBER of
@@ -183,9 +179,8 @@ class StabsHandler {
}
// Report a warning. FORMAT is a printf-like format string,
// specifying how to format the subsequent arguments. By default,
// print the message to the standard error output.
virtual void Warning(const char *format, ...) = 0;
// specifying how to format the subsequent arguments.
virtual void Warning(const char *format, ...) { }
};
} // namespace google_breakpad

View File

@@ -33,11 +33,11 @@
#import <Foundation/Foundation.h>
#include <mach-o/loader.h>
#include "common/dwarf/dwarf2reader.h"
#include "common/mac/dwarf/dwarf2reader.h"
// This will map from an architecture string to a SectionMap, which
// will contain the offsets for all the sections in the dictionary
typedef map<string, dwarf2reader::SectionMap *> ArchSectionMap;
typedef hash_map<string, dwarf2reader::SectionMap *> ArchSectionMap;
@interface DumpSymbols : NSObject {
@protected

View File

@@ -47,9 +47,9 @@
#import "dump_syms.h"
#import "common/mac/file_id.h"
#import "common/mac/macho_utilities.h"
#import "common/dwarf/dwarf2reader.h"
#import "common/dwarf/functioninfo.h"
#import "common/dwarf/bytereader.h"
#import "common/mac/dwarf/dwarf2reader.h"
#import "common/mac/dwarf/functioninfo.h"
#import "common/mac/dwarf/bytereader.h"
using google_breakpad::FileID;
@@ -68,6 +68,15 @@ static NSString *kHeaderCPUTypeKey = @"cpuType";
// for pruning out extraneous non-function symbols.
static const int kTextSection = 1;
namespace __gnu_cxx {
template<>
struct hash<std::string> {
size_t operator()(const std::string& k) const {
return hash< const char* >()( k.c_str() );
}
};
}
// Dump FunctionMap to stdout. Print address, function name, file
// name, line number, lowpc, and highpc if available.
void DumpFunctionMap(const dwarf2reader::FunctionMap function_map) {

View File

@@ -29,9 +29,7 @@
#ifndef UTIL_DEBUGINFO_BYTEREADER_INL_H__
#define UTIL_DEBUGINFO_BYTEREADER_INL_H__
#include <cassert>
#include "common/dwarf/bytereader.h"
#include "common/mac/dwarf/bytereader.h"
namespace dwarf2reader {
@@ -39,11 +37,9 @@ inline uint8 ByteReader::ReadOneByte(const char* buffer) const {
return buffer[0];
}
inline uint16 ByteReader::ReadTwoBytes(const char* signed_buffer) const {
const unsigned char *buffer
= reinterpret_cast<const unsigned char *>(signed_buffer);
const uint16 buffer0 = buffer[0];
const uint16 buffer1 = buffer[1];
inline uint16 ByteReader::ReadTwoBytes(const char* buffer) const {
const uint16 buffer0 = static_cast<uint16>(buffer[0]);
const uint16 buffer1 = static_cast<uint16>(buffer[1]);
if (endian_ == ENDIANNESS_LITTLE) {
return buffer0 | buffer1 << 8;
} else {
@@ -51,13 +47,11 @@ inline uint16 ByteReader::ReadTwoBytes(const char* signed_buffer) const {
}
}
inline uint64 ByteReader::ReadFourBytes(const char* signed_buffer) const {
const unsigned char *buffer
= reinterpret_cast<const unsigned char *>(signed_buffer);
const uint32 buffer0 = buffer[0];
const uint32 buffer1 = buffer[1];
const uint32 buffer2 = buffer[2];
const uint32 buffer3 = buffer[3];
inline uint64 ByteReader::ReadFourBytes(const char* buffer) const {
const uint32 buffer0 = static_cast<uint32>(buffer[0]);
const uint32 buffer1 = static_cast<uint32>(buffer[1]);
const uint32 buffer2 = static_cast<uint32>(buffer[2]);
const uint32 buffer3 = static_cast<uint32>(buffer[3]);
if (endian_ == ENDIANNESS_LITTLE) {
return buffer0 | buffer1 << 8 | buffer2 << 16 | buffer3 << 24;
} else {
@@ -65,17 +59,15 @@ inline uint64 ByteReader::ReadFourBytes(const char* signed_buffer) const {
}
}
inline uint64 ByteReader::ReadEightBytes(const char* signed_buffer) const {
const unsigned char *buffer
= reinterpret_cast<const unsigned char *>(signed_buffer);
const uint64 buffer0 = buffer[0];
const uint64 buffer1 = buffer[1];
const uint64 buffer2 = buffer[2];
const uint64 buffer3 = buffer[3];
const uint64 buffer4 = buffer[4];
const uint64 buffer5 = buffer[5];
const uint64 buffer6 = buffer[6];
const uint64 buffer7 = buffer[7];
inline uint64 ByteReader::ReadEightBytes(const char* buffer) const {
const uint64 buffer0 = static_cast<uint64>(buffer[0]);
const uint64 buffer1 = static_cast<uint64>(buffer[1]);
const uint64 buffer2 = static_cast<uint64>(buffer[2]);
const uint64 buffer3 = static_cast<uint64>(buffer[3]);
const uint64 buffer4 = static_cast<uint64>(buffer[4]);
const uint64 buffer5 = static_cast<uint64>(buffer[5]);
const uint64 buffer6 = static_cast<uint64>(buffer[6]);
const uint64 buffer7 = static_cast<uint64>(buffer[7]);
if (endian_ == ENDIANNESS_LITTLE) {
return buffer0 | buffer1 << 8 | buffer2 << 16 | buffer3 << 24 |
buffer4 << 32 | buffer5 << 40 | buffer6 << 48 | buffer7 << 56;

View File

@@ -26,9 +26,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "common/dwarf/bytereader-inl.h"
#include "common/mac/dwarf/bytereader-inl.h"
#include "common/dwarf/bytereader.h"
#include "common/mac/dwarf/bytereader.h"
namespace dwarf2reader {

View File

@@ -26,11 +26,11 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef COMMON_DWARF_BYTEREADER_H__
#define COMMON_DWARF_BYTEREADER_H__
#ifndef COMMON_MAC_DWARF_BYTEREADER_H__
#define COMMON_MAC_DWARF_BYTEREADER_H__
#include <string>
#include "common/dwarf/types.h"
#include "common/mac/dwarf/types.h"
namespace dwarf2reader {
@@ -129,4 +129,4 @@ class ByteReader {
} // namespace dwarf2reader
#endif // COMMON_DWARF_BYTEREADER_H__
#endif // COMMON_MAC_DWARF_BYTEREADER_H__

View File

@@ -26,8 +26,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef COMMON_DWARF_DWARF2ENUMS_H__
#define COMMON_DWARF_DWARF2ENUMS_H__
#ifndef COMMON_MAC_DWARF_DWARF2ENUMS_H__
#define COMMON_MAC_DWARF_DWARF2ENUMS_H__
namespace dwarf2reader {
@@ -486,40 +486,5 @@ enum DwarfOpcode {
DW_OP_GNU_push_tls_address =0xe0
};
// Source languages. These are values for DW_AT_language.
enum DwarfLanguage
{
DW_LANG_none =0x0000,
DW_LANG_C89 =0x0001,
DW_LANG_C =0x0002,
DW_LANG_Ada83 =0x0003,
DW_LANG_C_plus_plus =0x0004,
DW_LANG_Cobol74 =0x0005,
DW_LANG_Cobol85 =0x0006,
DW_LANG_Fortran77 =0x0007,
DW_LANG_Fortran90 =0x0008,
DW_LANG_Pascal83 =0x0009,
DW_LANG_Modula2 =0x000a,
DW_LANG_Java =0x000b,
DW_LANG_C99 =0x000c,
DW_LANG_Ada95 =0x000d,
DW_LANG_Fortran95 =0x000e,
DW_LANG_PLI =0x000f,
DW_LANG_ObjC =0x0010,
DW_LANG_ObjC_plus_plus =0x0011,
DW_LANG_UPC =0x0012,
DW_LANG_D =0x0013,
// Implementation-defined language code range.
DW_LANG_lo_user = 0x8000,
DW_LANG_hi_user = 0xffff,
// Extensions.
// MIPS assembly language. The GNU toolchain uses this for all
// assembly languages, since there's no generic DW_LANG_ value for that.
DW_LANG_Mips_Assembler =0x8001,
DW_LANG_Upc =0x8765 // Unified Parallel C
};
} // namespace dwarf2reader
#endif // COMMON_DWARF_DWARF2ENUMS_H__
#endif // COMMON_MAC_DWARF_DWARF2ENUMS_H__

View File

@@ -26,15 +26,25 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <ext/hash_map>
#include <stack>
#include <utility>
#include <memory>
#include <cstring>
#include "common/dwarf/bytereader-inl.h"
#include "common/dwarf/dwarf2reader.h"
#include "common/dwarf/bytereader.h"
#include "common/dwarf/line_state_machine.h"
#include "common/mac/dwarf/bytereader-inl.h"
#include "common/mac/dwarf/dwarf2reader.h"
#include "common/mac/dwarf/bytereader.h"
#include "common/mac/dwarf/line_state_machine.h"
namespace __gnu_cxx
{
template<> struct hash< std::string >
{
size_t operator()( const std::string& x ) const
{
return hash< const char* >()( x.c_str() );
}
};
}
namespace dwarf2reader {
@@ -77,12 +87,8 @@ void CompilationUnit::ReadAbbrevs() {
if (abbrevs_)
return;
// First get the debug_abbrev section. ".debug_abbrev" is the name
// recommended in the DWARF spec, and used on Linux;
// "__debug_abbrev" is the name used in Mac OS X Mach-O files.
SectionMap::const_iterator iter = sections_.find(".debug_abbrev");
if (iter == sections_.end())
iter = sections_.find("__debug_abbrev");
// First get the debug_abbrev section
SectionMap::const_iterator iter = sections_.find("__debug_abbrev");
assert(iter != sections_.end());
abbrevs_ = new vector<Abbrev>;
@@ -94,9 +100,7 @@ void CompilationUnit::ReadAbbrevs() {
const char* abbrev_start = iter->second.first +
header_.abbrev_offset;
const char* abbrevptr = abbrev_start;
#ifndef NDEBUG
const uint64 abbrev_length = iter->second.second - header_.abbrev_offset;
#endif
while (1) {
CompilationUnit::Abbrev abbrev;
@@ -269,12 +273,8 @@ void CompilationUnit::ReadHeader() {
}
uint64 CompilationUnit::Start() {
// First get the debug_info section. ".debug_info" is the name
// recommended in the DWARF spec, and used on Linux; "__debug_info"
// is the name used in Mac OS X Mach-O files.
SectionMap::const_iterator iter = sections_.find(".debug_info");
if (iter == sections_.end())
iter = sections_.find("__debug_info");
// First get the debug_info section
SectionMap::const_iterator iter = sections_.find("__debug_info");
assert(iter != sections_.end());
// Set up our buffer
@@ -304,12 +304,8 @@ uint64 CompilationUnit::Start() {
// Otherwise, continue by reading our abbreviation entries.
ReadAbbrevs();
// Set the string section if we have one. ".debug_str" is the name
// recommended in the DWARF spec, and used on Linux; "__debug_str"
// is the name used in Mac OS X Mach-O files.
iter = sections_.find(".debug_str");
if (iter == sections_.end())
iter = sections_.find("__debug_str");
// Set the string section if we have one.
iter = sections_.find("__debug_str");
if (iter != sections_.end()) {
string_buffer_ = iter->second.first;
string_buffer_length_ = iter->second.second;
@@ -480,7 +476,7 @@ void CompilationUnit::ProcessDIEs() {
// we need semantics of boost scoped_ptr here - no intention of trasnferring
// ownership of the stack. use const, but then we limit ourselves to not
// ever being able to call .reset() on the smart pointer.
std::auto_ptr<stack<uint64> > const die_stack(new stack<uint64>);
auto_ptr<stack<uint64> > const die_stack(new stack<uint64>);
while (dieptr < (lengthstart + header_.length)) {
// We give the user the absolute offset from the beginning of
@@ -815,18 +811,16 @@ void LineInfo::ReadLines() {
lengthstart += 4;
const char* lineptr = after_header_;
lsm.Reset(header_.default_is_stmt);
while (lineptr < lengthstart + header_.total_length) {
size_t oplength;
bool add_line = ProcessOneOpcode(reader_, handler_, header_,
lineptr, &lsm, &oplength, (uintptr_t)-1, NULL);
lineptr += oplength;
if (lsm.end_sequence) {
handler_->EndSequence(lsm.address);
lsm.Reset(header_.default_is_stmt);
} else if (add_line) {
handler_->AddLine(lsm.address, lsm.file_num, lsm.line_num,
lsm.column_num);
lsm.Reset(header_.default_is_stmt);
while (!lsm.end_sequence) {
size_t oplength;
bool add_line = ProcessOneOpcode(reader_, handler_, header_,
lineptr, &lsm, &oplength, (uintptr_t)-1, NULL);
if (add_line)
handler_->AddLine(lsm.address, lsm.file_num, lsm.line_num,
lsm.column_num);
lineptr += oplength;
}
}

View File

@@ -33,19 +33,20 @@
// reading if you wish to modify the implementation.
// Only a cursory attempt is made to explain terminology that is
// used here, as it is much better explained in the standard documents
#ifndef COMMON_DWARF_DWARF2READER_H__
#define COMMON_DWARF_DWARF2READER_H__
#ifndef COMMON_MAC_DWARF_DWARF2READER_H__
#define COMMON_MAC_DWARF_DWARF2READER_H__
#include <ext/hash_map>
#include <list>
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "common/dwarf/dwarf2enums.h"
#include "common/dwarf/types.h"
#include "common/mac/dwarf/dwarf2enums.h"
#include "common/mac/dwarf/types.h"
using namespace std;
using namespace __gnu_cxx;
namespace dwarf2reader {
struct LineStateMachine;
@@ -55,7 +56,7 @@ class LineInfoHandler;
// This maps from a string naming a section to a pair containing a
// the data for the section, and the size of the section.
typedef map<string, pair<const char*, uint64> > SectionMap;
typedef hash_map<string, pair<const char*, uint64> > SectionMap;
typedef list<pair<enum DwarfAttribute, enum DwarfForm> > AttributeList;
typedef AttributeList::iterator AttributeIterator;
typedef AttributeList::const_iterator ConstAttributeIterator;
@@ -173,16 +174,6 @@ class LineInfoHandler {
// starts at, if we know it (0 otherwise).
virtual void AddLine(uint64 address, uint32 file_num, uint32 line_num,
uint32 column_num) { }
// Called at the end of a sequence of lines. ADDRESS is the address
// of the first byte after the final machine instruction of the
// sequence.
//
// Note that this is *not* necessarily the end of the line data for
// the compilation unit: a single compilation unit's line program
// may contain several "end of sequence" markers, to describe (for
// example) several discontiguous regions of code.
virtual void EndSequence(uint64 address) { }
};
// The base of DWARF2/3 debug info is a DIE (Debugging Information
@@ -234,11 +225,8 @@ class CompilationUnit {
// Begin reading a Dwarf2 compilation unit, and calling the
// callbacks in the Dwarf2Handler
// Return the full length of the compilation unit, including
// headers. This plus the starting offset passed to the constructor
// is the offset of the end of the compilation unit --- the start of
// the next compilation unit, if there is one.
// Return the offset of the end of the compilation unit - the passed
// in offset.
uint64 Start();
private:

View File

@@ -34,9 +34,19 @@
#include <vector>
#include "common/dwarf/functioninfo.h"
#include "common/mac/dwarf/functioninfo.h"
#include "common/dwarf/bytereader.h"
#include "common/mac/dwarf/bytereader.h"
namespace __gnu_cxx
{
template<>
struct hash<std::string>
{
size_t operator()(const std::string& k) const;
};
}
namespace dwarf2reader {
@@ -121,17 +131,6 @@ void CULineInfoHandler::AddLine(uint64 address, uint32 file_num,
}
}
void CULineInfoHandler::EndSequence(uint64 address) {
// To preserve this code's behavior prior to the addition of the
// EndSequence member function, we duplicate the previous line,
// changing its address to ADDRESS.
LineMap::iterator it = linemap_->lower_bound(address);
if (it != linemap_->begin()) {
it--;
linemap_->insert(make_pair(address, it->second));
}
}
bool CUFunctionInfoHandler::StartCompilationUnit(uint64 offset,
uint8 address_size,
uint8 offset_size,

View File

@@ -31,15 +31,15 @@
// collector that uses the DWARF2/3 reader interface to build a mapping
// of addresses to files, lines, and functions.
#ifndef COMMON_DWARF_FUNCTIONINFO_H__
#define COMMON_DWARF_FUNCTIONINFO_H__
#ifndef COMMON_MAC_DWARF_FUNCTIONINFO_H__
#define COMMON_MAC_DWARF_FUNCTIONINFO_H__
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "common/dwarf/dwarf2reader.h"
#include "common/mac/dwarf/dwarf2reader.h"
namespace dwarf2reader {
@@ -99,16 +99,6 @@ class CULineInfoHandler: public LineInfoHandler {
virtual void AddLine(uint64 address, uint32 file_num, uint32 line_num,
uint32 column_num);
// Called at the end of a sequence of lines. ADDRESS is the address
// of the first byte after the final machine instruction of the
// sequence.
//
// Note that this is *not* necessarily the end of the line data for
// the compilation unit: a single compilation unit's line program
// may contain several "end of sequence" markers, to describe (for
// example) several discontiguous regions of code.
virtual void EndSequence(uint64 address);
private:
LineMap* linemap_;
@@ -185,4 +175,4 @@ class CUFunctionInfoHandler: public Dwarf2Handler {
};
} // namespace dwarf2reader
#endif // COMMON_DWARF_FUNCTIONINFO_H__
#endif // COMMON_MAC_DWARF_FUNCTIONINFO_H__

View File

@@ -27,8 +27,8 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef COMMON_DWARF_LINE_STATE_MACHINE_H__
#define COMMON_DWARF_LINE_STATE_MACHINE_H__
#ifndef COMMON_MAC_DWARF_LINE_STATE_MACHINE_H__
#define COMMON_MAC_DWARF_LINE_STATE_MACHINE_H__
namespace dwarf2reader {
@@ -58,4 +58,4 @@ struct LineStateMachine {
} // namespace dwarf2reader
#endif // COMMON_DWARF_LINE_STATE_MACHINE_H__
#endif // COMMON_MAC_DWARF_LINE_STATE_MACHINE_H__

View File

@@ -30,8 +30,8 @@
// This file contains some typedefs for basic types
#ifndef _COMMON_DWARF_TYPES_H__
#define _COMMON_DWARF_TYPES_H__
#ifndef _COMMON_MAC_DWARF_TYPES_H__
#define _COMMON_MAC_DWARF_TYPES_H__
typedef signed char int8;
typedef short int16;
@@ -43,4 +43,4 @@ typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned long long uint64;
#endif // _COMMON_DWARF_TYPES_H__
#endif // _COMMON_MAC_DWARF_TYPES_H__

View File

@@ -94,11 +94,8 @@ typedef enum {
/* EXCEPTION_PRIV_INSTRUCTION */
MD_EXCEPTION_CODE_WIN_STACK_OVERFLOW = 0xc00000fd,
/* EXCEPTION_STACK_OVERFLOW */
MD_EXCEPTION_CODE_WIN_POSSIBLE_DEADLOCK = 0xc0000194,
MD_EXCEPTION_CODE_WIN_POSSIBLE_DEADLOCK = 0xc0000194
/* EXCEPTION_POSSIBLE_DEADLOCK */
MD_EXCEPTION_CODE_WIN_UNHANDLED_CPP_EXCEPTION = 0xe06d7363
/* Per http://support.microsoft.com/kb/185294,
generated by Visual C++ compiler */
} MDExceptionCodeWin;

View File

@@ -33,14 +33,28 @@
#ifndef GOOGLE_BREAKPAD_PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_H__
#define GOOGLE_BREAKPAD_PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_H__
// TODO: Platforms that have no hash_map can use map, at the likely cost of
// performance.
#ifdef __SUNPRO_CC
#define BSLR_NO_HASH_MAP
#endif // __SUNPRO_CC
#ifdef BSLR_NO_HASH_MAP
#include <map>
#else // BSLR_NO_HASH_MAP
#include <ext/hash_map>
#endif // BSLR_NO_HASH_MAP
#include "google_breakpad/processor/source_line_resolver_interface.h"
namespace google_breakpad {
using std::string;
#ifdef BSLR_NO_HASH_MAP
using std::map;
#else // BSLR_NO_HASH_MAP
using __gnu_cxx::hash_map;
#endif // BSLR_NO_HASH_MAP
class BasicSourceLineResolver : public SourceLineResolverInterface {
public:
@@ -71,13 +85,23 @@ class BasicSourceLineResolver : public SourceLineResolverInterface {
struct Function;
struct PublicSymbol;
struct File;
#ifdef BSLR_NO_HASH_MAP
struct CompareString {
bool operator()(const string &s1, const string &s2) const;
};
#else // BSLR_NO_HASH_MAP
struct HashString {
size_t operator()(const string &s) const;
};
#endif // BSLR_NO_HASH_MAP
class Module;
// All of the modules we've loaded
#ifdef BSLR_NO_HASH_MAP
typedef map<string, Module*, CompareString> ModuleMap;
#else // BSLR_NO_HASH_MAP
typedef hash_map<string, Module*, HashString> ModuleMap;
#endif // BSLR_NO_HASH_MAP
ModuleMap *modules_;
// Disallow unwanted copy ctor and assignment operator

View File

@@ -51,6 +51,9 @@
using std::map;
using std::vector;
using std::make_pair;
#ifndef BSLR_NO_HASH_MAP
using __gnu_cxx::hash;
#endif // BSLR_NO_HASH_MAP
namespace google_breakpad {
@@ -122,7 +125,11 @@ class BasicSourceLineResolver::Module {
private:
friend class BasicSourceLineResolver;
#ifdef BSLR_NO_HASH_MAP
typedef map<int, string> FileMap;
#else // BSLR_NO_HASH_MAP
typedef hash_map<int, string> FileMap;
#endif // BSLR_NO_HASH_MAP
// The types for stack_info_. This is equivalent to MS DIA's
// StackFrameTypeEnum. Each identifies a different type of frame
@@ -695,9 +702,15 @@ bool BasicSourceLineResolver::Module::ParseStackInfo(char *stack_info_line) {
return true;
}
#ifdef BSLR_NO_HASH_MAP
bool BasicSourceLineResolver::CompareString::operator()(
const string &s1, const string &s2) const {
return strcmp(s1.c_str(), s2.c_str()) < 0;
}
#else // BSLR_NO_HASH_MAP
size_t BasicSourceLineResolver::HashString::operator()(const string &s) const {
return hash<const char*>()(s.c_str());
}
#endif // BSLR_NO_HASH_MAP
} // namespace google_breakpad

View File

@@ -28,7 +28,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cassert>
#include <cstdio>
#include "google_breakpad/processor/minidump_processor.h"
#include "google_breakpad/processor/call_stack.h"
@@ -754,9 +753,6 @@ string MinidumpProcessor::GetCrashReason(Minidump *dump, u_int64_t *address) {
case MD_EXCEPTION_CODE_WIN_POSSIBLE_DEADLOCK:
reason = "EXCEPTION_POSSIBLE_DEADLOCK";
break;
case MD_EXCEPTION_CODE_WIN_UNHANDLED_CPP_EXCEPTION:
reason = "Unhandled C++ Exception";
break;
default:
BPLOG(INFO) << "Unknown exception reason " << reason;
break;

View File

@@ -27,8 +27,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cstdio>
#include "processor/pathname_stripper.h"
#include "processor/logging.h"

View File

@@ -38,7 +38,6 @@
#define PROCESSOR_POSTFIX_EVALUATOR_INL_H__
#include <cstdio>
#include <sstream>
#include "processor/postfix_evaluator.h"

View File

@@ -16,40 +16,29 @@ BIN=dump_syms
all:$(BIN)
TOP = ../../../..
VPATH = $(TOP)/src/common/linux
VPATH += $(TOP)/src/common
VPATH += $(TOP)/src/common/dwarf
DUMP_OBJ = \
dump_symbols.o \
dump_syms.o \
dwarf2diehandler.o \
file_id.o \
guid_creator.o \
md5.o \
module.o \
stabs_reader.o \
$(NULL)
DUMP_OBJ=dump_symbols.o guid_creator.o dump_syms.o file_id.o md5.o \
stabs_reader.o module.o
dump_syms:$(DUMP_OBJ)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ $^
# From this directory:
dump_syms.o: dump_syms.cc
dump_symbols.o:../../../common/linux/dump_symbols.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $^
# From src/common/linux:
dump_symbols.o: dump_symbols.cc
stabs_reader.o: stabs_reader.cc
module.o: module.cc
guid_creator.o: guid_creator.cc
file_id.o: file_id.cc
stabs_reader.o:../../../common/linux/stabs_reader.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $^
# From src/common:
md5.o: md5.c
module.o:../../../common/linux/module.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $^
# From src/common/dwarf:
dwarf2diehandler.o: dwarf2diehandler.cc
guid_creator.o:../../../common/linux/guid_creator.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $^
file_id.o:../../../common/linux/file_id.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $^
md5.o:../../../common/md5.c
$(CC) $(CPPFLAGS) $(CXXFLAGS) -c $^
clean:
rm -f $(BIN) $(DUMP_OBJ)

View File

@@ -130,9 +130,9 @@
9BE650AF0B52FE3000611104 /* macho_id.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_id.h; path = ../../../common/mac/macho_id.h; sourceTree = SOURCE_ROOT; };
9BE650B00B52FE3000611104 /* macho_walker.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = macho_walker.cc; path = ../../../common/mac/macho_walker.cc; sourceTree = SOURCE_ROOT; };
9BE650B10B52FE3000611104 /* macho_walker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_walker.h; path = ../../../common/mac/macho_walker.h; sourceTree = SOURCE_ROOT; };
F9C7ECE20E8ABCA600E953AD /* bytereader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bytereader.cc; path = ../../../common/dwarf/bytereader.cc; sourceTree = SOURCE_ROOT; };
F9C7ECE30E8ABCA600E953AD /* dwarf2reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf2reader.cc; path = ../../../common/dwarf/dwarf2reader.cc; sourceTree = SOURCE_ROOT; };
F9C7ECE40E8ABCA600E953AD /* functioninfo.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = functioninfo.cc; path = ../../../common/dwarf/functioninfo.cc; sourceTree = SOURCE_ROOT; };
F9C7ECE20E8ABCA600E953AD /* bytereader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bytereader.cc; path = ../../../common/mac/dwarf/bytereader.cc; sourceTree = SOURCE_ROOT; };
F9C7ECE30E8ABCA600E953AD /* dwarf2reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf2reader.cc; path = ../../../common/mac/dwarf/dwarf2reader.cc; sourceTree = SOURCE_ROOT; };
F9C7ECE40E8ABCA600E953AD /* functioninfo.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = functioninfo.cc; path = ../../../common/mac/dwarf/functioninfo.cc; sourceTree = SOURCE_ROOT; };
FD6625C40CF4D438004AC844 /* stackwalker_amd64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker_amd64.cc; path = ../../../processor/stackwalker_amd64.cc; sourceTree = SOURCE_ROOT; };
FD6625C50CF4D438004AC844 /* stackwalker_amd64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stackwalker_amd64.h; path = ../../../processor/stackwalker_amd64.h; sourceTree = SOURCE_ROOT; };
FD8EDEAC0CADDAD400A5EDF1 /* stackwalker_sparc.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = stackwalker_sparc.cc; path = ../../../processor/stackwalker_sparc.cc; sourceTree = SOURCE_ROOT; };

View File

@@ -45,15 +45,15 @@
9BE650440B52F6D800611104 /* macho_id.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_id.h; path = ../../../common/mac/macho_id.h; sourceTree = SOURCE_ROOT; };
9BE650450B52F6D800611104 /* macho_walker.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = macho_walker.cc; path = ../../../common/mac/macho_walker.cc; sourceTree = SOURCE_ROOT; };
9BE650460B52F6D800611104 /* macho_walker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = macho_walker.h; path = ../../../common/mac/macho_walker.h; sourceTree = SOURCE_ROOT; };
F95B422B0E0E22D100DBDE83 /* bytereader-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "bytereader-inl.h"; path = "../../../common/dwarf/bytereader-inl.h"; sourceTree = SOURCE_ROOT; };
F95B422C0E0E22D100DBDE83 /* bytereader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bytereader.cc; path = ../../../common/dwarf/bytereader.cc; sourceTree = SOURCE_ROOT; };
F95B422D0E0E22D100DBDE83 /* bytereader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bytereader.h; path = ../../../common/dwarf/bytereader.h; sourceTree = SOURCE_ROOT; };
F95B422E0E0E22D100DBDE83 /* dwarf2enums.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf2enums.h; path = ../../../common/dwarf/dwarf2enums.h; sourceTree = SOURCE_ROOT; };
F95B422F0E0E22D100DBDE83 /* dwarf2reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf2reader.cc; path = ../../../common/dwarf/dwarf2reader.cc; sourceTree = SOURCE_ROOT; };
F95B42300E0E22D100DBDE83 /* dwarf2reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf2reader.h; path = ../../../common/dwarf/dwarf2reader.h; sourceTree = SOURCE_ROOT; };
F95B42310E0E22D100DBDE83 /* line_state_machine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = line_state_machine.h; path = ../../../common/dwarf/line_state_machine.h; sourceTree = SOURCE_ROOT; };
F9C7ED420E8AD93000E953AD /* functioninfo.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = functioninfo.cc; path = ../../../common/dwarf/functioninfo.cc; sourceTree = SOURCE_ROOT; };
F9F5344D0E7C902C0012363F /* functioninfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = functioninfo.h; path = ../../../common/dwarf/functioninfo.h; sourceTree = SOURCE_ROOT; };
F95B422B0E0E22D100DBDE83 /* bytereader-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "bytereader-inl.h"; path = "../../../common/mac/dwarf/bytereader-inl.h"; sourceTree = SOURCE_ROOT; };
F95B422C0E0E22D100DBDE83 /* bytereader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bytereader.cc; path = ../../../common/mac/dwarf/bytereader.cc; sourceTree = SOURCE_ROOT; };
F95B422D0E0E22D100DBDE83 /* bytereader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bytereader.h; path = ../../../common/mac/dwarf/bytereader.h; sourceTree = SOURCE_ROOT; };
F95B422E0E0E22D100DBDE83 /* dwarf2enums.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf2enums.h; path = ../../../common/mac/dwarf/dwarf2enums.h; sourceTree = SOURCE_ROOT; };
F95B422F0E0E22D100DBDE83 /* dwarf2reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dwarf2reader.cc; path = ../../../common/mac/dwarf/dwarf2reader.cc; sourceTree = SOURCE_ROOT; };
F95B42300E0E22D100DBDE83 /* dwarf2reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf2reader.h; path = ../../../common/mac/dwarf/dwarf2reader.h; sourceTree = SOURCE_ROOT; };
F95B42310E0E22D100DBDE83 /* line_state_machine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = line_state_machine.h; path = ../../../common/mac/dwarf/line_state_machine.h; sourceTree = SOURCE_ROOT; };
F9C7ED420E8AD93000E953AD /* functioninfo.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = functioninfo.cc; path = ../../../common/mac/dwarf/functioninfo.cc; sourceTree = SOURCE_ROOT; };
F9F5344D0E7C902C0012363F /* functioninfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = functioninfo.h; path = ../../../common/mac/dwarf/functioninfo.h; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */