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

Side by Side 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Crashpad Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "handler/mac/crash_report_exception_handler.h"
16
17 #include "base/logging.h"
18 #include "base/strings/stringprintf.h"
19 #include "minidump/minidump_file_writer.h"
20 #include "snapshot/mac/process_snapshot_mac.h"
21 #include "util/file/file_writer.h"
22 #include "util/mach/exception_behaviors.h"
23 #include "util/mach/mach_extensions.h"
24 #include "util/mach/scoped_task_suspend.h"
25 #include "util/misc/uuid.h"
26
27 namespace crashpad {
28
29 namespace {
30
31 // Calls CrashReportDatabase::ErrorWritingCrashReport() upon destruction unless
32 // disarmed by calling Disarm(). Armed upon construction.
33 class CallErrorWritingCrashReport {
34 public:
35 CallErrorWritingCrashReport(CrashReportDatabase* database,
36 CrashReportDatabase::NewReport* new_report)
37 : database_(database),
38 new_report_(new_report) {
39 }
40
41 ~CallErrorWritingCrashReport() {
42 if (new_report_) {
43 database_->ErrorWritingCrashReport(new_report_);
44 }
45 }
46
47 void Disarm() {
48 new_report_ = nullptr;
49 }
50
51 private:
52 CrashReportDatabase* database_; // weak
53 CrashReportDatabase::NewReport* new_report_; // weak
54
55 DISALLOW_COPY_AND_ASSIGN(CallErrorWritingCrashReport);
56 };
57
58 } // namespace
59
60 CrashReportExceptionHandler::CrashReportExceptionHandler(
61 CrashReportDatabase* database)
62 : database_(database) {
63 }
64
65 CrashReportExceptionHandler::~CrashReportExceptionHandler() {
66 }
67
68 kern_return_t CrashReportExceptionHandler::CatchMachException(
69 exception_behavior_t behavior,
70 exception_handler_t exception_port,
71 thread_t thread,
72 task_t task,
73 exception_type_t exception,
74 const mach_exception_data_type_t* code,
75 mach_msg_type_number_t code_count,
76 thread_state_flavor_t* flavor,
77 const natural_t* old_state,
78 mach_msg_type_number_t old_state_count,
79 thread_state_t new_state,
80 mach_msg_type_number_t* new_state_count,
81 const mach_msg_trailer_t* trailer,
82 bool* destroy_complex_request) {
83 *destroy_complex_request = true;
84
85 // The expected behavior is EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES,
86 // but it’s possible to deal with any exception behavior as long as it
87 // carries identity information (valid thread and task ports).
88 if (!ExceptionBehaviorHasIdentity(behavior)) {
89 LOG(ERROR) << base::StringPrintf(
90 "unexpected exception behavior 0x%x, rejecting", behavior);
91 return KERN_FAILURE;
92 } else if (behavior != (EXCEPTION_STATE_IDENTITY | kMachExceptionCodes)) {
93 LOG(WARNING) << base::StringPrintf(
94 "unexpected exception behavior 0x%x, proceeding", behavior);
95 }
96
97 if (task == mach_task_self()) {
98 LOG(ERROR) << "cannot suspend myself";
99 return KERN_FAILURE;
100 }
101
102 ScopedTaskSuspend suspend(task);
103
104 ProcessSnapshotMac process_snapshot;
105 if (!process_snapshot.Initialize(task)) {
106 return KERN_FAILURE;
107 }
108
109 CrashReportDatabase::NewReport* new_report;
110 CrashReportDatabase::OperationStatus database_status =
111 database_->PrepareNewCrashReport(&new_report);
112 if (database_status != CrashReportDatabase::kNoError) {
113 return KERN_FAILURE;
114 }
115
116 CallErrorWritingCrashReport call_error_writing_crash_report(database_,
117 new_report);
118
119 WeakFileHandleFileWriter file_writer(new_report->handle);
120
121 MinidumpFileWriter minidump;
122 minidump.InitializeFromSnapshot(&process_snapshot);
123 if (!minidump.WriteEverything(&file_writer)) {
124 return KERN_FAILURE;
125 }
126
127 call_error_writing_crash_report.Disarm();
128
129 UUID uuid;
130 database_status = database_->FinishedWritingCrashReport(new_report, &uuid);
131 if (database_status != CrashReportDatabase::kNoError) {
132 return KERN_FAILURE;
133 }
134
135 return ExcServerSuccessfulReturnValue(behavior, false);
136 }
137
138 } // namespace crashpad
OLDNEW
« 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