// Copyright (c) 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//


#define IGNORE_DEBUGGER "BREAKPAD_IGNORE_DEBUGGER"

#import "client/mac/Framework/Breakpad.h"

#include <assert.h>
#import <Foundation/Foundation.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/sysctl.h>

#import "client/mac/crash_generation/Inspector.h"
#import "client/mac/handler/exception_handler.h"
#import "client/mac/Framework/Breakpad.h"
#import "client/mac/Framework/OnDemandServer.h"
#import "client/mac/handler/protected_memory_allocator.h"
#import "common/mac/MachIPC.h"
#import "common/simple_string_dictionary.h"

#ifndef __EXCEPTIONS
// This file uses C++ try/catch (but shouldn't). Duplicate the macros from
// <c++/4.2.1/exception_defines.h> allowing this file to work properly with
// exceptions disabled even when other C++ libraries are used. #undef the try
// and catch macros first in case libstdc++ is in use and has already provided
// its own definitions.
#undef try
#define try       if (true)
#undef catch
#define catch(X)  if (false)
#endif  // __EXCEPTIONS

using google_breakpad::MachPortSender;
using google_breakpad::MachReceiveMessage;
using google_breakpad::MachSendMessage;
using google_breakpad::ReceivePort;
using google_breakpad::SimpleStringDictionary;

//=============================================================================
// We want any memory allocations which are used by breakpad during the
// exception handling process (after a crash has happened) to be read-only
// to prevent them from being smashed before a crash occurs.  Unfortunately
// we cannot protect against smashes to our exception handling thread's
// stack.
//
// NOTE: Any memory allocations which are not used during the exception
// handling process may be allocated in the normal ways.
//
// The ProtectedMemoryAllocator class provides an Allocate() method which
// we'll using in conjunction with placement operator new() to control
// allocation of C++ objects.  Note that we don't use operator delete()
// but instead call the objects destructor directly:  object->~ClassName();
//
ProtectedMemoryAllocator *gMasterAllocator = NULL;
ProtectedMemoryAllocator *gKeyValueAllocator = NULL;
ProtectedMemoryAllocator *gBreakpadAllocator = NULL;

// Mutex for thread-safe access to the key/value dictionary used by breakpad.
// It's a global instead of an instance variable of Breakpad
// since it can't live in a protected memory area.
pthread_mutex_t gDictionaryMutex;

//=============================================================================
// Stack-based object for thread-safe access to a memory-protected region.
// It's assumed that normally the memory block (allocated by the allocator)
// is protected (read-only).  Creating a stack-based instance of
// ProtectedMemoryLocker will unprotect this block after taking the lock.
// Its destructor will first re-protect the memory then release the lock.
class ProtectedMemoryLocker {
 public:
  ProtectedMemoryLocker(pthread_mutex_t *mutex,
                        ProtectedMemoryAllocator *allocator)
      : mutex_(mutex),
        allocator_(allocator) {
    // Lock the mutex
    __attribute__((unused)) int rv = pthread_mutex_lock(mutex_);
    assert(rv == 0);

    // Unprotect the memory
    allocator_->Unprotect();
  }

  ~ProtectedMemoryLocker() {
    // First protect the memory
    allocator_->Protect();

    // Then unlock the mutex
    __attribute__((unused)) int rv = pthread_mutex_unlock(mutex_);
    assert(rv == 0);
  };

 private:
  ProtectedMemoryLocker();
  ProtectedMemoryLocker(const ProtectedMemoryLocker&);
  ProtectedMemoryLocker& operator=(const ProtectedMemoryLocker&);

  pthread_mutex_t           *mutex_;
  ProtectedMemoryAllocator  *allocator_;
};

//=============================================================================
class Breakpad {
 public:
  // factory method
  static Breakpad *Create(NSDictionary *parameters) {
    // Allocate from our special allocation pool
    Breakpad *breakpad =
      new (gBreakpadAllocator->Allocate(sizeof(Breakpad)))
        Breakpad();

    if (!breakpad)
      return NULL;

    if (!breakpad->Initialize(parameters)) {
      // Don't use operator delete() here since we allocated from special pool
      breakpad->~Breakpad();
      return NULL;
    }

    return breakpad;
  }

  ~Breakpad();

