1*9712c20fSFrederick Mayle# How To Add Breakpad To Your Mac Client Application 2*9712c20fSFrederick Mayle 3*9712c20fSFrederick MayleThis document is a step-by-step recipe to get your Mac client app to build with 4*9712c20fSFrederick MayleBreakpad. 5*9712c20fSFrederick Mayle 6*9712c20fSFrederick Mayle## Preparing a binary build of Breakpad for use in your tree 7*9712c20fSFrederick Mayle 8*9712c20fSFrederick MayleYou can either check in a binary build of the Breakpad framework & tools or 9*9712c20fSFrederick Maylebuild it as a dependency of your project. The former is recommended, and 10*9712c20fSFrederick Mayledetailed here, since building dependencies through other projects is 11*9712c20fSFrederick Mayleproblematic(matching up configuration names), and the Breakpad code doesn't 12*9712c20fSFrederick Maylechange nearly often enough as your application's will. 13*9712c20fSFrederick Mayle 14*9712c20fSFrederick Mayle## Building the requisite targets 15*9712c20fSFrederick Mayle 16*9712c20fSFrederick MayleAll directories are relative to the `src` directory of the Breakpad checkout. 17*9712c20fSFrederick Mayle 18*9712c20fSFrederick Mayle* Build the 'All' target of `client/mac/Breakpad.xcodeproj` in Release mode. 19*9712c20fSFrederick Mayle* Execute `cp -R client/mac/build/Release/Breakpad.framework <location in your 20*9712c20fSFrederick Mayle source tree>` 21*9712c20fSFrederick Mayle* Inside `tools/mac/dump_syms` directory, build dump\_syms.xcodeproj, and copy 22*9712c20fSFrederick Mayle tools/mac/dump\_syms/build/Release/dump\_syms to a safe location where it 23*9712c20fSFrederick Mayle can be run during the build process. 24*9712c20fSFrederick Mayle 25*9712c20fSFrederick Mayle## Adding Breakpad.framework 26*9712c20fSFrederick Mayle 27*9712c20fSFrederick MayleInside your application's framework, add the Breakpad.Framework to your 28*9712c20fSFrederick Mayleproject's framework settings. When you select it from the file chooser, it will 29*9712c20fSFrederick Maylelet you pick a target to add it to; go ahead and check the one that's relevant 30*9712c20fSFrederick Mayleto your application. 31*9712c20fSFrederick Mayle 32*9712c20fSFrederick Mayle## Copy Breakpad into your Application Package 33*9712c20fSFrederick Mayle 34*9712c20fSFrederick MayleCopy Breakpad into your Application Package, so it will be around at run time. 35*9712c20fSFrederick Mayle 36*9712c20fSFrederick MayleGo to the Targets section of your Xcode Project window. Hit the disclosure 37*9712c20fSFrederick Mayletriangle to reveal the build phases of your application. Add a new Copy Files 38*9712c20fSFrederick Maylephase using the Contextual menu (Control Click). On the General panel of the new 39*9712c20fSFrederick Mayle'Get Info' of this new phase, set the destination to 'Frameworks' Close the 40*9712c20fSFrederick Mayle'Info' panel. Use the Contextual Menu to Rename your new phase 'Copy Frameworks' 41*9712c20fSFrederick MayleNow drag Breakpad again into this Copy Frameworks phase. Drag it from whereever 42*9712c20fSFrederick Mayleit appears in the project file tree. 43*9712c20fSFrederick Mayle 44*9712c20fSFrederick Mayle## Add a New Run Script build phase 45*9712c20fSFrederick Mayle 46*9712c20fSFrederick MayleNear the end of the build phases, add a new Run Script build phase. This will be 47*9712c20fSFrederick Maylerun before Xcode calls /usr/bin/strip on your project. This is where you'll be 48*9712c20fSFrederick Maylecalling dump\_sym to output the symbols for each architecture of your build. In 49*9712c20fSFrederick Maylemy case, the relevant lines read: 50*9712c20fSFrederick Mayle 51*9712c20fSFrederick Mayle``` 52*9712c20fSFrederick Mayle#!/bin/sh 53*9712c20fSFrederick Mayle$TOOL_DIR=<location of dump_syms from step 3 above> 54*9712c20fSFrederick Mayle 55*9712c20fSFrederick Mayle"$TOOL_DIR/dump_syms" -a ppc "$PROD" > "$TARGET_NAME ppc.breakpad" 56*9712c20fSFrederick Mayle 57*9712c20fSFrederick Mayle"$TOOL_DIR/dump_syms" -a i386 "$PROD" > "$TARGET_NAME i386.breakpad" 58*9712c20fSFrederick Mayle``` 59*9712c20fSFrederick Mayle 60*9712c20fSFrederick Mayle## Adjust the Project Settings 61*9712c20fSFrederick Mayle 62*9712c20fSFrederick Mayle* Turn on Separate Strip, 63*9712c20fSFrederick Mayle* Set the Strip Style to Non-Global Symbols. 64*9712c20fSFrederick Mayle 65*9712c20fSFrederick Mayle## Write Code! 66*9712c20fSFrederick Mayle 67*9712c20fSFrederick MayleYou'll need to have an object that acts as the delegate for NSApplication. 68*9712c20fSFrederick MayleInside this object's header, you'll need to add 69*9712c20fSFrederick Mayle 70*9712c20fSFrederick Mayle1. add an ivar for Breakpad and 71*9712c20fSFrederick Mayle2. a declaration for the applicationShouldTerminate:(NSApplication`*` sender) 72*9712c20fSFrederick Mayle message. 73*9712c20fSFrederick Mayle 74*9712c20fSFrederick Mayle``` 75*9712c20fSFrederick Mayle#import <Breakpad/Breakpad.h> 76*9712c20fSFrederick Mayle 77*9712c20fSFrederick Mayle@interface BreakpadTest : NSObject { 78*9712c20fSFrederick Mayle . 79*9712c20fSFrederick Mayle . 80*9712c20fSFrederick Mayle . 81*9712c20fSFrederick Mayle BreakpadRef breakpad; 82*9712c20fSFrederick Mayle . 83*9712c20fSFrederick Mayle . 84*9712c20fSFrederick Mayle . 85*9712c20fSFrederick Mayle} 86*9712c20fSFrederick Mayle. 87*9712c20fSFrederick Mayle. 88*9712c20fSFrederick Mayle- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; 89*9712c20fSFrederick Mayle. 90*9712c20fSFrederick Mayle. 91*9712c20fSFrederick Mayle@end 92*9712c20fSFrederick Mayle``` 93*9712c20fSFrederick Mayle 94*9712c20fSFrederick MayleInside your object's implementation file, 95*9712c20fSFrederick Mayle 96*9712c20fSFrederick Mayle1. add the following method InitBreakpad 97*9712c20fSFrederick Mayle2. modify your awakeFromNib method to look like the one below, 98*9712c20fSFrederick Mayle3. modify/add your application's delegate method to look like the one below 99*9712c20fSFrederick Mayle 100*9712c20fSFrederick Mayle``` 101*9712c20fSFrederick Maylestatic BreakpadRef InitBreakpad(void) { 102*9712c20fSFrederick Mayle NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 103*9712c20fSFrederick Mayle BreakpadRef breakpad = 0; 104*9712c20fSFrederick Mayle NSDictionary *plist = [[NSBundle mainBundle] infoDictionary]; 105*9712c20fSFrederick Mayle if (plist) { 106*9712c20fSFrederick Mayle // Note: version 1.0.0.4 of the framework changed the type of the argument 107*9712c20fSFrederick Mayle // from CFDictionaryRef to NSDictionary * on the next line: 108*9712c20fSFrederick Mayle breakpad = BreakpadCreate(plist); 109*9712c20fSFrederick Mayle } 110*9712c20fSFrederick Mayle [pool release]; 111*9712c20fSFrederick Mayle return breakpad; 112*9712c20fSFrederick Mayle} 113*9712c20fSFrederick Mayle 114*9712c20fSFrederick Mayle- (void)awakeFromNib { 115*9712c20fSFrederick Mayle breakpad = InitBreakpad(); 116*9712c20fSFrederick Mayle} 117*9712c20fSFrederick Mayle 118*9712c20fSFrederick Mayle- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { 119*9712c20fSFrederick Mayle BreakpadRelease(breakpad); 120*9712c20fSFrederick Mayle return NSTerminateNow; 121*9712c20fSFrederick Mayle} 122*9712c20fSFrederick Mayle``` 123*9712c20fSFrederick Mayle 124*9712c20fSFrederick Mayle## Configure Breakpad 125*9712c20fSFrederick Mayle 126*9712c20fSFrederick MayleConfigure Breakpad for your application. 127*9712c20fSFrederick Mayle 128*9712c20fSFrederick Mayle1. Take a look inside the Breakpad.framework at the Breakpad.h file for the 129*9712c20fSFrederick Mayle keys, default values, and descriptions to be passed to BreakpadCreate(). 130*9712c20fSFrederick Mayle2. Add/Edit the Breakpad specific entries in the dictionary passed to 131*9712c20fSFrederick Mayle BreakpadCreate() -- typically your application's info plist. 132*9712c20fSFrederick Mayle 133*9712c20fSFrederick MayleExample from the Notifier Info.plist: 134*9712c20fSFrederick Mayle`<key>BreakpadProduct</key><string>Google_Notifier_Mac</string> 135*9712c20fSFrederick Mayle<key>BreakpadProductDisplay</key><string>${PRODUCT_NAME}</string> 136*9712c20fSFrederick Mayle` 137*9712c20fSFrederick Mayle 138*9712c20fSFrederick Mayle## Build Your Application 139*9712c20fSFrederick Mayle 140*9712c20fSFrederick MayleAlmost done! 141*9712c20fSFrederick Mayle 142*9712c20fSFrederick Mayle## Verify 143*9712c20fSFrederick Mayle 144*9712c20fSFrederick MayleDouble-check: 145*9712c20fSFrederick Mayle 146*9712c20fSFrederick MayleYour app should have in its package contents: 147*9712c20fSFrederick MaylemyApp.app/Contents/Frameworks/Breakpad.framework. 148*9712c20fSFrederick Mayle 149*9712c20fSFrederick MayleThe symbol files have reasonable contents (you can look at them with a text 150*9712c20fSFrederick Mayleeditor.) 151*9712c20fSFrederick Mayle 152*9712c20fSFrederick MayleLook again at the Copy Frameworks phase of your project. Are you leaking .h 153*9712c20fSFrederick Maylefiles? Select them and delete them. (If you drag a bunch of files into your 154*9712c20fSFrederick Mayleproject, Xcode often wants to copy your .h files into the build, revealing 155*9712c20fSFrederick MayleGoogle secrets. Be vigilant!) 156*9712c20fSFrederick Mayle 157*9712c20fSFrederick Mayle## Upload the symbol file 158*9712c20fSFrederick Mayle 159*9712c20fSFrederick MayleYou'll need to configure your build process to store symbols in a location that 160*9712c20fSFrederick Mayleis accessible by the minidump processor. There is a tool in tools/mac/symupload 161*9712c20fSFrederick Maylethat can be used to send the symbol file via HTTP post. 162*9712c20fSFrederick Mayle 163*9712c20fSFrederick Mayle1. Test 164*9712c20fSFrederick Mayle 165*9712c20fSFrederick MayleConfigure breakpad to send reports to a URL by adding to your app's Info.plist: 166*9712c20fSFrederick Mayle 167*9712c20fSFrederick Mayle``` 168*9712c20fSFrederick Mayle<key>BreakpadURL</key> 169*9712c20fSFrederick Mayle<string>upload URL</string> 170*9712c20fSFrederick Mayle<key>BreakpadReportInterval</key> 171*9712c20fSFrederick Mayle<string>30</string> 172*9712c20fSFrederick Mayle``` 173*9712c20fSFrederick Mayle 174*9712c20fSFrederick Mayle## Final Notes 175*9712c20fSFrederick Mayle 176*9712c20fSFrederick MayleBreakpad checks whether it is being run under a debugger, and if so, normally 177*9712c20fSFrederick Mayledoes nothing. But, you can force Breakpad to function under a debugger by 178*9712c20fSFrederick Maylesetting the Unix shell variable BREAKPAD\_IGNORE\_DEBUGGER to a non-zero value. 179*9712c20fSFrederick MayleYou can bracket the source code in the above Write The Code step with #if DEBUG 180*9712c20fSFrederick Mayleto completely eliminate it from Debug builds. See 181*9712c20fSFrederick Mayle//depot/googlemac/GoogleNotifier/main.m for an example. FYI, when your process 182*9712c20fSFrederick Mayleforks(), exception handlers are reset to the default for child processes. So 183*9712c20fSFrederick Maylethey must reinitialize Breakpad, otherwise exceptions will be handled by Apple's 184*9712c20fSFrederick MayleCrash Reporter. 185