mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 816117 - Part 1: Add the ability to pass around a windows Thread Context to StackWalkMain64. r=ehsan
This commit is contained in:
parent
77b5416a40
commit
6a7b3d219c
@ -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",
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user