зеркало из https://github.com/mozilla/pjs.git
bug 386632 - update to breakpad revision 195. r=mento
This commit is contained in:
Родитель
189a8e2a26
Коммит
5b98caf4af
|
@ -29,7 +29,6 @@
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <asm/sigcontext.h>
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <asm/sigcontext.h>
|
#include <signal.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
|
@ -158,8 +158,9 @@ class DynamicImage {
|
||||||
// Makes local copy of file path to mach-o binary
|
// Makes local copy of file path to mach-o binary
|
||||||
void InitializeFilePath(char *inFilePath) {
|
void InitializeFilePath(char *inFilePath) {
|
||||||
if (inFilePath) {
|
if (inFilePath) {
|
||||||
file_path_ = reinterpret_cast<char*>(malloc(strlen(inFilePath)));
|
size_t path_size = 1 + strlen(inFilePath);
|
||||||
strcpy(file_path_, inFilePath);
|
file_path_ = reinterpret_cast<char*>(malloc(path_size));
|
||||||
|
strlcpy(file_path_, inFilePath, path_size);
|
||||||
} else {
|
} else {
|
||||||
file_path_ = NULL;
|
file_path_ = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ ExceptionHandler::ExceptionHandler(const wstring &dump_path,
|
||||||
FilterCallback filter,
|
FilterCallback filter,
|
||||||
MinidumpCallback callback,
|
MinidumpCallback callback,
|
||||||
void *callback_context,
|
void *callback_context,
|
||||||
bool install_handler)
|
int handler_types)
|
||||||
: filter_(filter),
|
: filter_(filter),
|
||||||
callback_(callback),
|
callback_(callback),
|
||||||
callback_context_(callback_context),
|
callback_context_(callback_context),
|
||||||
|
@ -62,7 +62,7 @@ ExceptionHandler::ExceptionHandler(const wstring &dump_path,
|
||||||
next_minidump_path_c_(NULL),
|
next_minidump_path_c_(NULL),
|
||||||
dbghelp_module_(NULL),
|
dbghelp_module_(NULL),
|
||||||
minidump_write_dump_(NULL),
|
minidump_write_dump_(NULL),
|
||||||
installed_handler_(install_handler),
|
handler_types_(handler_types),
|
||||||
previous_filter_(NULL),
|
previous_filter_(NULL),
|
||||||
previous_pch_(NULL),
|
previous_pch_(NULL),
|
||||||
handler_thread_(0),
|
handler_thread_(0),
|
||||||
|
@ -82,11 +82,10 @@ ExceptionHandler::ExceptionHandler(const wstring &dump_path,
|
||||||
set_dump_path(dump_path);
|
set_dump_path(dump_path);
|
||||||
|
|
||||||
// Set synchronization primitives and the handler thread. Each
|
// Set synchronization primitives and the handler thread. Each
|
||||||
// ExceptionHandler object gets its own handler thread, even if
|
// ExceptionHandler object gets its own handler thread because that's the
|
||||||
// install_handler is false, because that's the only way to reliably
|
// only way to reliably guarantee sufficient stack space in an exception,
|
||||||
// guarantee sufficient stack space in an exception, and the only way to
|
// and it allows an easy way to get a snapshot of the requesting thread's
|
||||||
// get a snapshot of the requesting thread's context outside of an
|
// context outside of an exception.
|
||||||
// exception.
|
|
||||||
InitializeCriticalSection(&handler_critical_section_);
|
InitializeCriticalSection(&handler_critical_section_);
|
||||||
handler_start_semaphore_ = CreateSemaphore(NULL, 0, 1, NULL);
|
handler_start_semaphore_ = CreateSemaphore(NULL, 0, 1, NULL);
|
||||||
handler_finish_semaphore_ = CreateSemaphore(NULL, 0, 1, NULL);
|
handler_finish_semaphore_ = CreateSemaphore(NULL, 0, 1, NULL);
|
||||||
|
@ -105,7 +104,7 @@ ExceptionHandler::ExceptionHandler(const wstring &dump_path,
|
||||||
GetProcAddress(dbghelp_module_, "MiniDumpWriteDump"));
|
GetProcAddress(dbghelp_module_, "MiniDumpWriteDump"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (install_handler) {
|
if (handler_types != HANDLER_NONE) {
|
||||||
if (!handler_stack_critical_section_initialized_) {
|
if (!handler_stack_critical_section_initialized_) {
|
||||||
InitializeCriticalSection(&handler_stack_critical_section_);
|
InitializeCriticalSection(&handler_stack_critical_section_);
|
||||||
handler_stack_critical_section_initialized_ = true;
|
handler_stack_critical_section_initialized_ = true;
|
||||||
|
@ -119,13 +118,17 @@ ExceptionHandler::ExceptionHandler(const wstring &dump_path,
|
||||||
handler_stack_ = new vector<ExceptionHandler *>();
|
handler_stack_ = new vector<ExceptionHandler *>();
|
||||||
}
|
}
|
||||||
handler_stack_->push_back(this);
|
handler_stack_->push_back(this);
|
||||||
previous_filter_ = SetUnhandledExceptionFilter(HandleException);
|
|
||||||
|
if (handler_types & HANDLER_EXCEPTION)
|
||||||
|
previous_filter_ = SetUnhandledExceptionFilter(HandleException);
|
||||||
|
|
||||||
#if _MSC_VER >= 1400 // MSVC 2005/8
|
#if _MSC_VER >= 1400 // MSVC 2005/8
|
||||||
previous_iph_ = _set_invalid_parameter_handler(HandleInvalidParameter);
|
if (handler_types & HANDLER_INVALID_PARAMETER)
|
||||||
|
previous_iph_ = _set_invalid_parameter_handler(HandleInvalidParameter);
|
||||||
#endif // _MSC_VER >= 1400
|
#endif // _MSC_VER >= 1400
|
||||||
|
|
||||||
previous_pch_ = _set_purecall_handler(HandlePureVirtualCall);
|
if (handler_types & HANDLER_PURECALL)
|
||||||
|
previous_pch_ = _set_purecall_handler(HandlePureVirtualCall);
|
||||||
|
|
||||||
LeaveCriticalSection(&handler_stack_critical_section_);
|
LeaveCriticalSection(&handler_stack_critical_section_);
|
||||||
}
|
}
|
||||||
|
@ -136,16 +139,19 @@ ExceptionHandler::~ExceptionHandler() {
|
||||||
FreeLibrary(dbghelp_module_);
|
FreeLibrary(dbghelp_module_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (installed_handler_) {
|
if (handler_types_ != HANDLER_NONE) {
|
||||||
EnterCriticalSection(&handler_stack_critical_section_);
|
EnterCriticalSection(&handler_stack_critical_section_);
|
||||||
|
|
||||||
SetUnhandledExceptionFilter(previous_filter_);
|
if (handler_types_ & HANDLER_EXCEPTION)
|
||||||
|
SetUnhandledExceptionFilter(previous_filter_);
|
||||||
|
|
||||||
#if _MSC_VER >= 1400 // MSVC 2005/8
|
#if _MSC_VER >= 1400 // MSVC 2005/8
|
||||||
_set_invalid_parameter_handler(previous_iph_);
|
if (handler_types_ & HANDLER_INVALID_PARAMETER)
|
||||||
|
_set_invalid_parameter_handler(previous_iph_);
|
||||||
#endif // _MSC_VER >= 1400
|
#endif // _MSC_VER >= 1400
|
||||||
|
|
||||||
_set_purecall_handler(previous_pch_);
|
if (handler_types_ & HANDLER_PURECALL)
|
||||||
|
_set_purecall_handler(previous_pch_);
|
||||||
|
|
||||||
if (handler_stack_->back() == this) {
|
if (handler_stack_->back() == this) {
|
||||||
handler_stack_->pop_back();
|
handler_stack_->pop_back();
|
||||||
|
@ -410,7 +416,11 @@ bool ExceptionHandler::WriteMinidumpOnHandlerThread(
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ExceptionHandler::WriteMinidump() {
|
bool ExceptionHandler::WriteMinidump() {
|
||||||
bool success = WriteMinidumpOnHandlerThread(NULL, NULL);
|
return WriteMinidumpForException(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ExceptionHandler::WriteMinidumpForException(EXCEPTION_POINTERS *exinfo) {
|
||||||
|
bool success = WriteMinidumpOnHandlerThread(exinfo, NULL);
|
||||||
UpdateNextID();
|
UpdateNextID();
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
@ -419,7 +429,8 @@ bool ExceptionHandler::WriteMinidump() {
|
||||||
bool ExceptionHandler::WriteMinidump(const wstring &dump_path,
|
bool ExceptionHandler::WriteMinidump(const wstring &dump_path,
|
||||||
MinidumpCallback callback,
|
MinidumpCallback callback,
|
||||||
void *callback_context) {
|
void *callback_context) {
|
||||||
ExceptionHandler handler(dump_path, NULL, callback, callback_context, false);
|
ExceptionHandler handler(dump_path, NULL, callback, callback_context,
|
||||||
|
HANDLER_NONE);
|
||||||
return handler.WriteMinidump();
|
return handler.WriteMinidump();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,17 +119,33 @@ class ExceptionHandler {
|
||||||
MDRawAssertionInfo *assertion,
|
MDRawAssertionInfo *assertion,
|
||||||
bool succeeded);
|
bool succeeded);
|
||||||
|
|
||||||
|
// HandlerType specifies which types of handlers should be installed, if
|
||||||
|
// any. Use HANDLER_NONE for an ExceptionHandler that remains idle,
|
||||||
|
// without catching any failures on its own. This type of handler may
|
||||||
|
// still be triggered by calling WriteMinidump. Otherwise, use a
|
||||||
|
// combination of the other HANDLER_ values, or HANDLER_ALL to install
|
||||||
|
// all handlers.
|
||||||
|
enum HandlerType {
|
||||||
|
HANDLER_NONE = 0,
|
||||||
|
HANDLER_EXCEPTION = 1 << 0, // SetUnhandledExceptionFilter
|
||||||
|
HANDLER_INVALID_PARAMETER = 1 << 1, // _set_invalid_parameter_handler
|
||||||
|
HANDLER_PURECALL = 1 << 2, // _set_purecall_handler
|
||||||
|
HANDLER_ALL = HANDLER_EXCEPTION |
|
||||||
|
HANDLER_INVALID_PARAMETER |
|
||||||
|
HANDLER_PURECALL
|
||||||
|
};
|
||||||
|
|
||||||
// Creates a new ExceptionHandler instance to handle writing minidumps.
|
// Creates a new ExceptionHandler instance to handle writing minidumps.
|
||||||
// Before writing a minidump, the optional filter callback will be called.
|
// Before writing a minidump, the optional filter callback will be called.
|
||||||
// Its return value determines whether or not Breakpad should write a minidump.
|
// Its return value determines whether or not Breakpad should write a
|
||||||
// Minidump files will be written to dump_path, and the optional callback
|
// minidump. Minidump files will be written to dump_path, and the optional
|
||||||
// is called after writing the dump file, as described above.
|
// callback is called after writing the dump file, as described above.
|
||||||
// If install_handler is true, then a minidump will be written whenever
|
// handler_types specifies the types of handlers that should be installed.
|
||||||
// an unhandled exception occurs. If it is false, minidumps will only
|
|
||||||
// be written when WriteMinidump is called.
|
|
||||||
ExceptionHandler(const wstring &dump_path,
|
ExceptionHandler(const wstring &dump_path,
|
||||||
FilterCallback filter, MinidumpCallback callback,
|
FilterCallback filter,
|
||||||
void *callback_context, bool install_handler);
|
MinidumpCallback callback,
|
||||||
|
void *callback_context,
|
||||||
|
int handler_types);
|
||||||
~ExceptionHandler();
|
~ExceptionHandler();
|
||||||
|
|
||||||
// Get and set the minidump path.
|
// Get and set the minidump path.
|
||||||
|
@ -144,6 +160,10 @@ class ExceptionHandler {
|
||||||
// execution state independently of a crash. Returns true on success.
|
// execution state independently of a crash. Returns true on success.
|
||||||
bool WriteMinidump();
|
bool WriteMinidump();
|
||||||
|
|
||||||
|
// Writes a minidump immediately, with the user-supplied exception
|
||||||
|
// information.
|
||||||
|
bool WriteMinidumpForException(EXCEPTION_POINTERS *exinfo);
|
||||||
|
|
||||||
// Convenience form of WriteMinidump which does not require an
|
// Convenience form of WriteMinidump which does not require an
|
||||||
// ExceptionHandler instance.
|
// ExceptionHandler instance.
|
||||||
static bool WriteMinidump(const wstring &dump_path,
|
static bool WriteMinidump(const wstring &dump_path,
|
||||||
|
@ -240,9 +260,9 @@ class ExceptionHandler {
|
||||||
HMODULE dbghelp_module_;
|
HMODULE dbghelp_module_;
|
||||||
MiniDumpWriteDump_type minidump_write_dump_;
|
MiniDumpWriteDump_type minidump_write_dump_;
|
||||||
|
|
||||||
// True if the ExceptionHandler installed an unhandled exception filter
|
// Tracks the handler types that were installed according to the
|
||||||
// when created (with an install_handler parameter set to true).
|
// handler_types constructor argument.
|
||||||
bool installed_handler_;
|
int handler_types_;
|
||||||
|
|
||||||
// When installed_handler_ is true, previous_filter_ is the unhandled
|
// When installed_handler_ is true, previous_filter_ is the unhandled
|
||||||
// exception filter that was set prior to installing ExceptionHandler as
|
// exception filter that was set prior to installing ExceptionHandler as
|
||||||
|
|
|
@ -223,7 +223,8 @@ int LoadLineInfo(struct nlist *list,
|
||||||
struct LineInfo line;
|
struct LineInfo line;
|
||||||
while (cur_list < list_end && cur_list->n_type == N_SLINE) {
|
while (cur_list < list_end && cur_list->n_type == N_SLINE) {
|
||||||
line.rva_to_func = cur_list->n_value;
|
line.rva_to_func = cur_list->n_value;
|
||||||
line.line_num = cur_list->n_desc;
|
// n_desc is a signed short
|
||||||
|
line.line_num = (unsigned short)cur_list->n_desc;
|
||||||
func_info->line_info.push_back(line);
|
func_info->line_info.push_back(line);
|
||||||
++cur_list;
|
++cur_list;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,9 @@ static void CrashFunction() {
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
google_breakpad::ExceptionHandler eh(L".", NULL, callback, NULL, true);
|
google_breakpad::ExceptionHandler eh(
|
||||||
|
L".", NULL, callback, NULL,
|
||||||
|
google_breakpad::ExceptionHandler::HANDLER_ALL);
|
||||||
CrashFunction();
|
CrashFunction();
|
||||||
printf("did not crash?\n");
|
printf("did not crash?\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче