diff --git a/toolkit/crashreporter/mac_utils.h b/toolkit/crashreporter/mac_utils.h index 7c67c847c428..5a7c8af20c52 100644 --- a/toolkit/crashreporter/mac_utils.h +++ b/toolkit/crashreporter/mac_utils.h @@ -38,10 +38,15 @@ #ifndef toolkit_breakpad_mac_utils_h__ #define toolkit_breakpad_mac_utils_h__ +#include "nsStringGlue.h" + /* * Look up a setting in our user defaults indicating * that the user wants to see the OS crash reporting dialog. */ bool PassToOSCrashReporter(); +// Given an Objective-C NSException object, put exception info into a string. +void GetObjCExceptionInfo(void* inException, nsACString& outString); + #endif /* toolkit_breakpad_mac_utils_h__ */ diff --git a/toolkit/crashreporter/mac_utils.mm b/toolkit/crashreporter/mac_utils.mm index 10fed6742c93..c3ad093ce1fa 100644 --- a/toolkit/crashreporter/mac_utils.mm +++ b/toolkit/crashreporter/mac_utils.mm @@ -20,6 +20,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Josh Aas * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -39,6 +40,7 @@ #include "mac_utils.h" #include "nsObjCExceptions.h" +#include "nsXPCOM.h" bool PassToOSCrashReporter() { @@ -53,3 +55,35 @@ bool PassToOSCrashReporter() NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(false); } + +void GetObjCExceptionInfo(void* inException, nsACString& outString) +{ + NSException* e = (NSException*)inException; + + NSString* name = [e name]; + NSString* reason = [e reason]; + unsigned int nameLength = [name length]; + unsigned int reasonLength = [reason length]; + + unichar* nameBuffer = (unichar*)NS_Alloc(sizeof(unichar) * (nameLength + 1)); + if (!nameBuffer) + return; + unichar* reasonBuffer = (unichar*)NS_Alloc(sizeof(unichar) * (reasonLength + 1)); + if (!reasonBuffer) { + NS_Free(nameBuffer); + return; + } + + [name getCharacters:nameBuffer]; + [reason getCharacters:reasonBuffer]; + nameBuffer[nameLength] = '\0'; + reasonBuffer[reasonLength] = '\0'; + + outString.AssignLiteral("\nObj-C Exception data:\n"); + AppendUTF16toUTF8(nameBuffer, outString); + outString.AppendLiteral(": "); + AppendUTF16toUTF8(reasonBuffer, outString); + + NS_Free(nameBuffer); + NS_Free(reasonBuffer); +} diff --git a/toolkit/crashreporter/nsExceptionHandler.cpp b/toolkit/crashreporter/nsExceptionHandler.cpp index 89002b852da4..be4c5b91b158 100755 --- a/toolkit/crashreporter/nsExceptionHandler.cpp +++ b/toolkit/crashreporter/nsExceptionHandler.cpp @@ -20,6 +20,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Josh Aas * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -885,4 +886,14 @@ nsresult WriteMinidumpForException(EXCEPTION_POINTERS* aExceptionInfo) } #endif +#ifdef XP_MACOSX +nsresult AppendObjCExceptionInfoToAppNotes(void *inException) +{ + nsCAutoString excString; + GetObjCExceptionInfo(inException, excString); + AppendAppNotesToCrashReport(excString); + return NS_OK; +} +#endif + } // namespace CrashReporter diff --git a/toolkit/crashreporter/nsExceptionHandler.h b/toolkit/crashreporter/nsExceptionHandler.h index fd02d91f9ed4..942367f777c7 100644 --- a/toolkit/crashreporter/nsExceptionHandler.h +++ b/toolkit/crashreporter/nsExceptionHandler.h @@ -62,6 +62,9 @@ nsresult SetupExtraData(nsILocalFile* aAppDataDirectory, #ifdef XP_WIN32 nsresult WriteMinidumpForException(EXCEPTION_POINTERS* aExceptionInfo); #endif +#ifdef XP_MACOSX + nsresult AppendObjCExceptionInfoToAppNotes(void *inException); +#endif } #endif /* nsExceptionHandler_h__ */ diff --git a/toolkit/xre/MacLaunchHelper.h b/toolkit/xre/MacLaunchHelper.h index 7959d2eee7e4..d29fb5398f63 100644 --- a/toolkit/xre/MacLaunchHelper.h +++ b/toolkit/xre/MacLaunchHelper.h @@ -39,12 +39,8 @@ #ifndef __MacLaunchHelper_h__ #define __MacLaunchHelper_h__ -#ifdef __cplusplus extern "C" { -#endif void LaunchChildMac(int aArgc, char** aArgv); -#ifdef __cplusplus } -#endif #endif diff --git a/toolkit/xre/MacLaunchHelper.m b/toolkit/xre/MacLaunchHelper.mm similarity index 99% rename from toolkit/xre/MacLaunchHelper.m rename to toolkit/xre/MacLaunchHelper.mm index 8bf9000f9534..868aa73252d3 100644 --- a/toolkit/xre/MacLaunchHelper.m +++ b/toolkit/xre/MacLaunchHelper.mm @@ -93,4 +93,3 @@ void LaunchChildMac(int aArgc, char** aArgv) NS_OBJC_END_TRY_ABORT_BLOCK; } - diff --git a/toolkit/xre/Makefile.in b/toolkit/xre/Makefile.in index 44c47e5cee2e..85039fbe1fab 100644 --- a/toolkit/xre/Makefile.in +++ b/toolkit/xre/Makefile.in @@ -152,8 +152,8 @@ endif endif endif -ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT))) -CMSRCS = MacLaunchHelper.m +ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa) +CMMSRCS += MacLaunchHelper.mm CPPSRCS += nsCommandLineServiceMac.cpp LOCAL_INCLUDES += -I$(topsrcdir)/xpfe/bootstrap/appleevents OS_CXXFLAGS += -fexceptions diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index d58c53ddb554..b982bb97194f 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -860,6 +860,16 @@ nsXULAppInfo::WriteMinidumpForException(void* aExceptionInfo) } #endif +NS_IMETHODIMP +nsXULAppInfo::AppendObjCExceptionInfoToAppNotes(void* aException) +{ +#ifdef XP_MACOSX + return CrashReporter::AppendObjCExceptionInfoToAppNotes(aException); +#else + return NS_ERROR_NOT_IMPLEMENTED; +#endif +} + static const nsXULAppInfo kAppInfo; static NS_METHOD AppInfoConstructor(nsISupports* aOuter, REFNSIID aIID, void **aResult) diff --git a/xpcom/base/nsObjCExceptions.h b/xpcom/base/nsObjCExceptions.h index d7be453aa934..8dbbcb098db2 100644 --- a/xpcom/base/nsObjCExceptions.h +++ b/xpcom/base/nsObjCExceptions.h @@ -46,6 +46,12 @@ #import #endif +#if defined(MOZ_CRASHREPORTER) && defined(__cplusplus) +#include "nsICrashReporter.h" +#include "nsCOMPtr.h" +#include "nsServiceManagerUtils.h" +#endif + #include #include #include "nsError.h" @@ -58,6 +64,14 @@ static void nsObjCExceptionLog(NSException* aException) NSLog(@"Mozilla has caught an Obj-C exception [%@: %@]", [aException name], [aException reason]); +#if defined(MOZ_CRASHREPORTER) && defined(__cplusplus) + // Attach exception info to the crash report. + nsCOMPtr crashReporter = + do_GetService("@mozilla.org/toolkit/crash-reporter;1"); + if (crashReporter) + crashReporter->AppendObjCExceptionInfoToAppNotes(static_cast(aException)); +#endif + #ifdef DEBUG @try { // Try to get stack information out of the exception. 10.5 returns the stack diff --git a/xpcom/system/nsICrashReporter.idl b/xpcom/system/nsICrashReporter.idl index a13bf248e00c..98df15d22bcf 100644 --- a/xpcom/system/nsICrashReporter.idl +++ b/xpcom/system/nsICrashReporter.idl @@ -43,7 +43,7 @@ * future releases. */ -[scriptable, uuid(189c9392-157c-445f-84db-900eb46d4839)] +[scriptable, uuid(D9A0F5B2-A7DF-4AEB-9775-21B9E01B4C59)] interface nsICrashReporter : nsISupports { /** @@ -79,5 +79,11 @@ interface nsICrashReporter : nsISupports * SEH (structured exception handling) exists on Windows only. * @param aExceptionInfo EXCEPTION_INFO* provided by Window's SEH */ - [noscript] void WriteMinidumpForException(in voidPtr aExceptionInfo); + [noscript] void writeMinidumpForException(in voidPtr aExceptionInfo); + + /** + * Append note containing an Obj-C exception's info. + * @param aException NSException object to append note for + */ + [noscript] void appendObjCExceptionInfoToAppNotes(in voidPtr aException); };