  void SetKeyValue(NSString *key, NSString *value);
  NSString *KeyValue(NSString *key);
  void RemoveKeyValue(NSString *key);

  void GenerateAndSendReport();

  void SetFilterCallback(BreakpadFilterCallback callback, void *context) {
    filter_callback_ = callback;
    filter_callback_context_ = context;
  }

 private:
  Breakpad()
    : handler_(NULL),
      config_params_(NULL),
      send_and_exit_(true),
      filter_callback_(NULL),
      filter_callback_context_(NULL) {
    inspector_path_[0] = 0;
  }

  bool Initialize(NSDictionary *parameters);

  bool ExtractParameters(NSDictionary *parameters);

  // Dispatches to HandleException()
  static bool ExceptionHandlerDirectCallback(void *context,
                                             int exception_type,
                                             int exception_code,
                                             int exception_subcode,
                                             mach_port_t crashing_thread);

  bool HandleException(int exception_type,
                       int exception_code,
                       int exception_subcode,
                       mach_port_t crashing_thread);

  // Since ExceptionHandler (w/o namespace) is defined as typedef in OSX's
  // MachineExceptions.h, we have to explicitly name the handler.
  google_breakpad::ExceptionHandler *handler_; // The actual handler (STRONG)

  char                    inspector_path_[PATH_MAX];  // Path to inspector tool

  SimpleStringDictionary  *config_params_; // Create parameters (STRONG)

  OnDemandServer          inspector_;

  bool                    send_and_exit_;  // Exit after sending, if true

  BreakpadFilterCallback  filter_callback_;
  void                    *filter_callback_context_;
};

#pragma mark -
#pragma mark Helper functions

//=============================================================================
// Helper functions

//=============================================================================
static BOOL IsDebuggerActive() {
  BOOL result = NO;
  NSUserDefaults *stdDefaults = [NSUserDefaults standardUserDefaults];

  // We check both defaults and the environment variable here

  BOOL ignoreDebugger = [stdDefaults boolForKey:@IGNORE_DEBUGGER];

  if (!ignoreDebugger) {
    char *ignoreDebuggerStr = getenv(IGNORE_DEBUGGER);
    ignoreDebugger = (ignoreDebuggerStr ? strtol(ignoreDebuggerStr, NULL, 10) : 0) != 0;
  }

  if (!ignoreDebugger) {
    pid_t pid = getpid();
    int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
    int mibSize = sizeof(mib) / sizeof(int);
    size_t actualSize;

    if (sysctl(mib, mibSize, NULL, &actualSize, NULL, 0) == 0) {
      struct kinfo_proc *info = (struct kinfo_proc *)malloc(actualSize);

      if (info) {
        // This comes from looking at the Darwin xnu Kernel
        if (sysctl(mib, mibSize, info, &actualSize, NULL, 0) == 0)
          result = (info->kp_proc.p_flag & P_TRACED) ? YES : NO;

        free(info);
      }
    }
  }

  return result;
}

//=============================================================================
bool Breakpad::ExceptionHandlerDirectCallback(void *context,
                                                    int exception_type,
                                                    int exception_code,
                                                    int exception_subcode,
                                                    mach_port_t crashing_thread) {
  Breakpad *breakpad = (Breakpad *)context;

  // If our context is damaged or something, just return false to indicate that
  // the handler should continue without us.
  if (!breakpad)
    return false;

  return breakpad->HandleException( exception_type,
                                    exception_code,
                                    exception_subcode,
                                    crashing_thread);
}

//=============================================================================
#pragma mark -

#include <dlfcn.h>

//=============================================================================
// Returns the pathname to the Resources directory for this version of
// Breakpad which we are now running.
//
// Don't make the function static, since _dyld_lookup_and_bind_fully needs a
// simple non-static C name
//
extern "C" {
NSString * GetResourcePath();
NSString * GetResourcePath() {
  NSString *resourcePath = nil;

  // If there are multiple breakpads installed then calling bundleWithIdentifier
  // will not work properly, so only use that as a backup plan.
  // We want to find the bundle containing the code where this function lives
  // and work from there
  //

  // Get the pathname to the code which contains this function
  Dl_info info;
  if (dladdr((const void*)GetResourcePath, &info) != 0) {
    NSFileManager *filemgr = [NSFileManager defaultManager];
    NSString *filePath =
        [filemgr stringWithFileSystemRepresentation:info.dli_fname
                                             length:strlen(info.dli_fname)];
    NSString *bundlePath = [filePath stringByDeletingLastPathComponent];
    // The "Resources" directory should be in the same directory as the
    // executable code, since that's how the Breakpad framework is built.
    resourcePath = [bundlePath stringByAppendingPathComponent:@"Resources/"];
  } else {
    // fallback plan
    NSBundle *bundle =
        [NSBundle bundleWithIdentifier:@"com.Google.BreakpadFramework"];
    resourcePath = [bundle resourcePath];
  }

  return resourcePath;
}
}  // extern "C"

