From c56f6e0563fb8f68f748fa5ed4336df1497cfab3 Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Thu, 2 Dec 2010 11:47:48 +0000 Subject: [PATCH] Mac lib: use newer backtrace() APIs under OS 10.5.x on Intel Macs svn path=/trunk/boinc/; revision=22794 --- checkin_notes | 9 +++++ lib/mac/mac_backtrace.cpp | 69 ++++++++++++++++++--------------------- 2 files changed, 41 insertions(+), 37 deletions(-) diff --git a/checkin_notes b/checkin_notes index 7b4d4b3ec2..91fece99ed 100644 --- a/checkin_notes +++ b/checkin_notes @@ -8579,3 +8579,12 @@ David 1 Dec 2010 client_types.cpp cs_statefile.cpp acct_mgr.cpp + +Charlie 2 Dec 2010 + - lib: The custom Mac backtrace code doesn't work on Intel Macs running + under OS 10.5.x, so use newer backtrace() and backtrace_symbols() + APIs under OS 10.5.x, with explanatory text suggesting alternatives. + + lib/ + mac/ + mac_backtrace.cpp diff --git a/lib/mac/mac_backtrace.cpp b/lib/mac/mac_backtrace.cpp index ab2a3f62b6..de6850d692 100644 --- a/lib/mac/mac_backtrace.cpp +++ b/lib/mac/mac_backtrace.cpp @@ -44,8 +44,6 @@ * Pipe the output of the shell script through c++filt to demangle C++ symbols. */ -// The old way still seems to work better under OS 10.6.4 -#define USE_NEW_ROUTINES false #ifdef __ppc__ #include @@ -96,9 +94,8 @@ void PrintBacktrace(void) { char nameBuf[256], pathToThisProcess[1024]; const NXArchInfo *localArch; - char OSMinorVersion; + char OSMinorVersion = '?'; time_t t; -#if USE_NEW_ROUTINES char atosPipeBuf[1024], cppfiltPipeBuf[1024]; char outBuf[1024], offsetBuf[32]; char *sourceSymbol, *symbolEnd; @@ -112,7 +109,6 @@ void PrintBacktrace(void) { backtrace_symbolsProc myBacktrace_symbolsProc = NULL; char saved_env[128], *env = NULL; bool atosExists = false, cppfiltExists = false; -#endif #if 0 // To debug backtrace logic: @@ -158,30 +154,32 @@ void PrintBacktrace(void) { fputs(asctime(localtime(&t)), stderr); fputc('\n', stderr); -#ifdef __ppc__ - long OSVersion = 0; - OSStatus gestaltErr = Gestalt(gestaltSystemVersion, &OSVersion); - if ((gestaltErr == noErr) && ((OSVersion & 0xfff0) == 0x1050)) { - fputs("BOINC backtrace is not supported for PowerPC under OS 10.5.x\n", stderr); - fputs("To get a backtrace run under OS 10.4.x or run on an Intel Mac\n\n", stderr); - } -#endif - err = QCRCreateFromSelf(&crRef); -#if USE_NEW_ROUTINES - // Use new backtrace functions if available (only in OS 10.5 and later) - systemlib = dlopen ("/usr/lib/libSystem.dylib", RTLD_NOW ); - if (systemlib) { - myBacktraceProc = (backtraceProc)dlsym(systemlib, "backtrace"); - } - if (myBacktraceProc) { + if (OSMinorVersion == '5') { +#ifdef __ppc__ + fputs("BOINC backtrace under OS 10.5.x only shows exported (global) symbols\n", stderr); + fputs("and may work poorly on a PowerPC Mac after a crash. For a better\n", stderr); + fputs("backtrace, run under OS 10.4.x.\n\n", stderr); +#else + fputs("BOINC backtrace under OS 10.5.x only shows exported (global) symbols\n", stderr); + fputs("and may not show the final location which caused a crash. For a better\n", stderr); + fputs("backtrace, either run under OS 10.4.x or run under OS 10.6.x or later.\n\n", stderr); +#endif + // Use new backtrace functions if available (only in OS 10.5 and later) + systemlib = dlopen ("/usr/lib/libSystem.dylib", RTLD_NOW ); + if (systemlib) { + myBacktraceProc = (backtraceProc)dlsym(systemlib, "backtrace"); + } + if (! myBacktraceProc) { + goto skipBackTrace; // Should never happen + } frames = myBacktraceProc(callstack, CALL_STACK_SIZE); myBacktrace_symbolsProc = (backtrace_symbolsProc)dlsym(systemlib, "backtrace_symbols"); if (myBacktrace_symbolsProc) { symbols = myBacktrace_symbolsProc(callstack, frames); } else { - goto useOldMethod; + goto skipBackTrace; // Should never happen } atosExists = boinc_file_exists("/usr/bin/atos"); @@ -253,17 +251,16 @@ void PrintBacktrace(void) { if (atosPipe) { fprintf(atosPipe, "%#llx\n", (QTMAddr)callstack[i]); BT_PersistentFGets(atosPipeBuf, sizeof(atosPipeBuf), atosPipe); - sourceSymbol = strrchr(atosPipeBuf, (int)':'); - if (sourceSymbol) { - if (*--sourceSymbol != ':') { - sourceSymbol = strrchr(atosPipeBuf, (int)'('); - if (sourceSymbol) { - strlcat(outBuf, sourceSymbol-1, sizeof(outBuf)); - symbolEnd = strchr(outBuf, (int)'\n'); - if (symbolEnd) { - *symbolEnd = '\0'; - } - } + sourceSymbol = strstr(atosPipeBuf, "0x"); + if (!sourceSymbol) { // If atos returned a symbol (not just a hex value) + sourceSymbol = strstr(outBuf, "0x"); + if (sourceSymbol) sourceSymbol = strstr(sourceSymbol, " "); + if (sourceSymbol) *++sourceSymbol = '\0'; // Remove questionable symbol from backtrace_symbols() + strlcat(outBuf, " ", sizeof(outBuf)); + strlcat(outBuf, atosPipeBuf, sizeof(outBuf)); + symbolEnd = strchr(outBuf, (int)'\n'); + if (symbolEnd) { + *symbolEnd = '\0'; } } } @@ -286,14 +283,12 @@ void PrintBacktrace(void) { } } +skipBackTrace: fprintf(stderr, "\n"); } else { -useOldMethod: + // Not OS 10.5.x QCRPrintBacktraces(crRef, stderr); } -#else // ! USE_NEW_ROUTINES - QCRPrintBacktraces(crRef, stderr); -#endif // make sure this much gets written to file in case future // versions of OS break our crash dump code beyond this point.