diff --git a/checkin_notes b/checkin_notes index 1536a46aaa..9d4c23004a 100755 --- a/checkin_notes +++ b/checkin_notes @@ -2965,3 +2965,18 @@ David 29 Mar 2007 clientgui/ AdvancedFrame.cpp DlgAbout.cpp + +Charlie 30 Mar 2007 + - Mac: Major fixes and improvements to backtrace: correctly show + address of instruction which caused SIGSEGV or SIGBUS faults, + remove bogus NULL stack frame at end of trace; improve output + format, etc. + - Mac: Add browser.C,h to XCode project. + + lib/ + mac_backtrace.C + MoreBacktrace.C + mac_build/ + boinc.xcodeproj/ + project.pbxproj + diff --git a/lib/MoreBacktrace.c b/lib/MoreBacktrace.c index ee1d53c820..c3851bb041 100644 --- a/lib/MoreBacktrace.c +++ b/lib/MoreBacktrace.c @@ -64,6 +64,9 @@ Change History (most recent first): $Log$ +Revision 1.2 2007/03/31 01:32:35 charlief +*** empty log message *** + Revision 1.1 2006/02/10 17:27:12 charlief *** empty log message *** @@ -707,7 +710,6 @@ static int BacktraceCore(MoreBTContext *context) } else { frameOutPtr = &tmpFrameOut; } - context->frameCountOut += 1; // Record this entry. @@ -741,7 +743,8 @@ static int BacktraceCore(MoreBTContext *context) ) { frameOutPtr->flags |= kMoreBTFrameBadMask; stopNow = true; - } + } else + context->frameCountOut += 1; if ( (err == 0) && ! stopNow) { @@ -1251,9 +1254,9 @@ static int PowerPCCrossSignalFrame(MoreBTContext *context, MoreBTAddr thisFrame, // idea how to detect such a system at runtime. } else { // Mac OS X 10.3 and later - offsetToPC = 0x90; - offsetToFP = 0x9c; - offsetToLR = 0x188; + offsetToPC = 0xf8; // 0xd8 + offsetof(struct mcontext, ss.srr0) + offsetToFP = 0x104; // 0xd8 + offsetof(struct mcontext, ss.r1) + offsetToLR = 0x168; // 0xd8 + offsetof(struct mcontext, ss.lr) } } @@ -1446,6 +1449,11 @@ static int IntelGetFrameNextPC(MoreBTContext *context, MoreBTAddr thisFrame, Mor Things to note about the above: + ** The following does not appear to be entirely correct; mcontext does + ** always seem to be at a fixed offset of 0x30 from the frame start. + ** Also, siginfo_t.si_addr does not contain the offending PC in cases + ** where an actual bus error or segment violation occurred. -- CAF 3/30/07 + o The kernel aligns the stack such that the catcher field of the sigframe structure is aligned on a 16 byte boundary. This means that there's a variable amount of pad between sigframe and mcontext. @@ -1478,12 +1486,9 @@ static int IntelCrossSignalFrame(MoreBTContext *context, MoreBTAddr thisFrame, M err = ReadAddr(context, thisFrame + 0x14, &sigInfo); - // Get the previous PC from si_addr field of siginfo_t. - - if (err == 0) { - err = ReadAddr(context, sigInfo + 0x18, nextPCPtr); - } - + // Get the previous PC from ss.eip field of mcontext. + err = ReadAddr(context, thisFrame + 0x64, nextPCPtr); // 0x30 + offsetof(struct mcontext, ss.eip) = 0x64 + // Get the previous frame by simply reading from the frame pointer. // Because of the way things work, this ends up being correct. @@ -1650,33 +1655,19 @@ extern int MoreBacktraceMachThread( #if TARGET_CPU_PPC - #if 0 // Changed for BOINC: this won't compile under GCC3.3 ?? - #define InitThreadState(threadState) \ - do { \ - uint32_t tmpPC = 0; \ - uint32_t tmpFP = 0; \ - asm { \ - bl next ; \ - next: mflr tmpPC ; \ - mr tmpFP,sp \ - } \ - ((ppc_thread_state_t *) threadState)->srr0 = tmpPC; \ - ((ppc_thread_state_t *) threadState)->r1 = tmpFP; \ + // GCC 3.3 seems to reject the block syntax, so we use the following + #define InitThreadState(threadState) \ + do { \ + uint32_t tmpPC = 0; \ + uint32_t tmpFP = 0; \ + __asm__ volatile("bl next"); \ + __asm__ volatile("next: mflr %0" : "=r" (tmpPC)); \ + __asm__ volatile("mr %0,r1" : "=r" (tmpFP)); \ + \ + ((ppc_thread_state_t *) threadState)->srr0 = tmpPC; \ + ((ppc_thread_state_t *) threadState)->r1 = tmpFP; \ } while (0) - #else - void InitThreadState(threadState) { - uint32_t tmpPC = 0; - uint32_t tmpFP = 0; - - __asm__ volatile("mflr %0" : "=r" (tmpPC)); - __asm__ volatile("mr %0,r1" : "=r" (tmpFP)); - - ((ppc_thread_state_t *) threadState)->srr0 = tmpPC; - ((ppc_thread_state_t *) threadState)->r1 = tmpFP; - - } - #endif #elif TARGET_CPU_PPC64 #define InitThreadState(threadState) \ diff --git a/lib/mac_backtrace.C b/lib/mac_backtrace.C index 38067e9614..6919246527 100644 --- a/lib/mac_backtrace.C +++ b/lib/mac_backtrace.C @@ -98,41 +98,36 @@ void PrintBacktrace(void) { time(&t); fputs(asctime(localtime(&t)), stderr); - + frameCount = sizeof(frames) / sizeof(*frames); - err = MoreBacktraceMachSelf(0, 0, frames, frameCount, &validFrames); // Calling task first - if (err == 0) { - if (validFrames > frameCount) { - validFrames = frameCount; - } - err = OutputFrames(frames, validFrames, true); - } - fflush(stderr); - targetTask = mach_task_self(); currentThread = mach_thread_self(); err = task_threads(targetTask, &threadList, &threadCount); if (threadList != NULL) { for (thisThread = 0; thisThread < threadCount; thisThread++) { + fprintf(stderr, "\nThread number %d ", thisThread); - if (threadList[thisThread] != currentThread) { // Calling task cannot call thread_get_state on itself + if (threadList[thisThread] == currentThread) { // Calling task cannot call thread_get_state on itself + fputs("crashed. Stack frame backtrace:", stderr); + err = MoreBacktraceMachSelf(0, 0, frames, frameCount, &validFrames); // Calling task first + } else { + fputs("stack frame backtrace: ", stderr); err = thread_suspend(threadList[thisThread]); didSuspend = (err == 0); err = MoreBacktraceMachThread(targetTask, threadList[thisThread], 0, 0, frames, frameCount, &validFrames); if (didSuspend) thread_resume(threadList[thisThread]); - if (err == 0) { - if (validFrames > frameCount) { - validFrames = frameCount; - } - fprintf(stderr, "\nThread number %d: ", thisThread); - err = OutputFrames(frames, validFrames, true); - } + } + + if (err == 0) { + if (validFrames > frameCount) + validFrames = frameCount; + err = OutputFrames(frames, validFrames, true); fflush(stderr); } - } - } + } // End for (thisThread) loop + } // End if (threadList != NULL) } @@ -258,7 +253,7 @@ static int OutputFrames(const MoreBTFrame *frameArray, unsigned long frameCount, if ((frameCount >= SKIPFRAME) && (frameArray[SKIPFRAME-1].flags & kMoreBTSignalHandlerMask)) skipframe = SKIPFRAME; - fputs("Stack frame backtrace:\n # Flags Frame Addr Caller PC Return Address Symbol\n" + fputs("\n # Flags Frame Addr Caller PC Return Address Symbol\n" "=== === ========== ========== =====================\n", stderr); for (frameIndex = skipframe; frameIndex < frameCount; frameIndex++) { diff --git a/mac_build/boinc.xcodeproj/project.pbxproj b/mac_build/boinc.xcodeproj/project.pbxproj index 0e48325b6f..2f8f0513ce 100755 --- a/mac_build/boinc.xcodeproj/project.pbxproj +++ b/mac_build/boinc.xcodeproj/project.pbxproj @@ -213,6 +213,7 @@ DD7DD79A0B8BFA2F00B11279 /* ViewMessagesGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDCDCDF00B532433009BB03C /* ViewMessagesGrid.cpp */; }; DD7DD79B0B8BFA4000B11279 /* ViewResources.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD81C42307C5D1D70098A04D /* ViewResources.cpp */; }; DD7DD7C90B8BFD4800B11279 /* ViewMessages.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD81C42507C5D1D70098A04D /* ViewMessages.cpp */; }; + DD9986830BBDF11000B690C2 /* browser.C in Sources */ = {isa = PBXBuildFile; fileRef = DD9986810BBDF11000B690C2 /* browser.C */; }; DDA12A6D0A36974600FBDD12 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD1929D80918A2F100C31BCF /* Security.framework */; }; DDA12AA20A369B5500FBDD12 /* SetupSecurity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD7748B40A356D6C0025D05E /* SetupSecurity.cpp */; }; DDA12AAE0A369C5800FBDD12 /* SecurityUtility.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA12AAD0A369C5800FBDD12 /* SecurityUtility.cpp */; }; @@ -869,7 +870,7 @@ DD344BEE07C5B1770043025C /* proxy_info.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = proxy_info.h; path = ../lib/proxy_info.h; sourceTree = SOURCE_ROOT; }; DD344BEF07C5B1770043025C /* proxy_info.C */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = proxy_info.C; path = ../lib/proxy_info.C; sourceTree = SOURCE_ROOT; }; DD35353107E1E05C00C4718D /* libboinc_api.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libboinc_api.a; sourceTree = BUILT_PRODUCTS_DIR; }; - DD3E15420A774397007E0084 /* BOINCManager.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = BOINCManager.app; sourceTree = BUILT_PRODUCTS_DIR; }; + DD3E15420A774397007E0084 /* BOINCManager.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BOINCManager.app; sourceTree = BUILT_PRODUCTS_DIR; }; DD407A4A07D2FB1200163EF5 /* libboinc.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libboinc.a; sourceTree = BUILT_PRODUCTS_DIR; }; DD407AB707D2FC7D00163EF5 /* mem_usage.C */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = mem_usage.C; path = ../lib/mem_usage.C; sourceTree = SOURCE_ROOT; }; DD407AB807D2FC7D00163EF5 /* mem_usage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mem_usage.h; path = ../lib/mem_usage.h; sourceTree = SOURCE_ROOT; }; @@ -1022,6 +1023,8 @@ DD8DD4A609D9432F0043019E /* BOINCDialupManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = BOINCDialupManager.h; path = ../clientgui/BOINCDialupManager.h; sourceTree = SOURCE_ROOT; }; DD96AFF90811075000A06F22 /* BOINCSaver.saver */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BOINCSaver.saver; sourceTree = BUILT_PRODUCTS_DIR; }; DD96AFFA0811075100A06F22 /* ScreenSaver-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "ScreenSaver-Info.plist"; sourceTree = SOURCE_ROOT; }; + DD9986810BBDF11000B690C2 /* browser.C */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = browser.C; path = ../lib/browser.C; sourceTree = SOURCE_ROOT; }; + DD9986820BBDF11000B690C2 /* browser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = browser.h; path = ../lib/browser.h; sourceTree = SOURCE_ROOT; }; DD9C94A00A5A3A4100AB0D10 /* AdvancedFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AdvancedFrame.cpp; path = ../clientgui/AdvancedFrame.cpp; sourceTree = SOURCE_ROOT; }; DD9C94A10A5A3A4100AB0D10 /* AdvancedFrame.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AdvancedFrame.h; path = ../clientgui/AdvancedFrame.h; sourceTree = SOURCE_ROOT; }; DD9C94A20A5A3A4100AB0D10 /* BOINCBaseFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = BOINCBaseFrame.cpp; path = ../clientgui/BOINCBaseFrame.cpp; sourceTree = SOURCE_ROOT; }; @@ -1520,6 +1523,8 @@ DD344B6407C5ACEB0043025C /* base64.h */, DD69FEF608416C9A00C01361 /* boinc_cmd.C */, DD81C5F007C5D8290098A04D /* boinc_win.h */, + DD9986810BBDF11000B690C2 /* browser.C */, + DD9986820BBDF11000B690C2 /* browser.h */, DD7168360AAD72040051642B /* common_defs.h */, F51DA64D02DB97FF010E292A /* crypt.C */, F51DA64E02DB97FF010E292A /* crypt.h */, @@ -2436,6 +2441,7 @@ DD7DD7C90B8BFD4800B11279 /* ViewMessages.cpp in Sources */, DD7BF7E60B8E7B6C00A009F7 /* str_util.C in Sources */, DD205A1A0BAF596E0008D473 /* ProjectListCtrl.cpp in Sources */, + DD9986830BBDF11000B690C2 /* browser.C in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };