In a conversation on #macdev, it was pointed out that the Crash Reporter has an “Application Specific Information:” line when certain Apple apps crash. This obviously warranted investigation, and through the powers of Google it was determined that said investigation had in fact happened a few months ago. How fortunate that we didn’t spend time investigating it and writing test cases, only to find someone had already done a better job.
Anyway, this is an entirely unsupported thing to do, and the means of doing it may disappear at any time, so don’t. But if you do, do it cleanly, like this:
#ifndef NDEBUG /* Function to set “Application Specific Information” field in crash reporter log in Leopard. Extremely unsupported, so not used in release builds. */ static void InitCrashReporterInfo(void); static void SetCrashReporterInfo(const char *info); static BOOL sCrashReporterInfoAvailable = NO; #else #define InitCrashReporterInfo() do {} while (0) #define SetCrashReporterInfo(i) do {} while (0) #define sCrashReporterInfoAvailable 0 #endif /* Insert code here. Or make it non-static, depending on what you’re doing. */ #ifndef NDEBUG static char **sCrashReporterInfo = NULL; static char *sOldCrashReporterInfo = NULL; static NSLock *sCrashReporterInfoLock = nil; static void InitCrashReporterInfo(void) { // Load secret symbol __crashreporter_info__; don’t do anything if not found. sCrashReporterInfo = dlsym(RTLD_DEFAULT, "__crashreporter_info__"); if (sCrashReporterInfo != NULL) { // We'll need a lock, too. sCrashReporterInfoLock = [[NSLock alloc] init]; if (sCrashReporterInfoLock != nil) { sCrashReporterInfoAvailable = YES; } else { sCrashReporterInfo = NULL; } } } static void SetCrashReporterInfo(const char *info) { char *copy = NULL, *old = NULL; /* Don’t do anything if setup failed or the string is NULL or empty. (The NULL and empty checks may not be desirable in other uses.) */ if (!sCrashReporterInfoAvailable || info == NULL || *info == '\0') return; // Copy the string, which we assume to be dynamic... copy = strdup(info); if (copy == NULL) return; /* ...and swap it in. Note that we keep a separate pointer to the old value, in case something else overwrites __crashreporter_info__. */ [sCrashReporterInfoLock lock]; *sCrashReporterInfo = copy; old = sOldCrashReporterInfo; sOldCrashReporterInfo = copy; [sCrashReporterInfoLock unlock]; // Delete our old string. if (old != NULL) free(old); } #endif
For this to be actually useful, you’d want to be using Smart Crash Reports (apparently coming soonish to a Leopardy computer near you) or something similar.
Pingback: Ahruman’s Webthing » Blog Archive » Hacking your Log Messages
Pingback: Recent Links Tagged With "crashreporter" - JabberTags