//=============================================================================
bool Breakpad::Initialize(NSDictionary *parameters) {
  // Initialize
  config_params_ = NULL;
  handler_ = NULL;

  // Check for debugger
  if (IsDebuggerActive()) {
    return true;
  }

  // Gather any user specified parameters
  if (!ExtractParameters(parameters)) {
    return false;
  }

  // Get path to Inspector executable.
  NSString *inspectorPathString = KeyValue(@BREAKPAD_INSPECTOR_LOCATION);

  // Standardize path (resolve symlinkes, etc.)  and escape spaces
  inspectorPathString = [inspectorPathString stringByStandardizingPath];
  inspectorPathString = [[inspectorPathString componentsSeparatedByString:@" "]
                                              componentsJoinedByString:@"\\ "];

  // Create an on-demand server object representing the Inspector.
  // In case of a crash, we simply need to call the LaunchOnDemand()
  // method on it, then send a mach message to its service port.
  // It will then launch and perform a process inspection of our crashed state.
  // See the HandleException() method for the details.
#define RECEIVE_PORT_NAME "com.Breakpad.Inspector"

  name_t portName;
  snprintf(portName, sizeof(name_t),  "%s%d", RECEIVE_PORT_NAME, getpid());

  // Save the location of the Inspector
  strlcpy(inspector_path_, [inspectorPathString fileSystemRepresentation],
          sizeof(inspector_path_));

  // Append a single command-line argument to the Inspector path
  // representing the bootstrap name of the launch-on-demand receive port.
  // When the Inspector is launched, it can use this to lookup the port
  // by calling bootstrap_check_in().
  strlcat(inspector_path_, " ", sizeof(inspector_path_));
  strlcat(inspector_path_, portName, sizeof(inspector_path_));

  kern_return_t kr = inspector_.Initialize(inspector_path_,
                                           portName,
                                           true);        // shutdown on exit

  if (kr != KERN_SUCCESS) {
    return false;
  }

  // Create the handler (allocating it in our special protected pool)
  handler_ =
      new (gBreakpadAllocator->Allocate(
          sizeof(google_breakpad::ExceptionHandler)))
          google_breakpad::ExceptionHandler(
              Breakpad::ExceptionHandlerDirectCallback, this, true);
  return true;
}

//=============================================================================
Breakpad::~Breakpad() {
  // Note that we don't use operator delete() on these pointers,
  // since they were allocated by ProtectedMemoryAllocator objects.
  //
  if (config_params_) {
    config_params_->~SimpleStringDictionary();
  }

  if (handler_)
    handler_->~ExceptionHandler();
}

