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) 43enum { 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. 54struct 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 62struct 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 75using std::string; 76using google_breakpad::MinidumpGenerator; 77 78namespace google_breakpad { 79 80//============================================================================= 81class 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//============================================================================= 112class 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