1 // Copyright 2018 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 #ifndef CRASHPAD_HANDLER_LINUX_CRASH_REPORT_EXCEPTION_HANDLER_H_
16 #define CRASHPAD_HANDLER_LINUX_CRASH_REPORT_EXCEPTION_HANDLER_H_
17 
18 #include <map>
19 #include <string>
20 
21 #include "base/macros.h"
22 #include "client/crash_report_database.h"
23 #include "handler/crash_report_upload_thread.h"
24 #include "handler/linux/exception_handler_server.h"
25 #include "handler/user_stream_data_source.h"
26 #include "util/linux/exception_handler_protocol.h"
27 #include "util/linux/ptrace_connection.h"
28 #include "util/misc/address_types.h"
29 #include "util/misc/uuid.h"
30 
31 namespace crashpad {
32 
33 class ProcessSnapshotLinux;
34 class ProcessSnapshotSanitized;
35 
36 //! \brief An exception handler that writes crash reports for exceptions
37 //!     to a CrashReportDatabase.
38 class CrashReportExceptionHandler : public ExceptionHandlerServer::Delegate {
39  public:
40   //! \brief Creates a new object that will store crash reports in \a database.
41   //!
42   //! \param[in] database The database to store crash reports in. Weak.
43   //! \param[in] upload_thread The upload thread to notify when a new crash
44   //!     report is written into \a database. Report upload is skipped if this
45   //!     value is `nullptr`.
46   //! \param[in] process_annotations A map of annotations to insert as
47   //!     process-level annotations into each crash report that is written. Do
48   //!     not confuse this with module-level annotations, which are under the
49   //!     control of the crashing process, and are used to implement Chrome’s
50   //!     “crash keys.” Process-level annotations are those that are beyond the
51   //!     control of the crashing process, which must reliably be set even if
52   //!     the process crashes before it’s able to establish its own annotations.
53   //!     To interoperate with Breakpad servers, the recommended practice is to
54   //!     specify values for the `"prod"` and `"ver"` keys as process
55   //!     annotations.
56   //! \param[in] write_minidump_to_database Whether the minidump shall be
57   //!     written to database.
58   //! \param[in] write_minidump_to_log Whether the minidump shall be written to
59   //!     log.
60   //! \param[in] user_stream_data_sources Data sources to be used to extend
61   //!     crash reports. For each crash report that is written, the data sources
62   //!     are called in turn. These data sources may contribute additional
63   //!     minidump streams. `nullptr` if not required.
64   CrashReportExceptionHandler(
65       CrashReportDatabase* database,
66       CrashReportUploadThread* upload_thread,
67       const std::map<std::string, std::string>* process_annotations,
68       bool write_minidump_to_database,
69       bool write_minidump_to_log,
70       const UserStreamDataSources* user_stream_data_sources);
71 
72   ~CrashReportExceptionHandler() override;
73 
74   // ExceptionHandlerServer::Delegate:
75 
76   bool HandleException(pid_t client_process_id,
77                        uid_t client_uid,
78                        const ExceptionHandlerProtocol::ClientInformation& info,
79                        VMAddress requesting_thread_stack_address = 0,
80                        pid_t* requesting_thread_id = nullptr,
81                        UUID* local_report_id = nullptr) override;
82 
83   bool HandleExceptionWithBroker(
84       pid_t client_process_id,
85       uid_t client_uid,
86       const ExceptionHandlerProtocol::ClientInformation& info,
87       int broker_sock,
88       UUID* local_report_id = nullptr) override;
89 
90  private:
91   bool HandleExceptionWithConnection(
92       PtraceConnection* connection,
93       const ExceptionHandlerProtocol::ClientInformation& info,
94       uid_t client_uid,
95       VMAddress requesting_thread_stack_address,
96       pid_t* requesting_thread_id,
97       UUID* local_report_id = nullptr);
98 
99   bool WriteMinidumpToDatabase(ProcessSnapshotLinux* process_snapshot,
100                                ProcessSnapshotSanitized* sanitized_snapshot,
101                                bool write_minidump_to_log,
102                                UUID* local_report_id);
103   bool WriteMinidumpToLog(ProcessSnapshotLinux* process_snapshot,
104                           ProcessSnapshotSanitized* sanitized_snapshot);
105 
106   CrashReportDatabase* database_;  // weak
107   CrashReportUploadThread* upload_thread_;  // weak
108   const std::map<std::string, std::string>* process_annotations_;  // weak
109   bool write_minidump_to_database_;
110   bool write_minidump_to_log_;
111   const UserStreamDataSources* user_stream_data_sources_;  // weak
112 
113   DISALLOW_COPY_AND_ASSIGN(CrashReportExceptionHandler);
114 };
115 
116 }  // namespace crashpad
117 
118 #endif  // CRASHPAD_HANDLER_LINUX_CRASH_REPORT_EXCEPTION_HANDLER_H_
119