//=============================================================================
bool Breakpad::ExtractParameters(NSDictionary *parameters) {
  NSUserDefaults *stdDefaults = [NSUserDefaults standardUserDefaults];
  NSString *skipConfirm = [stdDefaults stringForKey:@BREAKPAD_SKIP_CONFIRM];
  NSString *sendAndExit = [stdDefaults stringForKey:@BREAKPAD_SEND_AND_EXIT];

  NSString *serverType = [parameters objectForKey:@BREAKPAD_SERVER_TYPE];
  NSString *display = [parameters objectForKey:@BREAKPAD_PRODUCT_DISPLAY];
  NSString *product = [parameters objectForKey:@BREAKPAD_PRODUCT];
  NSString *version = [parameters objectForKey:@BREAKPAD_VERSION];
  NSString *urlStr = [parameters objectForKey:@BREAKPAD_URL];
  NSString *interval = [parameters objectForKey:@BREAKPAD_REPORT_INTERVAL];
  NSString *inspectorPathString =
      [parameters objectForKey:@BREAKPAD_INSPECTOR_LOCATION];
  NSString *reporterPathString =
      [parameters objectForKey:@BREAKPAD_REPORTER_EXE_LOCATION];
  NSString *timeout = [parameters objectForKey:@BREAKPAD_CONFIRM_TIMEOUT];
  NSArray  *logFilePaths = [parameters objectForKey:@BREAKPAD_LOGFILES];
  NSString *logFileTailSize =
      [parameters objectForKey:@BREAKPAD_LOGFILE_UPLOAD_SIZE];
  NSString *requestUserText =
      [parameters objectForKey:@BREAKPAD_REQUEST_COMMENTS];
  NSString *requestEmail = [parameters objectForKey:@BREAKPAD_REQUEST_EMAIL];
  NSString *vendor =
      [parameters objectForKey:@BREAKPAD_VENDOR];
  NSString *dumpSubdirectory =
      [parameters objectForKey:@BREAKPAD_DUMP_DIRECTORY];

  NSDictionary *serverParameters =
      [parameters objectForKey:@BREAKPAD_SERVER_PARAMETER_DICT];

  // These may have been set above as user prefs, which take priority.
  if (!skipConfirm) {
    skipConfirm = [parameters objectForKey:@BREAKPAD_SKIP_CONFIRM];
  }
  if (!sendAndExit) {
    sendAndExit = [parameters objectForKey:@BREAKPAD_SEND_AND_EXIT];
  }

  if (!product)
    product = [parameters objectForKey:@"CFBundleName"];

  if (!display) {
    display = [parameters objectForKey:@"CFBundleDisplayName"];
    if (!display) {
      display = product;
    }
  }

  if (!version)
    version = [parameters objectForKey:@"CFBundleVersion"];

  if (!interval)
    interval = @"3600";

  if (!timeout)
    timeout = @"300";

  if (!logFileTailSize)
    logFileTailSize = @"200000";

  if (!vendor) {
    vendor = @"Vendor not specified";
  }

  // Normalize the values.
  if (skipConfirm) {
    skipConfirm = [skipConfirm uppercaseString];

    if ([skipConfirm isEqualToString:@"YES"] ||
        [skipConfirm isEqualToString:@"TRUE"] ||
        [skipConfirm isEqualToString:@"1"])
      skipConfirm = @"YES";
    else
      skipConfirm = @"NO";
  } else {
    skipConfirm = @"NO";
  }

  send_and_exit_ = true;
  if (sendAndExit) {
    sendAndExit = [sendAndExit uppercaseString];

    if ([sendAndExit isEqualToString:@"NO"] ||
        [sendAndExit isEqualToString:@"FALSE"] ||
        [sendAndExit isEqualToString:@"0"])
      send_and_exit_ = false;
  }

  if (requestUserText) {
    requestUserText = [requestUserText uppercaseString];

    if ([requestUserText isEqualToString:@"YES"] ||
        [requestUserText isEqualToString:@"TRUE"] ||
        [requestUserText isEqualToString:@"1"])
      requestUserText = @"YES";
    else
      requestUserText = @"NO";
  } else {
    requestUserText = @"NO";
  }

  // Find the helper applications if not specified in user config.
  NSString *resourcePath = nil;
  if (!inspectorPathString || !reporterPathString) {
    resourcePath = GetResourcePath();
    if (!resourcePath) {
      return false;
    }
  }

  // Find Inspector.
  if (!inspectorPathString) {
    inspectorPathString =
        [resourcePath stringByAppendingPathComponent:@"Inspector"];
  }

  // Verify that there is an Inspector tool.
  if (![[NSFileManager defaultManager] fileExistsAtPath:inspectorPathString]) {
    return false;
  }

  // Find Reporter.
  if (!reporterPathString) {
    reporterPathString =
        [resourcePath
         stringByAppendingPathComponent:@"crash_report_sender.app"];
    reporterPathString =
        [[NSBundle bundleWithPath:reporterPathString] executablePath];
  }

  // Verify that there is a Reporter application.
  if (![[NSFileManager defaultManager]
             fileExistsAtPath:reporterPathString]) {
    return false;
  }

  if (!dumpSubdirectory) {
    dumpSubdirectory = @"";
  }

  // The product, version, and URL are required values.
  if (![product length]) {
    return false;
  }

  if (![version length]) {
    return false;
  }

  if (![urlStr length]) {
    return false;
  }

  config_params_ =
      new (gKeyValueAllocator->Allocate(sizeof(SimpleStringDictionary)) )
        SimpleStringDictionary();

  SimpleStringDictionary &dictionary = *config_params_;

  dictionary.SetKeyValue(BREAKPAD_SERVER_TYPE,     [serverType UTF8String]);
  dictionary.SetKeyValue(BREAKPAD_PRODUCT_DISPLAY, [display UTF8String]);
  dictionary.SetKeyValue(BREAKPAD_PRODUCT,         [product UTF8String]);
  dictionary.SetKeyValue(BREAKPAD_VERSION,         [version UTF8String]);
  dictionary.SetKeyValue(BREAKPAD_URL,             [urlStr UTF8String]);
  dictionary.SetKeyValue(BREAKPAD_REPORT_INTERVAL, [interval UTF8String]);
  dictionary.SetKeyValue(BREAKPAD_SKIP_CONFIRM,    [skipConfirm UTF8String]);
  dictionary.SetKeyValue(BREAKPAD_CONFIRM_TIMEOUT, [timeout UTF8String]);
  dictionary.SetKeyValue(BREAKPAD_INSPECTOR_LOCATION,
                         [inspectorPathString fileSystemRepresentation]);
  dictionary.SetKeyValue(BREAKPAD_REPORTER_EXE_LOCATION,
                         [reporterPathString fileSystemRepresentation]);
  dictionary.SetKeyValue(BREAKPAD_LOGFILE_UPLOAD_SIZE,
                         [logFileTailSize UTF8String]);
  dictionary.SetKeyValue(BREAKPAD_REQUEST_COMMENTS,
                         [requestUserText UTF8String]);
  dictionary.SetKeyValue(BREAKPAD_REQUEST_EMAIL, [requestEmail UTF8String]);
  dictionary.SetKeyValue(BREAKPAD_VENDOR, [vendor UTF8String]);
  dictionary.SetKeyValue(BREAKPAD_DUMP_DIRECTORY,
                         [dumpSubdirectory UTF8String]);

  struct timeval tv;
  gettimeofday(&tv, NULL);
  char timeStartedString[32];
  sprintf(timeStartedString, "%zd", tv.tv_sec);
  dictionary.SetKeyValue(BREAKPAD_PROCESS_START_TIME,
                         timeStartedString);

  if (logFilePaths) {
    char logFileKey[255];
    for(unsigned int i = 0; i < [logFilePaths count]; i++) {
      sprintf(logFileKey,"%s%d", BREAKPAD_LOGFILE_KEY_PREFIX, i);
      dictionary.SetKeyValue(logFileKey,
                             [[logFilePaths objectAtIndex:i]
                               fileSystemRepresentation]);
    }
  }

  if (serverParameters) {
    // For each key-value pair, call BreakpadAddUploadParameter()
    NSEnumerator *keyEnumerator = [serverParameters keyEnumerator];
    NSString *aParameter;
    while ((aParameter = [keyEnumerator nextObject])) {
      BreakpadAddUploadParameter(this, aParameter,
				 [serverParameters objectForKey:aParameter]);
    }
  }
  return true;
}

