diff options
author | ladderbreaker <ladderbreaker@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2007-03-08 23:47:37 +0000 |
---|---|---|
committer | ladderbreaker <ladderbreaker@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2007-03-08 23:47:37 +0000 |
commit | 530a7ad99eba824dcca7fd300e85f1faa5828a3d (patch) | |
tree | 12fef8b26f63cdcc92e2647a0244c126db2e8d27 /src/client/mac/handler/exception_handler.cc | |
parent | Fix exception handler build with MSVC versions prior to 2005. r=mmentovai. (diff) | |
download | breakpad-530a7ad99eba824dcca7fd300e85f1faa5828a3d.tar.xz |
fixes for issue 128: reviewed by Waylonis
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@124 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/client/mac/handler/exception_handler.cc')
-rw-r--r-- | src/client/mac/handler/exception_handler.cc | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/client/mac/handler/exception_handler.cc b/src/client/mac/handler/exception_handler.cc index 0fdd18f7..e540df23 100644 --- a/src/client/mac/handler/exception_handler.cc +++ b/src/client/mac/handler/exception_handler.cc @@ -337,13 +337,22 @@ void *ExceptionHandler::WaitForMessage(void *exception_handler_class) { // If the actual exception code is zero, then we're calling this handler // in a way that indicates that we want to either exit this thread or // generate a minidump + // + // While reporting, all threads (except this one) must be suspended + // to avoid misleading stacks. If appropriate they will be resumed + // afterwards. if (!receive.exception) { if (self->is_in_teardown_) return NULL; + self->SuspendThreads(); + // Write out the dump and save the result for later retrieval self->last_minidump_write_result_ = self->WriteMinidumpWithException(0, 0, 0); + + self->ResumeThreads(); + if (self->use_minidump_write_mutex_) pthread_mutex_unlock(&self->minidump_write_mutex_); } else { @@ -353,6 +362,7 @@ void *ExceptionHandler::WaitForMessage(void *exception_handler_class) { // exceptions that occur in the parent process are caught and // processed. if (receive.task.name == mach_task_self()) { + self->SuspendThreads(); // Generate the minidump with the exception data. self->WriteMinidumpWithException(receive.exception, receive.code[0], @@ -512,4 +522,40 @@ void ExceptionHandler::UpdateNextID() { next_minidump_id_c_ = next_minidump_id_.c_str(); } +bool ExceptionHandler::SuspendThreads() { + thread_act_port_array_t threads_for_task; + mach_msg_type_number_t thread_count; + + if (task_threads(mach_task_self(), &threads_for_task, &thread_count)) + return false; + + // suspend all of the threads except for this one + for (unsigned int i = 0; i < thread_count; ++i) { + if (threads_for_task[i] != mach_thread_self()) { + if (thread_suspend(threads_for_task[i])) + return false; + } + } + + return true; +} + +bool ExceptionHandler::ResumeThreads() { + thread_act_port_array_t threads_for_task; + mach_msg_type_number_t thread_count; + + if (task_threads(mach_task_self(), &threads_for_task, &thread_count)) + return false; + + // resume all of the threads except for this one + for (unsigned int i = 0; i < thread_count; ++i) { + if (threads_for_task[i] != mach_thread_self()) { + if (thread_resume(threads_for_task[i])) + return false; + } + } + + return true; +} + } // namespace google_breakpad |