bug 386632 - update to breakpad revision 195. r=mento

This commit is contained in:
ted.mielczarek@gmail.com 2007-07-09 11:10:24 -07:00
Родитель 189a8e2a26
Коммит 5b98caf4af
7 изменённых файлов: 68 добавлений и 34 удалений

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

@ -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;