//=============================================================================
void Breakpad::SetKeyValue(NSString *key, NSString *value) {
  // We allow nil values. This is the same as removing the keyvalue.
  if (!config_params_ || !key)
    return;

  config_params_->SetKeyValue([key UTF8String], [value UTF8String]);
}

//=============================================================================
NSString *Breakpad::KeyValue(NSString *key) {
  if (!config_params_ || !key)
    return nil;

  const char *value = config_params_->GetValueForKey([key UTF8String]);
  return value ? [NSString stringWithUTF8String:value] : nil;
}

//=============================================================================
void Breakpad::RemoveKeyValue(NSString *key) {
  if (!config_params_ || !key) return;

  config_params_->RemoveKey([key UTF8String]);
}

//=============================================================================
void Breakpad::GenerateAndSendReport() {
  config_params_->SetKeyValue(BREAKPAD_ON_DEMAND, "YES");
  HandleException(0, 0, 0, mach_thread_self());
  config_params_->SetKeyValue(BREAKPAD_ON_DEMAND, "NO");
}

//=============================================================================
bool Breakpad::HandleException(int exception_type,
                               int exception_code,
                               int exception_subcode,
                               mach_port_t crashing_thread) {
  if (filter_callback_) {
    bool should_handle = filter_callback_(exception_type,
                                          exception_code,
                                          crashing_thread,
                                          filter_callback_context_);
    if (!should_handle) return false;
  }

  // We need to reset the memory protections to be read/write,
  // since LaunchOnDemand() requires changing state.
  gBreakpadAllocator->Unprotect();
  // Configure the server to launch when we message the service port.
  // The reason we do this here, rather than at startup, is that we
  // can leak a bootstrap service entry if this method is called and
  // there never ends up being a crash.
  inspector_.LaunchOnDemand();
  gBreakpadAllocator->Protect();

  // The Inspector should send a message to this port to verify it
  // received our information and has finished the inspection.
  ReceivePort acknowledge_port;

  // Send initial information to the Inspector.
  MachSendMessage message(kMsgType_InspectorInitialInfo);
  message.AddDescriptor(mach_task_self());          // our task
  message.AddDescriptor(crashing_thread);           // crashing thread
  message.AddDescriptor(mach_thread_self());        // exception-handling thread
  message.AddDescriptor(acknowledge_port.GetPort());// message receive port

  InspectorInfo info;
  info.exception_type = exception_type;
  info.exception_code = exception_code;
  info.exception_subcode = exception_subcode;
  info.parameter_count = config_params_->GetCount();
  message.SetData(&info, sizeof(info));

  MachPortSender sender(inspector_.GetServicePort());

  kern_return_t result = sender.SendMessage(message, 2000);

  if (result == KERN_SUCCESS) {
    // Now, send a series of key-value pairs to the Inspector.
    const SimpleStringDictionary::Entry *entry = NULL;
    SimpleStringDictionary::Iterator iter(*config_params_);

    while ( (entry = iter.Next()) ) {
      KeyValueMessageData keyvalue_data(*entry);

      MachSendMessage keyvalue_message(kMsgType_InspectorKeyValuePair);
      keyvalue_message.SetData(&keyvalue_data, sizeof(keyvalue_data));

      result = sender.SendMessage(keyvalue_message, 2000);

      if (result != KERN_SUCCESS) {
        break;
      }
    }

    if (result == KERN_SUCCESS) {
      // Wait for acknowledgement that the inspection has finished.
      MachReceiveMessage acknowledge_messsage;
      result = acknowledge_port.WaitForMessage(&acknowledge_messsage, 5000);
    }
  }

#if VERBOSE
  PRINT_MACH_RESULT(result, "Breakpad: SendMessage ");
  printf("Breakpad: Inspector service port = %#x\n",
    inspector_.GetServicePort());
#endif

  // If we don't want any forwarding, return true here to indicate that we've
  // processed things as much as we want.
  if (send_and_exit_) return true;

  return false;
}

