Bug 816117 - Part 1: Add the ability to pass around a windows Thread Context to StackWalkMain64. r=ehsan

This commit is contained in:
Bas Schouten 2012-12-08 06:15:21 +01:00
parent 77b5416a40
commit 6a7b3d219c
7 changed files with 35 additions and 20 deletions

View File

@ -77,7 +77,7 @@ ah_crap_handler(int signum)
signum);
printf("Stack:\n");
NS_StackWalk(PrintStackFrame, 2, nullptr, 0);
NS_StackWalk(PrintStackFrame, 2, nullptr, 0, nullptr);
printf("Sleeping for %d seconds.\n",_gdb_sleep_duration);
printf("Type 'gdb %s %d' to attach your debugger to this thread.\n",

View File

@ -929,7 +929,7 @@ backtrace(tm_thread *t, int skip, int *immediate_abort)
/* Walk the stack, even if stacks_enabled is false. We do this to
check if we must set immediate_abort. */
info->entries = 0;
rv = NS_StackWalk(stack_callback, skip, info, 0);
rv = NS_StackWalk(stack_callback, skip, info, 0, NULL);
*immediate_abort = rv == NS_ERROR_UNEXPECTED;
if (rv == NS_ERROR_UNEXPECTED || info->entries == 0) {
t->suppress_tracing--;
@ -964,7 +964,7 @@ backtrace(tm_thread *t, int skip, int *immediate_abort)
/* skip == 0 means |backtrace| should show up, so don't use skip + 1 */
/* NB: this call is repeated below if the buffer is too small */
info->entries = 0;
rv = NS_StackWalk(stack_callback, skip, info, 0);
rv = NS_StackWalk(stack_callback, skip, info, 0, NULL);
*immediate_abort = rv == NS_ERROR_UNEXPECTED;
if (rv == NS_ERROR_UNEXPECTED || info->entries == 0) {
t->suppress_tracing--;
@ -988,7 +988,7 @@ backtrace(tm_thread *t, int skip, int *immediate_abort)
/* and call NS_StackWalk again */
info->entries = 0;
NS_StackWalk(stack_callback, skip, info, 0);
NS_StackWalk(stack_callback, skip, info, 0, NULL);
/* same stack */
PR_ASSERT(info->entries * 2 == new_stack_buffer_size);

View File

@ -102,7 +102,7 @@ my_malloc_logger(uint32_t type, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3,
// stack shows up as having two pthread_cond_wait$UNIX2003 frames.
const char *name = OnSnowLeopardOrLater() ? "new_sem_from_pool" :
"pthread_cond_wait$UNIX2003";
NS_StackWalk(stack_callback, 0, const_cast<char*>(name), 0);
NS_StackWalk(stack_callback, 0, const_cast<char*>(name), 0, nullptr);
}
// This is called from NS_LogInit() and from the stack walking functions, but
@ -219,6 +219,7 @@ struct WalkStackData {
void **sps;
uint32_t sp_size;
uint32_t sp_count;
void *platformData;
};
void PrintError(char *prefix, WalkStackData* data);
@ -304,13 +305,17 @@ WalkStackMain64(struct WalkStackData* data)
BOOL ok;
// Get a context for the specified thread.
memset(&context, 0, sizeof(CONTEXT));
context.ContextFlags = CONTEXT_FULL;
if (!GetThreadContext(myThread, &context)) {
if (data->walkCallingThread) {
PrintError("GetThreadContext");
if (!data->platformData) {
memset(&context, 0, sizeof(CONTEXT));
context.ContextFlags = CONTEXT_FULL;
if (!GetThreadContext(myThread, &context)) {
if (data->walkCallingThread) {
PrintError("GetThreadContext");
}
return;
}
return;
} else {
context = *static_cast<CONTEXT*>(data->platformData);
}
// Setup initial stack frame to walk from
@ -457,7 +462,7 @@ WalkStackThread(void* aData)
EXPORT_XPCOM_API(nsresult)
NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
void *aClosure, uintptr_t aThread)
void *aClosure, uintptr_t aThread, void *aPlatformData)
{
StackWalkInitCriticalAddress();
static HANDLE myProcess = NULL;
@ -516,6 +521,7 @@ NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
data.sps = local_sps;
data.sp_count = 0;
data.sp_size = ArrayLength(local_pcs);
data.platformData = aPlatformData;
if (aThread) {
// If we're walking the stack of another thread, we don't need to
@ -1014,9 +1020,10 @@ cs_operate(int (*operate_func)(void *, void *, void *), void * usrarg)
EXPORT_XPCOM_API(nsresult)
NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
void *aClosure, uintptr_t aThread)
void *aClosure, uintptr_t aThread, void *aPlatformData)
{
MOZ_ASSERT(!aThread);
MOZ_ASSERT(!aPlatformData);
struct my_user_args args;
StackWalkInitCriticalAddress();
@ -1142,9 +1149,10 @@ FramePointerStackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
EXPORT_XPCOM_API(nsresult)
NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
void *aClosure, uintptr_t aThread)
void *aClosure, uintptr_t aThread, void *aPlatformData)
{
MOZ_ASSERT(!aThread);
MOZ_ASSERT(!aPlatformData);
StackWalkInitCriticalAddress();
// Get the frame pointer
@ -1201,9 +1209,10 @@ unwind_callback (struct _Unwind_Context *context, void *closure)
EXPORT_XPCOM_API(nsresult)
NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
void *aClosure, uintptr_t aThread)
void *aClosure, uintptr_t aThread, void *aPlatformData)
{
MOZ_ASSERT(!aThread);
MOZ_ASSERT(!aPlatformData);
StackWalkInitCriticalAddress();
unwind_info info;
info.callback = aCallback;
@ -1289,9 +1298,10 @@ NS_FormatCodeAddressDetails(void *aPC, const nsCodeAddressDetails *aDetails,
EXPORT_XPCOM_API(nsresult)
NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
void *aClosure, uintptr_t aThread)
void *aClosure, uintptr_t aThread, void *aPlatformData)
{
MOZ_ASSERT(!aThread);
MOZ_ASSERT(!aPlatformData);
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@ -36,6 +36,11 @@ typedef void
* Passing null causes us to walk the stack of the
* current thread. On Windows, this is a thread HANDLE.
* It is currently not supported on any other platform.
* @param aPlatformData Platform specific data that can help in walking the
* stack, this should be NULL unless you really know
* what you're doing! This needs to be a pointer to a
* CONTEXT on Windows and should not be passed on other
* platforms.
*
* Returns NS_ERROR_NOT_IMPLEMENTED on platforms where it is
* unimplemented.
@ -48,7 +53,7 @@ typedef void
*/
XPCOM_API(nsresult)
NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
void *aClosure, uintptr_t aThread);
void *aClosure, uintptr_t aThread, void *aPlatformData);
typedef struct {
/*

View File

@ -854,7 +854,7 @@ static void PrintStackFrame(void *aPC, void *aSP, void *aClosure)
void
nsTraceRefcntImpl::WalkTheStack(FILE* aStream)
{
NS_StackWalk(PrintStackFrame, 2, aStream, 0);
NS_StackWalk(PrintStackFrame, 2, aStream, 0, nullptr);
}
//----------------------------------------------------------------------

View File

@ -95,7 +95,7 @@ bool ValidWriteAssert(bool ok)
// concurrently from many writes, so we use multiple temporary files.
std::vector<uintptr_t> rawStack;
NS_StackWalk(RecordStackWalker, 0, reinterpret_cast<void*>(&rawStack), 0);
NS_StackWalk(RecordStackWalker, 0, reinterpret_cast<void*>(&rawStack), 0, nullptr);
Telemetry::ProcessedStack stack = Telemetry::GetStackAndModules(rawStack);
nsPrintfCString nameAux("%s%s", sProfileDirectory,

View File

@ -134,7 +134,7 @@ GetChromeHangReport(Telemetry::ProcessedStack &aStack)
if (ret == -1)
return;
NS_StackWalk(ChromeStackWalker, 0, reinterpret_cast<void*>(&rawStack),
reinterpret_cast<uintptr_t>(winMainThreadHandle));
reinterpret_cast<uintptr_t>(winMainThreadHandle), nullptr);
ret = ::ResumeThread(winMainThreadHandle);
if (ret == -1)
return;