OLD | NEW |
(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/win/crash_report_exception_handler.h" |
| 16 |
| 17 #include "client/crash_report_database.h" |
| 18 #include "client/settings.h" |
| 19 #include "handler/crash_report_upload_thread.h" |
| 20 #include "minidump/minidump_file_writer.h" |
| 21 #include "snapshot/win/process_snapshot_win.h" |
| 22 #include "util/file/file_writer.h" |
| 23 #include "util/win/registration_protocol_win.h" |
| 24 |
| 25 namespace crashpad { |
| 26 |
| 27 CrashReportExceptionHandler::CrashReportExceptionHandler( |
| 28 CrashReportDatabase* database, |
| 29 CrashReportUploadThread* upload_thread, |
| 30 const std::map<std::string, std::string>* process_annotations) |
| 31 : database_(database), |
| 32 upload_thread_(upload_thread), |
| 33 process_annotations_(process_annotations) { |
| 34 } |
| 35 |
| 36 CrashReportExceptionHandler::~CrashReportExceptionHandler() { |
| 37 } |
| 38 |
| 39 void CrashReportExceptionHandler::ExceptionHandlerServerStarted() { |
| 40 } |
| 41 |
| 42 unsigned int CrashReportExceptionHandler::ExceptionHandlerServerException( |
| 43 HANDLE process, |
| 44 WinVMAddress exception_information_address) { |
| 45 const unsigned int kFailedTerminationCode = 0xffff7002; |
| 46 |
| 47 // TODO(scottmg): ScopedProcessSuspend |
| 48 |
| 49 ProcessSnapshotWin process_snapshot; |
| 50 if (!process_snapshot.Initialize(process)) { |
| 51 LOG(WARNING) << "ProcessSnapshotWin::Initialize failed"; |
| 52 return kFailedTerminationCode; |
| 53 } |
| 54 |
| 55 if (!process_snapshot.InitializeException(exception_information_address)) { |
| 56 LOG(WARNING) << "ProcessSnapshotWin::InitializeException failed"; |
| 57 return kFailedTerminationCode; |
| 58 } |
| 59 |
| 60 // Now that we have the exception information, even if something else fails we |
| 61 // can terminate the process with the correct exit code. |
| 62 const unsigned int termination_code = |
| 63 process_snapshot.Exception()->Exception(); |
| 64 |
| 65 CrashpadInfoClientOptions client_options; |
| 66 process_snapshot.GetCrashpadOptions(&client_options); |
| 67 if (client_options.crashpad_handler_behavior != TriState::kDisabled) { |
| 68 UUID client_id; |
| 69 Settings* const settings = database_->GetSettings(); |
| 70 if (settings) { |
| 71 // If GetSettings() or GetClientID() fails, something else will log a |
| 72 // message and client_id will be left at its default value, all zeroes, |
| 73 // which is appropriate. |
| 74 settings->GetClientID(&client_id); |
| 75 } |
| 76 |
| 77 process_snapshot.SetClientID(client_id); |
| 78 process_snapshot.SetAnnotationsSimpleMap(*process_annotations_); |
| 79 |
| 80 CrashReportDatabase::NewReport* new_report; |
| 81 CrashReportDatabase::OperationStatus database_status = |
| 82 database_->PrepareNewCrashReport(&new_report); |
| 83 if (database_status != CrashReportDatabase::kNoError) { |
| 84 LOG(ERROR) << "PrepareNewCrashReport failed"; |
| 85 return termination_code; |
| 86 } |
| 87 |
| 88 process_snapshot.SetReportID(new_report->uuid); |
| 89 |
| 90 CrashReportDatabase::CallErrorWritingCrashReport |
| 91 call_error_writing_crash_report(database_, new_report); |
| 92 |
| 93 WeakFileHandleFileWriter file_writer(new_report->handle); |
| 94 |
| 95 MinidumpFileWriter minidump; |
| 96 minidump.InitializeFromSnapshot(&process_snapshot); |
| 97 if (!minidump.WriteEverything(&file_writer)) { |
| 98 LOG(ERROR) << "WriteEverything failed"; |
| 99 return termination_code; |
| 100 } |
| 101 |
| 102 call_error_writing_crash_report.Disarm(); |
| 103 |
| 104 UUID uuid; |
| 105 database_status = database_->FinishedWritingCrashReport(new_report, &uuid); |
| 106 if (database_status != CrashReportDatabase::kNoError) { |
| 107 LOG(ERROR) << "FinishedWritingCrashReport failed"; |
| 108 return termination_code; |
| 109 } |
| 110 |
| 111 upload_thread_->ReportPending(); |
| 112 } |
| 113 |
| 114 return termination_code; |
| 115 } |
| 116 |
| 117 } // namespace crashpad |
OLD | NEW |