//=============================================================================
//=============================================================================

#pragma mark -
#pragma mark Public API

//=============================================================================
BreakpadRef BreakpadCreate(NSDictionary *parameters) {
  try {
    // This is confusing.  Our two main allocators for breakpad memory are:
    //    - gKeyValueAllocator for the key/value memory
    //    - gBreakpadAllocator for the Breakpad, ExceptionHandler, and other
    //      breakpad allocations which are accessed at exception handling time.
    //
    // But in order to avoid these two allocators themselves from being smashed,
    // we'll protect them as well by allocating them with gMasterAllocator.
    //
    // gMasterAllocator itself will NOT be protected, but this doesn't matter,
    // since once it does its allocations and locks the memory, smashes to itself
    // don't affect anything we care about.
    gMasterAllocator =
        new ProtectedMemoryAllocator(sizeof(ProtectedMemoryAllocator) * 2);

    gKeyValueAllocator =
        new (gMasterAllocator->Allocate(sizeof(ProtectedMemoryAllocator)))
            ProtectedMemoryAllocator(sizeof(SimpleStringDictionary));

    // Create a mutex for use in accessing the SimpleStringDictionary
    int mutexResult = pthread_mutex_init(&gDictionaryMutex, NULL);
    if (mutexResult == 0) {

      // With the current compiler, gBreakpadAllocator is allocating 1444 bytes.
      // Let's round up to the nearest page size.
      //
      int breakpad_pool_size = 4096;

      /*
       sizeof(Breakpad)
       + sizeof(google_breakpad::ExceptionHandler)
       + sizeof( STUFF ALLOCATED INSIDE ExceptionHandler )
       */

      gBreakpadAllocator =
          new (gMasterAllocator->Allocate(sizeof(ProtectedMemoryAllocator)))
              ProtectedMemoryAllocator(breakpad_pool_size);

      // Stack-based autorelease pool for Breakpad::Create() obj-c code.
      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
      Breakpad *breakpad = Breakpad::Create(parameters);

      if (breakpad) {
        // Make read-only to protect against memory smashers
        gMasterAllocator->Protect();
        gKeyValueAllocator->Protect();
        gBreakpadAllocator->Protect();
        // Can uncomment this line to figure out how much space was actually
        // allocated using this allocator
        //     printf("gBreakpadAllocator allocated size = %d\n",
        //         gBreakpadAllocator->GetAllocatedSize() );
        [pool release];
        return (BreakpadRef)breakpad;
      }

      [pool release];
    }
  } catch(...) {    // don't let exceptions leave this C API
    fprintf(stderr, "BreakpadCreate() : error\n");
  }

  if (gKeyValueAllocator) {
    gKeyValueAllocator->~ProtectedMemoryAllocator();
    gKeyValueAllocator = NULL;
  }

  if (gBreakpadAllocator) {
    gBreakpadAllocator->~ProtectedMemoryAllocator();
    gBreakpadAllocator = NULL;
  }

  delete gMasterAllocator;
  gMasterAllocator = NULL;

  return NULL;
}

