Bug 886216 - Add missing breakpad patches. r=ted

--HG--
rename : toolkit/crashreporter/breakpad-patches/12-sht-arm-exidx-define.patch => toolkit/crashreporter/breakpad-patches/16-sht-arm-exidx-define.patch
This commit is contained in:
Mike Hommey 2013-07-31 14:03:21 +09:00
Родитель 3d33d515ba
Коммит 622c6ed12a
6 изменённых файлов: 1785 добавлений и 6 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,38 @@
# HG changeset patch
# User Georg Fritzsche <georg.fritzsche@googlemail.com>
# Date 1366630152 -7200
# Mon Apr 22 13:29:12 2013 +0200
# Node ID 11f7a9321b7d5d85eddc2db16e58e6870a7c4e06
# Parent e74de3db7dd27ffda8f4772f892cfb52c5c35649
Bug 836829 - Fix missing result check in Mac exception handler. r=ted
diff --git a/src/client/mac/handler/exception_handler.cc b/src/client/mac/handler/exception_handler.cc
--- a/src/client/mac/handler/exception_handler.cc
+++ b/src/client/mac/handler/exception_handler.cc
@@ -276,19 +276,23 @@ bool ExceptionHandler::WriteMinidump(boo
use_minidump_write_mutex_ = true;
last_minidump_write_result_ = false;
// Lock the mutex. Since we just created it, this will return immediately.
if (pthread_mutex_lock(&minidump_write_mutex_) == 0) {
// Send an empty message to the handle port so that a minidump will
// be written
- SendMessageToHandlerThread(write_exception_stream ?
- kWriteDumpWithExceptionMessage :
- kWriteDumpMessage);
+ bool result = SendMessageToHandlerThread(write_exception_stream ?
+ kWriteDumpWithExceptionMessage :
+ kWriteDumpMessage);
+ if (!result) {
+ pthread_mutex_unlock(&minidump_write_mutex_);
+ return false;
+ }
// Wait for the minidump writer to complete its writing. It will unlock
// the mutex when completed
pthread_mutex_lock(&minidump_write_mutex_);
}
use_minidump_write_mutex_ = false;
UpdateNextID();

Просмотреть файл

@ -0,0 +1,346 @@
# HG changeset patch
# User Julian Seward <jseward@acm.org>
# Date 1372168568 -7200
# Tue Jun 25 15:56:08 2013 +0200
# Node ID 6d06a09b3f5624dd833bd6f905bfd88e3fdec00a
# Parent 11f7a9321b7d5d85eddc2db16e58e6870a7c4e06
Bug 883126 - Improve performance of EXIDX unwinding in Breakpad. r=ted
diff --git a/src/common/arm_ex_to_module.cc b/src/common/arm_ex_to_module.cc
--- a/src/common/arm_ex_to_module.cc
+++ b/src/common/arm_ex_to_module.cc
@@ -66,141 +66,126 @@ WITH THE SOFTWARE OR THE USE OR OTHER DE
#define ARM_EXBUF_START(x) (((x) >> 4) & 0x0f)
#define ARM_EXBUF_COUNT(x) ((x) & 0x0f)
#define ARM_EXBUF_END(x) (ARM_EXBUF_START(x) + ARM_EXBUF_COUNT(x))
using google_breakpad::ustr__pc;
using google_breakpad::ustr__lr;
using google_breakpad::ustr__sp;
+using google_breakpad::ustr__ZDra;
+using google_breakpad::ustr__ZDcfa;
using google_breakpad::Module;
using google_breakpad::ToUniqueString;
using google_breakpad::UniqueString;
namespace arm_ex_to_module {
// Translate command from extab_data to command for Module.
int ARMExToModule::TranslateCmd(const struct extab_data* edata,
- Module::StackFrameEntry* entry, string& vsp) {
+ Module::StackFrameEntry* entry,
+ Module::Expr& vsp) {
int ret = 0;
switch (edata->cmd) {
case ARM_EXIDX_CMD_FINISH:
/* Copy LR to PC if there isn't currently a rule for PC in force. */
if (entry->initial_rules.find(ustr__pc())
== entry->initial_rules.end()) {
if (entry->initial_rules.find(ustr__lr())
== entry->initial_rules.end()) {
- entry->initial_rules[ustr__pc()] = Module::Expr("lr");
+ entry->initial_rules[ustr__pc()] = Module::Expr(ustr__lr(),
+ 0, false); // "lr"
} else {
entry->initial_rules[ustr__pc()] = entry->initial_rules[ustr__lr()];
}
}
break;
case ARM_EXIDX_CMD_SUB_FROM_VSP:
- {
- char c[16];
- sprintf(c, " %d -", edata->data);
- vsp += c;
- }
+ vsp = vsp.add_delta(- static_cast<long>(edata->data));
break;
case ARM_EXIDX_CMD_ADD_TO_VSP:
- {
- char c[16];
- sprintf(c, " %d +", edata->data);
- vsp += c;
- }
+ vsp = vsp.add_delta(static_cast<long>(edata->data));
break;
case ARM_EXIDX_CMD_REG_POP:
for (unsigned int i = 0; i < 16; i++) {
if (edata->data & (1 << i)) {
- entry->initial_rules[ToUniqueString(regnames[i])]
- = Module::Expr(vsp + " ^");
- vsp += " 4 +";
+ entry->initial_rules[ToUniqueString(regnames[i])] = vsp.deref();
+ vsp = vsp.add_delta(4);
}
}
/* Set cfa in case the SP got popped. */
if (edata->data & (1 << 13)) {
- Module::Expr& vsp_expr = entry->initial_rules[ustr__sp()];
- // It must be a postfix expression (we don't generate anything
- // else here), so return -1 to fail out if it isn't.
- if (!vsp_expr.isExprPostfix()) {
- ret = -1;
- break;
- };
- vsp = vsp_expr.getExprPostfix();
+ vsp = entry->initial_rules[ustr__sp()];
}
break;
case ARM_EXIDX_CMD_REG_TO_SP: {
assert (edata->data < 16);
const char* const regname = regnames[edata->data];
const UniqueString* regname_us = ToUniqueString(regname);
if (entry->initial_rules.find(regname_us) == entry->initial_rules.end()) {
- entry->initial_rules[ustr__sp()] = Module::Expr(regname);
+ entry->initial_rules[ustr__sp()] = Module::Expr(regname_us,
+ 0, false); // "regname"
} else {
entry->initial_rules[ustr__sp()] = entry->initial_rules[regname_us];
}
- Module::Expr& vsp_expr = entry->initial_rules[ustr__sp()];
- if (!vsp_expr.isExprPostfix()) {
- ret = -1;
- break;
- };
- vsp = vsp_expr.getExprPostfix();
+ vsp = entry->initial_rules[ustr__sp()];
break;
}
case ARM_EXIDX_CMD_VFP_POP:
/* Don't recover VFP registers, but be sure to adjust the stack
pointer. */
for (unsigned int i = ARM_EXBUF_START(edata->data);
i <= ARM_EXBUF_END(edata->data); i++) {
- vsp += " 8 +";
+ vsp = vsp.add_delta(8);
}
if (!(edata->data & ARM_EXIDX_VFP_FSTMD)) {
- vsp += " 4 +";
+ vsp = vsp.add_delta(4);
}
break;
case ARM_EXIDX_CMD_WREG_POP:
for (unsigned int i = ARM_EXBUF_START(edata->data);
i <= ARM_EXBUF_END(edata->data); i++) {
- vsp += " 8 +";
+ vsp = vsp.add_delta(8);
}
break;
case ARM_EXIDX_CMD_WCGR_POP:
// Pop wCGR registers under mask {wCGR3,2,1,0}, hence "i < 4"
for (unsigned int i = 0; i < 4; i++) {
if (edata->data & (1 << i)) {
- vsp += " 4 +";
+ vsp = vsp.add_delta(4);
}
}
break;
case ARM_EXIDX_CMD_REFUSED:
case ARM_EXIDX_CMD_RESERVED:
ret = -1;
break;
}
return ret;
}
void ARMExToModule::AddStackFrame(uintptr_t addr, size_t size) {
stack_frame_entry_ = new Module::StackFrameEntry;
stack_frame_entry_->address = addr;
stack_frame_entry_->size = size;
- stack_frame_entry_->initial_rules[ToUniqueString(kCFA)] = Module::Expr("sp");
- vsp_ = "sp";
+ Module::Expr sp_expr = Module::Expr(ustr__sp(), 0, false); // "sp"
+ stack_frame_entry_->initial_rules[ustr__ZDcfa()] = sp_expr; // ".cfa"
+ vsp_ = sp_expr;
}
int ARMExToModule::ImproveStackFrame(const struct extab_data* edata) {
return TranslateCmd(edata, stack_frame_entry_, vsp_) ;
}
void ARMExToModule::DeleteStackFrame() {
delete stack_frame_entry_;
}
void ARMExToModule::SubmitStackFrame() {
// return address always winds up in pc
- stack_frame_entry_->initial_rules[ToUniqueString(kRA)]
+ stack_frame_entry_->initial_rules[ustr__ZDra()] // ".ra"
= stack_frame_entry_->initial_rules[ustr__pc()];
// the final value of vsp is the new value of sp
stack_frame_entry_->initial_rules[ustr__sp()] = vsp_;
module_->AddStackFrameEntry(stack_frame_entry_);
}
} // namespace arm_ex_to_module
diff --git a/src/common/arm_ex_to_module.h b/src/common/arm_ex_to_module.h
--- a/src/common/arm_ex_to_module.h
+++ b/src/common/arm_ex_to_module.h
@@ -89,19 +89,16 @@ struct extab_data {
uint32_t data;
};
enum extab_cmd_flags {
ARM_EXIDX_VFP_SHIFT_16 = 1 << 16,
ARM_EXIDX_VFP_FSTMD = 1 << 17, // distinguishes FSTMxxD from FSTMxxX
};
-const string kRA = ".ra";
-const string kCFA = ".cfa";
-
static const char* const regnames[] = {
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
"fps", "cpsr"
};
// Receives information from arm_ex_reader::ExceptionTableInfo
@@ -113,17 +110,17 @@ class ARMExToModule {
~ARMExToModule() { }
void AddStackFrame(uintptr_t addr, size_t size);
int ImproveStackFrame(const struct extab_data* edata);
void DeleteStackFrame();
void SubmitStackFrame();
private:
Module* module_;
Module::StackFrameEntry* stack_frame_entry_;
- string vsp_;
+ Module::Expr vsp_;
int TranslateCmd(const struct extab_data* edata,
Module::StackFrameEntry* entry,
- string& vsp);
+ Module::Expr& vsp);
};
} // namespace arm_ex_to_module
#endif // COMMON_ARM_EX_TO_MODULE__
diff --git a/src/common/module.h b/src/common/module.h
--- a/src/common/module.h
+++ b/src/common/module.h
@@ -39,16 +39,20 @@
#define COMMON_LINUX_MODULE_H__
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
#include "common/symbol_data.h"
#include "common/using_std_string.h"
#include "common/unique_string.h"
#include "google_breakpad/common/breakpad_types.h"
namespace google_breakpad {
using std::set;
@@ -161,30 +165,98 @@ class Module {
// Construct an invalid expression
Expr() {
postfix_ = "";
ident_ = NULL;
offset_ = 0;
how_ = kExprInvalid;
}
bool isExprInvalid() const { return how_ == kExprInvalid; }
- bool isExprPostfix() const { return how_ == kExprPostfix; }
- // Return the postfix expression string. This is only
- // meaningful on Exprs for which isExprPostfix returns true.
- // In all other cases it returns an empty string.
- string getExprPostfix() const { return postfix_; }
+ // Return the postfix expression string, either directly,
+ // if this is a postfix expression, or by synthesising it
+ // for a simple expression.
+ string getExprPostfix() const {
+ switch (how_) {
+ case kExprPostfix:
+ return postfix_;
+ case kExprSimple:
+ case kExprSimpleMem: {
+ char buf[40];
+ sprintf(buf, " %ld %c%s", labs(offset_), offset_ < 0 ? '-' : '+',
+ how_ == kExprSimple ? "" : " ^");
+ return string(FromUniqueString(ident_)) + string(buf);
+ }
+ case kExprInvalid:
+ default:
+ assert(0 && "getExprPostfix: invalid Module::Expr type");
+ return "Expr::genExprPostfix: kExprInvalid";
+ }
+ }
bool operator==(const Expr& other) const {
return how_ == other.how_ &&
ident_ == other.ident_ &&
offset_ == other.offset_ &&
postfix_ == other.postfix_;
}
+ // Returns an Expr which evaluates to |this| + |delta|
+ Expr add_delta(long delta) {
+ if (delta == 0) {
+ return *this;
+ }
+ // If it's a simple form expression of the form "identifier + offset",
+ // simply add |delta| on to |offset|. In the other two possible
+ // cases:
+ // *(identifier + offset)
+ // completely arbitrary postfix expression string
+ // the only option is to "downgrade" it to a postfix expression and add
+ // "+/- delta" at the end of the string, since the result can't be
+ // represented in the simple form.
+ switch (how_) {
+ case kExprSimpleMem:
+ case kExprPostfix: {
+ char buf[40];
+ sprintf(buf, " %ld %c", labs(delta), delta < 0 ? '-' : '+');
+ return Expr(getExprPostfix() + string(buf));
+ }
+ case kExprSimple:
+ return Expr(ident_, offset_ + delta, false);
+ case kExprInvalid:
+ default:
+ assert(0 && "add_delta: invalid Module::Expr type");
+ // Invalid inputs produce an invalid result
+ return Expr();
+ }
+ }
+
+ // Returns an Expr which evaluates to *|this|
+ Expr deref() {
+ // In the simplest case, a kExprSimple can be changed into a
+ // kExprSimpleMem. In all other cases it has to be dumped as a
+ // postfix string, and " ^" added at the end.
+ switch (how_) {
+ case kExprSimple: {
+ Expr t = *this;
+ t.how_ = kExprSimpleMem;
+ return t;
+ }
+ case kExprSimpleMem:
+ case kExprPostfix: {
+ return Expr(getExprPostfix() + " ^");
+ }
+ case kExprInvalid:
+ default:
+ assert(0 && "deref: invalid Module::Expr type");
+ // Invalid inputs produce an invalid result
+ return Expr();
+ }
+ }
+
// The identifier that gives the starting value for simple expressions.
const UniqueString* ident_;
// The offset to add for simple expressions.
long offset_;
// The Postfix expression string to evaluate for non-simple expressions.
string postfix_;
// The operation expressed by this expression.
ExprHow how_;

Просмотреть файл

@ -0,0 +1,96 @@
# HG changeset patch
# User Julian Seward <jseward@acm.org>
# Date 1366643454 -7200
# Mon Apr 22 17:10:54 2013 +0200
# Node ID 3e64f12d9dab619c90bee02ed071bcda0100844e
# Parent 6d06a09b3f5624dd833bd6f905bfd88e3fdec00a
Bug 859745 - Install sane unwinding limit for SPS/breakpad. r=ted
diff --git a/src/google_breakpad/processor/stackwalker.h b/src/google_breakpad/processor/stackwalker.h
--- a/src/google_breakpad/processor/stackwalker.h
+++ b/src/google_breakpad/processor/stackwalker.h
@@ -83,17 +83,20 @@ class Stackwalker {
// argument. If no suitable concrete subclass exists, returns NULL.
static Stackwalker* StackwalkerForCPU(
const SystemInfo* system_info,
MinidumpContext* context,
MemoryRegion* memory,
const CodeModules* modules,
StackFrameSymbolizer* resolver_helper);
- static void set_max_frames(uint32_t max_frames) { max_frames_ = max_frames; }
+ static void set_max_frames(uint32_t max_frames) {
+ max_frames_ = max_frames;
+ max_frames_set_ = true;
+ }
static uint32_t max_frames() { return max_frames_; }
protected:
// system_info identifies the operating system, NULL or empty if unknown.
// memory identifies a MemoryRegion that provides the stack memory
// for the stack to walk. modules, if non-NULL, is a CodeModules
// object that is used to look up which code module each stack frame is
// associated with. frame_symbolizer is a StackFrameSymbolizer object that
@@ -191,14 +194,19 @@ class Stackwalker {
// the end of the stack has been reached). GetCallerFrame allocates a new
// StackFrame (or StackFrame subclass), ownership of which is taken by
// the caller.
virtual StackFrame* GetCallerFrame(const CallStack* stack) = 0;
// The maximum number of frames Stackwalker will walk through.
// This defaults to 1024 to prevent infinite loops.
static uint32_t max_frames_;
+
+ // Keep track of whether max_frames_ has been set by the user, since
+ // it affects whether or not an error message is printed in the case
+ // where an unwind got stopped by the limit.
+ static bool max_frames_set_;
};
} // namespace google_breakpad
#endif // GOOGLE_BREAKPAD_PROCESSOR_STACKWALKER_H__
diff --git a/src/processor/stackwalker.cc b/src/processor/stackwalker.cc
--- a/src/processor/stackwalker.cc
+++ b/src/processor/stackwalker.cc
@@ -52,16 +52,17 @@
#include "processor/stackwalker_x86.h"
#include "processor/stackwalker_amd64.h"
#include "processor/stackwalker_arm.h"
namespace google_breakpad {
const int Stackwalker::kRASearchWords = 30;
uint32_t Stackwalker::max_frames_ = 1024;
+bool Stackwalker::max_frames_set_ = false;
Stackwalker::Stackwalker(const SystemInfo* system_info,
MemoryRegion* memory,
const CodeModules* modules,
StackFrameSymbolizer* frame_symbolizer)
: system_info_(system_info),
memory_(memory),
modules_(modules),
@@ -120,17 +121,20 @@ bool Stackwalker::Walk(CallStack* stack,
modules_without_symbols->push_back(frame->module);
}
}
// 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());
if (stack->frames_.size() > max_frames_) {
- BPLOG(ERROR) << "The stack is over " << max_frames_ << " frames.";
+ // Only emit an error message in the case where the limit that we
+ // reached is the default limit, not set by the user.
+ if (!max_frames_set_)
+ BPLOG(ERROR) << "The stack is over " << max_frames_ << " frames.";
break;
}
// Get the next frame and take ownership.
frame.reset(GetCallerFrame(stack));
}
return true;

Просмотреть файл

@ -433,8 +433,6 @@ src_tools_linux_dump_syms_dump_syms_SOURCES = \
src/common/dwarf/bytereader.cc \
src/common/dwarf/dwarf2diehandler.cc \
src/common/dwarf/dwarf2reader.cc \
src/common/arm_ex_reader.cc \
src/common/arm_ex_to_module.cc \
src/common/linux/dump_symbols.cc \
src/common/linux/elf_symbols_to_module.cc \
src/common/linux/elfutils.cc \
@ -1017,10 +1015,6 @@ EXTRA_DIST = \
src/common/convert_UTF.h \
src/common/linux/dump_symbols.cc \
src/common/linux/dump_symbols.h \
src/common/arm_ex_reader.cc \
src/common/arm_ex_reader.h \
src/common/arm_ex_to_module.cc \
src/common/arm_ex_to_module.h \
src/common/linux/elf_symbols_to_module.cc \
src/common/linux/elf_symbols_to_module.h \
src/common/linux/elfutils.cc \