13ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// Copyright (c) 2007, Google Inc. 23ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// All rights reserved. 33ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 43ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// Redistribution and use in source and binary forms, with or without 53ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// modification, are permitted provided that the following conditions are 63ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// met: 73ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 83ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// * Redistributions of source code must retain the above copyright 93ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// notice, this list of conditions and the following disclaimer. 103ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// * Redistributions in binary form must reproduce the above 113ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// copyright notice, this list of conditions and the following disclaimer 123ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// in the documentation and/or other materials provided with the 133ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// distribution. 143ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// * Neither the name of Google Inc. nor the names of its 153ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// contributors may be used to endorse or promote products derived from 163ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// this software without specific prior written permission. 173ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 183ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 193ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 203ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 213ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 223ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 233ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 243ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 253ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 263ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 273ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 283ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 293ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 303ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// Interface file between the Breakpad.framework and 313ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// the Inspector process. 323ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 33303311b8370b307ea38201fc3ad241a5610f8cfcrsesek@chromium.org#include "common/simple_string_dictionary.h" 343ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 353ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid#import <Foundation/Foundation.h> 361e9dbde88a0f7cdcaba556a24fa468627d5c7e84mark@chromium.org#include <mach/mach.h> 371e9dbde88a0f7cdcaba556a24fa468627d5c7e84mark@chromium.org 3800936cf4ad413ec012b81c814319467c206d7447qsr@chromium.org#import "client/mac/crash_generation/ConfigFile.h" 393ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid#import "client/mac/handler/minidump_generator.h" 403ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 413ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 423ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// Types of mach messsages (message IDs) 433ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsidenum { 443ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid kMsgType_InspectorInitialInfo = 0, // data is InspectorInfo 453ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid kMsgType_InspectorKeyValuePair = 1, // data is KeyValueMessageData 463ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid kMsgType_InspectorAcknowledgement = 2 // no data sent 473ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid}; 483ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 493ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// Initial information sent from the crashed process by 503ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// Breakpad.framework to the Inspector process 513ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// The mach message with this struct as data will also include 523ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// several descriptors for sending mach port rights to the crashed 533ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// task, etc. 543ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsidstruct InspectorInfo { 553ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid int exception_type; 563ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid int exception_code; 5761e88c7ad7eb072977b4d4d26bcf8929b75af2d4ted.mielczarek int exception_subcode; 583ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid unsigned int parameter_count; // key-value pairs 593ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid}; 603ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 613ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// Key/value message data to be sent to the Inspector 623ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsidstruct KeyValueMessageData { 633ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid public: 643ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid KeyValueMessageData() {} 65c36fcd7f534887b5f8e83dca2ef445cb05e09463rsesek@chromium.org explicit KeyValueMessageData( 66c36fcd7f534887b5f8e83dca2ef445cb05e09463rsesek@chromium.org const google_breakpad::SimpleStringDictionary::Entry &inEntry) { 67c36fcd7f534887b5f8e83dca2ef445cb05e09463rsesek@chromium.org strlcpy(key, inEntry.key, sizeof(key) ); 68c36fcd7f534887b5f8e83dca2ef445cb05e09463rsesek@chromium.org strlcpy(value, inEntry.value, sizeof(value) ); 693ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 703ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 71c36fcd7f534887b5f8e83dca2ef445cb05e09463rsesek@chromium.org char key[google_breakpad::SimpleStringDictionary::key_size]; 72c36fcd7f534887b5f8e83dca2ef445cb05e09463rsesek@chromium.org char value[google_breakpad::SimpleStringDictionary::value_size]; 733ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid}; 743ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 753ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsidusing std::string; 763ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsidusing google_breakpad::MinidumpGenerator; 773ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 783ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsidnamespace google_breakpad { 793ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 803ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid//============================================================================= 813ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsidclass MinidumpLocation { 823ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid public: 83ba5ee2c8f51c481db23a1ce848368ec69dabac48mark@chromium.org MinidumpLocation(NSString *minidumpDir) { 843ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // Ensure that the path exists. Fallback to /tmp if unable to locate path. 85a3d4c973369987e14cc0c05964e288ea0eac11dcnealsid assert(minidumpDir); 863ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid if (!EnsureDirectoryPathExists(minidumpDir)) { 873ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid minidumpDir = @"/tmp"; 883ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 893ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 903ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid strlcpy(minidump_dir_path_, [minidumpDir fileSystemRepresentation], 913ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid sizeof(minidump_dir_path_)); 923ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 933ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // now generate a unique ID 943ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid string dump_path(minidump_dir_path_); 953ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid string next_minidump_id; 963ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 973ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid string next_minidump_path_ = 983ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid (MinidumpGenerator::UniqueNameInDirectory(dump_path, &next_minidump_id)); 993ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1003ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid strlcpy(minidump_id_, next_minidump_id.c_str(), sizeof(minidump_id_)); 1013ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid }; 1023ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1033ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid const char *GetPath() { return minidump_dir_path_; } 1043ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid const char *GetID() { return minidump_id_; } 1053ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1063ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid private: 1073ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid char minidump_dir_path_[PATH_MAX]; // Path to minidump directory 1083ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid char minidump_id_[128]; 1093ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid}; 1103ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1113ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid//============================================================================= 1123ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsidclass Inspector { 1133ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid public: 1143ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid Inspector() {}; 1153ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1163ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // given a bootstrap service name, receives mach messages 1173ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // from a crashed process, then inspects it, creates a minidump file 1183ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // and asks the user if he wants to upload it to a server. 1193ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid void Inspect(const char *receive_port_name); 1203ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1213ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid private: 1221e9dbde88a0f7cdcaba556a24fa468627d5c7e84mark@chromium.org // The Inspector is invoked with its bootstrap port set to the bootstrap 1231e9dbde88a0f7cdcaba556a24fa468627d5c7e84mark@chromium.org // subset established in OnDemandServer.mm OnDemandServer::Initialize. 1241e9dbde88a0f7cdcaba556a24fa468627d5c7e84mark@chromium.org // For proper communication with the system, the sender (which will inherit 1251e9dbde88a0f7cdcaba556a24fa468627d5c7e84mark@chromium.org // the Inspector's bootstrap port) needs the per-session bootstrap namespace 1261e9dbde88a0f7cdcaba556a24fa468627d5c7e84mark@chromium.org // available directly in its bootstrap port. OnDemandServer stashed this 1271e9dbde88a0f7cdcaba556a24fa468627d5c7e84mark@chromium.org // port into the subset namespace under a special name. ResetBootstrapPort 1281e9dbde88a0f7cdcaba556a24fa468627d5c7e84mark@chromium.org // recovers this port and switches this task to use it as its own bootstrap 1291e9dbde88a0f7cdcaba556a24fa468627d5c7e84mark@chromium.org // (ensuring that children like the sender will inherit it), and saves the 1301e9dbde88a0f7cdcaba556a24fa468627d5c7e84mark@chromium.org // subset in bootstrap_subset_port_ for use by ServiceCheckIn and 1311e9dbde88a0f7cdcaba556a24fa468627d5c7e84mark@chromium.org // ServiceCheckOut. 132405bb7aff734100b8d25adfd93d42d54a778b9a4mark@chromium.org kern_return_t ResetBootstrapPort(); 1331e9dbde88a0f7cdcaba556a24fa468627d5c7e84mark@chromium.org 1343ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid kern_return_t ServiceCheckIn(const char *receive_port_name); 1353ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid kern_return_t ServiceCheckOut(const char *receive_port_name); 1363ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1373ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid kern_return_t ReadMessages(); 1383ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1393ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid bool InspectTask(); 1403ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid kern_return_t SendAcknowledgement(); 1413ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1421e9dbde88a0f7cdcaba556a24fa468627d5c7e84mark@chromium.org // The bootstrap port in which the inspector is registered and into which it 1431e9dbde88a0f7cdcaba556a24fa468627d5c7e84mark@chromium.org // must check in. 1441e9dbde88a0f7cdcaba556a24fa468627d5c7e84mark@chromium.org mach_port_t bootstrap_subset_port_; 1451e9dbde88a0f7cdcaba556a24fa468627d5c7e84mark@chromium.org 1463ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid mach_port_t service_rcv_port_; 1473ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1483ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid int exception_type_; 1493ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid int exception_code_; 15061e88c7ad7eb072977b4d4d26bcf8929b75af2d4ted.mielczarek int exception_subcode_; 1513ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid mach_port_t remote_task_; 1523ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid mach_port_t crashing_thread_; 1533ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid mach_port_t handler_thread_; 1543ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid mach_port_t ack_port_; 1553ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1563ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid SimpleStringDictionary config_params_; 1573ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1583ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid ConfigFile config_file_; 1593ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid}; 1603ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1613ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1623ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid} // namespace google_breakpad 163