Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(248)

Unified Diff: handler/mac/crash_report_exception_handler.cc

Issue 904493002: handler: Write crash reports to a crash report database (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Rename FileHandleFileWriter to WeakFileHandleFileWriter Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « handler/mac/crash_report_exception_handler.h ('k') | handler/mac/exception_handler_server.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: handler/mac/crash_report_exception_handler.cc
diff --git a/handler/mac/crash_report_exception_handler.cc b/handler/mac/crash_report_exception_handler.cc
new file mode 100644
index 0000000000000000000000000000000000000000..2f497c6bfec29ad41337a9590eed6fb9b4125b1e
--- /dev/null
+++ b/handler/mac/crash_report_exception_handler.cc
@@ -0,0 +1,138 @@
+// Copyright 2015 The Crashpad Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "handler/mac/crash_report_exception_handler.h"
+
+#include "base/logging.h"
+#include "base/strings/stringprintf.h"
+#include "minidump/minidump_file_writer.h"
+#include "snapshot/mac/process_snapshot_mac.h"
+#include "util/file/file_writer.h"
+#include "util/mach/exception_behaviors.h"
+#include "util/mach/mach_extensions.h"
+#include "util/mach/scoped_task_suspend.h"
+#include "util/misc/uuid.h"
+
+namespace crashpad {
+
+namespace {
+
+// Calls CrashReportDatabase::ErrorWritingCrashReport() upon destruction unless
+// disarmed by calling Disarm(). Armed upon construction.
+class CallErrorWritingCrashReport {
+ public:
+ CallErrorWritingCrashReport(CrashReportDatabase* database,
+ CrashReportDatabase::NewReport* new_report)
+ : database_(database),
+ new_report_(new_report) {
+ }
+
+ ~CallErrorWritingCrashReport() {
+ if (new_report_) {
+ database_->ErrorWritingCrashReport(new_report_);
+ }
+ }
+
+ void Disarm() {
+ new_report_ = nullptr;
+ }
+
+ private:
+ CrashReportDatabase* database_; // weak
+ CrashReportDatabase::NewReport* new_report_; // weak
+
+ DISALLOW_COPY_AND_ASSIGN(CallErrorWritingCrashReport);
+};
+
+} // namespace
+
+CrashReportExceptionHandler::CrashReportExceptionHandler(
+ CrashReportDatabase* database)
+ : database_(database) {
+}
+
+CrashReportExceptionHandler::~CrashReportExceptionHandler() {
+}
+
+kern_return_t CrashReportExceptionHandler::CatchMachException(
+ exception_behavior_t behavior,
+ exception_handler_t exception_port,
+ thread_t thread,
+ task_t task,
+ exception_type_t exception,
+ const mach_exception_data_type_t* code,
+ mach_msg_type_number_t code_count,
+ thread_state_flavor_t* flavor,
+ const natural_t* old_state,
+ mach_msg_type_number_t old_state_count,
+ thread_state_t new_state,
+ mach_msg_type_number_t* new_state_count,
+ const mach_msg_trailer_t* trailer,
+ bool* destroy_complex_request) {
+ *destroy_complex_request = true;
+
+ // The expected behavior is EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES,
+ // but it’s possible to deal with any exception behavior as long as it
+ // carries identity information (valid thread and task ports).
+ if (!ExceptionBehaviorHasIdentity(behavior)) {
+ LOG(ERROR) << base::StringPrintf(
+ "unexpected exception behavior 0x%x, rejecting", behavior);
+ return KERN_FAILURE;
+ } else if (behavior != (EXCEPTION_STATE_IDENTITY | kMachExceptionCodes)) {
+ LOG(WARNING) << base::StringPrintf(
+ "unexpected exception behavior 0x%x, proceeding", behavior);
+ }
+
+ if (task == mach_task_self()) {
+ LOG(ERROR) << "cannot suspend myself";
+ return KERN_FAILURE;
+ }
+
+ ScopedTaskSuspend suspend(task);
+
+ ProcessSnapshotMac process_snapshot;
+ if (!process_snapshot.Initialize(task)) {
+ return KERN_FAILURE;
+ }
+
+ CrashReportDatabase::NewReport* new_report;
+ CrashReportDatabase::OperationStatus database_status =
+ database_->PrepareNewCrashReport(&new_report);
+ if (database_status != CrashReportDatabase::kNoError) {
+ return KERN_FAILURE;
+ }
+
+ CallErrorWritingCrashReport call_error_writing_crash_report(database_,
+ new_report);
+
+ WeakFileHandleFileWriter file_writer(new_report->handle);
+
+ MinidumpFileWriter minidump;
+ minidump.InitializeFromSnapshot(&process_snapshot);
+ if (!minidump.WriteEverything(&file_writer)) {
+ return KERN_FAILURE;
+ }
+
+ call_error_writing_crash_report.Disarm();
+
+ UUID uuid;
+ database_status = database_->FinishedWritingCrashReport(new_report, &uuid);
+ if (database_status != CrashReportDatabase::kNoError) {
+ return KERN_FAILURE;
+ }
+
+ return ExcServerSuccessfulReturnValue(behavior, false);
+}
+
+} // namespace crashpad
« no previous file with comments | « handler/mac/crash_report_exception_handler.h ('k') | handler/mac/exception_handler_server.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698