//=============================================================================
void BreakpadRelease(BreakpadRef ref) {
  try {
    Breakpad *breakpad = (Breakpad *)ref;

    if (gMasterAllocator) {
      gMasterAllocator->Unprotect();
      gKeyValueAllocator->Unprotect();
      gBreakpadAllocator->Unprotect();

      breakpad->~Breakpad();

      // Unfortunately, it's not possible to deallocate this stuff
      // because the exception handling thread is still finishing up
      // asynchronously at this point...  OK, it could be done with
      // locks, etc.  But since BreakpadRelease() should usually only
      // be called right before the process exits, it's not worth
      // deallocating this stuff.
#if 0
      gKeyValueAllocator->~ProtectedMemoryAllocator();
      gBreakpadAllocator->~ProtectedMemoryAllocator();
      delete gMasterAllocator;

      gMasterAllocator = NULL;
      gKeyValueAllocator = NULL;
      gBreakpadAllocator = NULL;
#endif

      pthread_mutex_destroy(&gDictionaryMutex);
    }
  } catch(...) {    // don't let exceptions leave this C API
    fprintf(stderr, "BreakpadRelease() : error\n");
  }
}

//=============================================================================
void BreakpadSetKeyValue(BreakpadRef ref, NSString *key, NSString *value) {
  try {
    // Not called at exception time
    Breakpad *breakpad = (Breakpad *)ref;

    if (breakpad && key && gKeyValueAllocator) {
      ProtectedMemoryLocker locker(&gDictionaryMutex, gKeyValueAllocator);

      breakpad->SetKeyValue(key, value);
    }
  } catch(...) {    // don't let exceptions leave this C API
    fprintf(stderr, "BreakpadSetKeyValue() : error\n");
  }
}

void BreakpadAddUploadParameter(BreakpadRef ref,
                                NSString *key,
                                NSString *value) {
  // The only difference, internally, between an upload parameter and
  // a key value one that is set with BreakpadSetKeyValue is that we
  // prepend the keyname with a special prefix.  This informs the
  // crash sender that the parameter should be sent along with the
  // POST of the crash dump upload.
  try {
    Breakpad *breakpad = (Breakpad *)ref;

    if (breakpad && key && gKeyValueAllocator) {
      ProtectedMemoryLocker locker(&gDictionaryMutex, gKeyValueAllocator);

      NSString *prefixedKey = [@BREAKPAD_SERVER_PARAMETER_PREFIX
				stringByAppendingString:key];
      breakpad->SetKeyValue(prefixedKey, value);
    }
  } catch(...) {    // don't let exceptions leave this C API
    fprintf(stderr, "BreakpadSetKeyValue() : error\n");
  }
}

