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] attachments A vector of file paths that should be captured with
57   //!     each report at the time of the crash.
58   //! \param[in] write_minidump_to_database Whether the minidump shall be
59   //!     written to database.
60   //! \param[in] write_minidump_to_log Whether the minidump shall be written to
61   //!     log.
62   //! \param[in] user_stream_data_sources Data sources to be used to extend
63   //!     crash reports. For each crash report that is written, the data sources
64   //!     are called in turn. These data sources may contribute additional
65   //!     minidump streams. `nullptr` if not required.
66   CrashReportExceptionHandler(
67       CrashReportDatabase* database,
68       CrashReportUploadThread* upload_thread,
69       const std::map<std::string, std::string>* process_annotations,
70       const std::vector<base::FilePath>* attachments,
71       bool write_minidump_to_database,
72       bool write_minidump_to_log,
73       const UserStreamDataSources* user_stream_data_sources);
74 
75   ~CrashReportExceptionHandler() override;
76 
77   // ExceptionHandlerServer::Delegate:
78 
79   bool HandleException(pid_t client_process_id,
80                        uid_t client_uid,
81                        const ExceptionHandlerProtocol::ClientInformation& info,
82                        VMAddress requesting_thread_stack_address = 0,
83                        pid_t* requesting_thread_id = nullptr,
84                        UUID* local_report_id = nullptr) override;
85 
86   bool HandleExceptionWithBroker(
87       pid_t client_process_id,
88       uid_t client_uid,
89       const ExceptionHandlerProtocol::ClientInformation& info,
90       int broker_sock,
91       UUID* local_report_id = nullptr) override;
92 
93  private:
94   bool HandleExceptionWithConnection(
95       PtraceConnection* connection,
96       const ExceptionHandlerProtocol::ClientInformation& info,
97       uid_t client_uid,
98       VMAddress requesting_thread_stack_address,
99       pid_t* requesting_thread_id,
100       UUID* local_report_id = nullptr);
101 
102   bool WriteMinidumpToDatabase(ProcessSnapshotLinux* process_snapshot,
103                                ProcessSnapshotSanitized* sanitized_snapshot,
104                                bool write_minidump_to_log,
105                                UUID* local_report_id);
106   bool WriteMinidumpToLog(ProcessSnapshotLinux* process_snapshot,
107                           ProcessSnapshotSanitized* sanitized_snapshot);
108 
109   CrashReportDatabase* database_;  // weak
110   CrashReportUploadThread* upload_thread_;  // weak
111   const std::map<std::string, std::string>* process_annotations_;  // weak
112   const std::vector<base::FilePath>* attachments_;  // weak
113   bool write_minidump_to_database_;
114   bool write_minidump_to_log_;
115   const UserStreamDataSources* user_stream_data_sources_;  // weak
116 
117   DISALLOW_COPY_AND_ASSIGN(CrashReportExceptionHandler);
118 };
119 
120 }  // namespace crashpad
121 
122 #endif  // CRASHPAD_HANDLER_LINUX_CRASH_REPORT_EXCEPTION_HANDLER_H_
123