xref: /aosp_15_r20/external/google-breakpad/src/client/mac/crash_generation/Inspector.h (revision 9712c20fc9bbfbac4935993a2ca0b3958c5adad2)
1 // Copyright 2007 Google LLC
2 //
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are
5 // met:
6 //
7 //     * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 //     * Redistributions in binary form must reproduce the above
10 // copyright notice, this list of conditions and the following disclaimer
11 // in the documentation and/or other materials provided with the
12 // distribution.
13 //     * Neither the name of Google LLC nor the names of its
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 //
29 // Interface file between the Breakpad.framework and
30 // the Inspector process.
31 
32 #include "common/simple_string_dictionary.h"
33 
34 #import <Foundation/Foundation.h>
35 #include <mach/mach.h>
36 
37 #import "client/mac/crash_generation/ConfigFile.h"
38 #import "client/mac/handler/minidump_generator.h"
39 
40 
41 // Types of mach messsages (message IDs)
42 enum {
43   kMsgType_InspectorInitialInfo = 0,    // data is InspectorInfo
44   kMsgType_InspectorKeyValuePair = 1,   // data is KeyValueMessageData
45   kMsgType_InspectorAcknowledgement = 2 // no data sent
46 };
47 
48 // Initial information sent from the crashed process by
49 // Breakpad.framework to the Inspector process
50 // The mach message with this struct as data will also include
51 // several descriptors for sending mach port rights to the crashed
52 // task, etc.
53 struct InspectorInfo {
54   int           exception_type;
55   int           exception_code;
56   int           exception_subcode;
57   unsigned int  parameter_count;  // key-value pairs
58 };
59 
60 // Key/value message data to be sent to the Inspector
61 struct KeyValueMessageData {
62  public:
KeyValueMessageDataKeyValueMessageData63   KeyValueMessageData() {}
KeyValueMessageDataKeyValueMessageData64   explicit KeyValueMessageData(
65       const google_breakpad::SimpleStringDictionary::Entry& inEntry) {
66     strlcpy(key, inEntry.key, sizeof(key) );
67     strlcpy(value, inEntry.value, sizeof(value) );
68   }
69 
70   char key[google_breakpad::SimpleStringDictionary::key_size];
71   char value[google_breakpad::SimpleStringDictionary::value_size];
72 };
73 
74 using std::string;
75 using google_breakpad::MinidumpGenerator;
76 
77 namespace google_breakpad {
78 
79 //=============================================================================
80 class MinidumpLocation {
81  public:
MinidumpLocation(NSString * minidumpDir)82   MinidumpLocation(NSString* minidumpDir) {
83     // Ensure that the path exists.  Fallback to /tmp if unable to locate path.
84     assert(minidumpDir);
85     if (!EnsureDirectoryPathExists(minidumpDir)) {
86       minidumpDir = @"/tmp";
87     }
88 
89     strlcpy(minidump_dir_path_, [minidumpDir fileSystemRepresentation],
90             sizeof(minidump_dir_path_));
91 
92     // now generate a unique ID
93     string dump_path(minidump_dir_path_);
94     string next_minidump_id;
95 
96     string next_minidump_path_ =
97       (MinidumpGenerator::UniqueNameInDirectory(dump_path, &next_minidump_id));
98 
99     strlcpy(minidump_id_, next_minidump_id.c_str(), sizeof(minidump_id_));
100   }
101 
GetPath()102   const char* GetPath() { return minidump_dir_path_; }
GetID()103   const char* GetID() { return minidump_id_; }
104 
105  private:
106   char minidump_dir_path_[PATH_MAX];             // Path to minidump directory
107   char minidump_id_[128];
108 };
109 
110 //=============================================================================
111 class Inspector {
112  public:
Inspector()113   Inspector() {}
114 
115   // given a bootstrap service name, receives mach messages
116   // from a crashed process, then inspects it, creates a minidump file
117   // and asks the user if he wants to upload it to a server.
118   void            Inspect(const char* receive_port_name);
119 
120  private:
121   // The Inspector is invoked with its bootstrap port set to the bootstrap
122   // subset established in OnDemandServer.mm OnDemandServer::Initialize.
123   // For proper communication with the system, the sender (which will inherit
124   // the Inspector's bootstrap port) needs the per-session bootstrap namespace
125   // available directly in its bootstrap port. OnDemandServer stashed this
126   // port into the subset namespace under a special name. ResetBootstrapPort
127   // recovers this port and switches this task to use it as its own bootstrap
128   // (ensuring that children like the sender will inherit it), and saves the
129   // subset in bootstrap_subset_port_ for use by ServiceCheckIn and
130   // ServiceCheckOut.
131   kern_return_t   ResetBootstrapPort();
132 
133   kern_return_t   ServiceCheckIn(const char* receive_port_name);
134   kern_return_t   ServiceCheckOut(const char* receive_port_name);
135 
136   kern_return_t   ReadMessages();
137 
138   bool            InspectTask();
139   kern_return_t   SendAcknowledgement();
140 
141   // The bootstrap port in which the inspector is registered and into which it
142   // must check in.
143   mach_port_t     bootstrap_subset_port_;
144 
145   mach_port_t     service_rcv_port_;
146 
147   int             exception_type_;
148   int             exception_code_;
149   int             exception_subcode_;
150   mach_port_t     remote_task_;
151   mach_port_t     crashing_thread_;
152   mach_port_t     handler_thread_;
153   mach_port_t     ack_port_;
154 
155   SimpleStringDictionary config_params_;
156 
157   ConfigFile      config_file_;
158 };
159 
160 
161 } // namespace google_breakpad
162