void BreakpadRemoveUploadParameter(BreakpadRef ref,
                                   NSString *key) {
  try {
    // Not called at exception time
    Breakpad *breakpad = (Breakpad *)ref;

    if (breakpad && key && gKeyValueAllocator) {
      ProtectedMemoryLocker locker(&gDictionaryMutex, gKeyValueAllocator);

      NSString *prefixedKey = [NSString stringWithFormat:@"%@%@",
                                        @BREAKPAD_SERVER_PARAMETER_PREFIX, key];
      breakpad->RemoveKeyValue(prefixedKey);
    }
  } catch(...) {    // don't let exceptions leave this C API
    fprintf(stderr, "BreakpadRemoveKeyValue() : error\n");
  }
}
//=============================================================================
NSString *BreakpadKeyValue(BreakpadRef ref, NSString *key) {
  NSString *value = nil;

  try {
    // Not called at exception time
    Breakpad *breakpad = (Breakpad *)ref;

    if (!breakpad || !key || !gKeyValueAllocator)
      return nil;

    ProtectedMemoryLocker locker(&gDictionaryMutex, gKeyValueAllocator);

    value = breakpad->KeyValue(key);
  } catch(...) {    // don't let exceptions leave this C API
    fprintf(stderr, "BreakpadKeyValue() : error\n");
  }

  return value;
}

//=============================================================================
void BreakpadRemoveKeyValue(BreakpadRef ref, NSString *key) {
  try {
    // Not called at exception time
    Breakpad *breakpad = (Breakpad *)ref;

    if (breakpad && key && gKeyValueAllocator) {
      ProtectedMemoryLocker locker(&gDictionaryMutex, gKeyValueAllocator);

      breakpad->RemoveKeyValue(key);
    }
  } catch(...) {    // don't let exceptions leave this C API
    fprintf(stderr, "BreakpadRemoveKeyValue() : error\n");
  }
}

//=============================================================================
void BreakpadGenerateAndSendReport(BreakpadRef ref) {
  try {
    Breakpad *breakpad = (Breakpad *)ref;

    if (breakpad && gKeyValueAllocator) {
      ProtectedMemoryLocker locker(&gDictionaryMutex, gKeyValueAllocator);

      gBreakpadAllocator->Unprotect();
      breakpad->GenerateAndSendReport();
      gBreakpadAllocator->Protect();
    }
  } catch(...) {    // don't let exceptions leave this C API
    fprintf(stderr, "BreakpadGenerateAndSendReport() : error\n");
  }
}

//=============================================================================
void BreakpadSetFilterCallback(BreakpadRef ref,
                               BreakpadFilterCallback callback,
                               void *context) {

  try {
    Breakpad *breakpad = (Breakpad *)ref;

    if (breakpad && gBreakpadAllocator) {
      // share the dictionary mutex here (we really don't need a mutex)
      ProtectedMemoryLocker locker(&gDictionaryMutex, gBreakpadAllocator);

      breakpad->SetFilterCallback(callback, context);
    }
  } catch(...) {    // don't let exceptions leave this C API
    fprintf(stderr, "BreakpadSetFilterCallback() : error\n");
  }
}

//============================================================================
void BreakpadAddLogFile(BreakpadRef ref, NSString *logPathname) {
  int logFileCounter = 0;

  NSString *logFileKey = [NSString stringWithFormat:@"%@%d",
                                   @BREAKPAD_LOGFILE_KEY_PREFIX,
                                   logFileCounter];

  NSString *existingLogFilename = nil;
  existingLogFilename = BreakpadKeyValue(ref, logFileKey);
  // Find the first log file key that we can use by testing for existence
  while (existingLogFilename) {
    if ([existingLogFilename isEqualToString:logPathname]) {
      return;
    }
    logFileCounter++;
    logFileKey = [NSString stringWithFormat:@"%@%d",
                           @BREAKPAD_LOGFILE_KEY_PREFIX,
                           logFileCounter];
    existingLogFilename = BreakpadKeyValue(ref, logFileKey);
  }

  BreakpadSetKeyValue(ref, logFileKey, logPathname);
}
