Mac: Fix bugs in new backtrace code

svn path=/trunk/boinc/; revision=15015
This commit is contained in:
Charlie Fenton 2008-04-04 10:39:22 +00:00
parent 5c3eb71f34
commit 62b7599359
2 changed files with 59 additions and 32 deletions

View File

@ -2571,7 +2571,7 @@ Charlie Mar 20 2008
lib/
mac/
mac_backtrace.C
Å buildWxMac.sh
buildWxMac.sh
David Mar 20 2008
- updated GeoIP stuff
@ -3077,3 +3077,10 @@ Charlie April 3 2008
mac_build/
HowToBuildBOINC_XCode.rtf
Charlie April 4 2008
Mac: Fix bugs in new backtrace code.
lib/
mac/
mac_backtrace.C

View File

@ -82,14 +82,15 @@ enum {
#define SKIPFRAME 4 /* Number frames overhead for signal handler and backtrace */
static char * PersistentFGets(char *buf, size_t buflen, FILE *f);
static void GetNameOfThisApp(char *nameBuf, int buflen);
static void GetPathToThisProcess(char* outbuf, size_t maxLen);
static void PrintOSVersion(char *minorVersion);
void PrintBacktrace(void) {
int err;
QCrashReportRef crRef = NULL;
char nameBuf[1024];
char pathToThisProcess[1024], pipeBuf[1024], *nameBuf;
const NXArchInfo *localArch;
char OSMinorVersion;
time_t t;
@ -120,10 +121,18 @@ void PrintBacktrace(void) {
}
#endif
GetNameOfThisApp(nameBuf, sizeof(nameBuf));
if (nameBuf[0])
GetPathToThisProcess(pathToThisProcess, sizeof(pathToThisProcess));
nameBuf = strrchr(pathToThisProcess, '/');
if (nameBuf) {
++nameBuf; // Advance over the separator
} else {
nameBuf = pathToThisProcess;
}
if (nameBuf[0]) {
fprintf(stderr, "\nCrashed executable name: %s\n", nameBuf);
}
#ifdef BOINC_VERSION_STRING
fprintf(stderr, "built using BOINC library version %s\n", BOINC_VERSION_STRING);
#endif
@ -145,7 +154,7 @@ void PrintBacktrace(void) {
err = QCRCreateFromSelf(&crRef);
// Use new backtrace functions if available (only in OS 10.5 and later)
systemlib = dlopen ("libSystem.dylib", RTLD_NOW );
systemlib = dlopen ("/usr/lib/libSystem.dylib", RTLD_NOW );
if (systemlib) {
myBacktraceProc = (backtraceProc)dlsym(systemlib, "backtrace");
}
@ -164,17 +173,17 @@ void PrintBacktrace(void) {
}
setenv("NSUnbufferedIO", "YES", 1);
snprintf(nameBuf, sizeof(nameBuf), "/usr/bin/atos -p %d", getpid());
f = popen(nameBuf, "r+");
snprintf(pipeBuf, sizeof(pipeBuf), "/usr/bin/atos -o %s", pathToThisProcess);
f = popen(pipeBuf, "r+");
if (f) {
setbuf(f, 0);
for (i=0; i<frames; i++) {
fprintf(f, "%#lx\n", (long)callstack[i]);
PersistentFGets(nameBuf, sizeof(nameBuf), f);
PersistentFGets(pipeBuf, sizeof(pipeBuf), f);
#ifdef __LP64__
fprintf(stderr, "%3d 0x%016llx %s", i, (unsigned long long)callstack[i], nameBuf);
fprintf(stderr, "%3d 0x%016llx %s", i, (unsigned long long)callstack[i], pipeBuf);
#else
fprintf(stderr, "%3d 0x%08lx %s", i, (unsigned long)callstack[i], nameBuf);
fprintf(stderr, "%3d 0x%08lx %s", i, (unsigned long)callstack[i], pipeBuf);
#endif
}
}
@ -218,29 +227,40 @@ static char * PersistentFGets(char *buf, size_t buflen, FILE *f) {
}
static void GetNameOfThisApp(char *nameBuf, int buflen) {
static void GetPathToThisProcess(char* outbuf, size_t maxLen) {
FILE *f;
char buf[64];
pid_t myPID = getpid();
int i;
nameBuf[0] = 0; // in case of failure
sprintf(buf, "ps -p %d -c -o command", myPID);
f = popen(buf, "r");
if (!f)
return;
PersistentFGets(nameBuf, buflen, f); // Skip over line of column headings
nameBuf[0] = 0;
PersistentFGets(nameBuf, buflen, f); // Get the UNIX command which ran us
fclose(f);
char buf[256], *p, *q;
pid_t aPID = getpid();
for (i=strlen(nameBuf)-1; i>=0; --i) {
if (nameBuf[i] <= ' ')
nameBuf[i] = 0; // Strip off trailing spaces, newlines, etc.
else
break;
*outbuf = '\0';
sprintf(buf, "ps -xwo command -p %d", (int)aPID);
f = popen(buf, "r");
if (f == NULL)
return;
PersistentFGets (outbuf, maxLen, f); // Discard header line
PersistentFGets (outbuf, maxLen, f);
pclose(f);
// Remove trailing newline if present
p = strchr(outbuf, '\n');
if (p)
*p = '\0';
// Strip off any arguments
p = strstr(outbuf, " -");
q = p;
if (p) {
while (*p == ' ') {
q = p;
if (--p < outbuf)
break;
}
}
if (q)
*q = '\0';
}