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