mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Bug 766579 - Part 1: Add SP param to NS_StackWalk. r=dbaron
--HG-- extra : rebase_source : dd4905ffadf5fe9327449fffdfbc665b05d74a6a
This commit is contained in:
parent
ec268d38f1
commit
325b77e999
@ -56,7 +56,7 @@ static const int kClientChannelFd = 3;
|
||||
|
||||
extern "C" {
|
||||
|
||||
static void PrintStackFrame(void *aPC, void *aClosure)
|
||||
static void PrintStackFrame(void *aPC, void *aSP, void *aClosure)
|
||||
{
|
||||
char buf[1024];
|
||||
nsCodeAddressDetails details;
|
||||
|
@ -586,7 +586,7 @@ typedef struct {
|
||||
} PCArray;
|
||||
|
||||
static
|
||||
void StackWalkCallback(void* aPC, void* aClosure)
|
||||
void StackWalkCallback(void* aPC, void* aSP, void* aClosure)
|
||||
{
|
||||
PCArray* array = static_cast<PCArray*>(aClosure);
|
||||
if (array->count >= array->size) {
|
||||
@ -610,7 +610,7 @@ void TableTicker::doBacktrace(ThreadProfile &aProfile, TickSample* aSample)
|
||||
};
|
||||
|
||||
// Start with the current function.
|
||||
StackWalkCallback(aSample->pc, &array);
|
||||
StackWalkCallback(aSample->pc, aSample->sp, &array);
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
pthread_t pt = GetProfiledThread(platform_data());
|
||||
|
@ -893,7 +893,7 @@ calltree(void **stack, size_t num_stack_entries, tm_thread *t)
|
||||
* reverse it in calltree.
|
||||
*/
|
||||
static void
|
||||
stack_callback(void *pc, void *closure)
|
||||
stack_callback(void *pc, void *sp, void *closure)
|
||||
{
|
||||
stack_buffer_info *info = (stack_buffer_info*) closure;
|
||||
|
||||
|
@ -51,7 +51,7 @@ malloc_logger_t(uint32_t type, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3,
|
||||
extern malloc_logger_t *malloc_logger;
|
||||
|
||||
static void
|
||||
stack_callback(void *pc, void *closure)
|
||||
stack_callback(void *pc, void *sp, void *closure)
|
||||
{
|
||||
const char *name = reinterpret_cast<char *>(closure);
|
||||
Dl_info info;
|
||||
@ -210,6 +210,9 @@ struct WalkStackData {
|
||||
void **pcs;
|
||||
PRUint32 pc_size;
|
||||
PRUint32 pc_count;
|
||||
void **sps;
|
||||
PRUint32 sp_size;
|
||||
PRUint32 sp_count;
|
||||
};
|
||||
|
||||
void PrintError(char *prefix, WalkStackData* data);
|
||||
@ -288,6 +291,7 @@ WalkStackMain64(struct WalkStackData* data)
|
||||
HANDLE myProcess = data->process;
|
||||
HANDLE myThread = data->thread;
|
||||
DWORD64 addr;
|
||||
DWORD64 spaddr;
|
||||
STACKFRAME64 frame64;
|
||||
// skip our own stack walking frames
|
||||
int skip = (data->walkCallingThread ? 3 : 0) + data->skipFrames;
|
||||
@ -349,10 +353,12 @@ WalkStackMain64(struct WalkStackData* data)
|
||||
);
|
||||
LeaveCriticalSection(&gDbgHelpCS);
|
||||
|
||||
if (ok)
|
||||
if (ok) {
|
||||
addr = frame64.AddrPC.Offset;
|
||||
else {
|
||||
spaddr = frame64.AddrStack.Offset;
|
||||
} else {
|
||||
addr = 0;
|
||||
spaddr = 0;
|
||||
PrintError("WalkStack64");
|
||||
}
|
||||
|
||||
@ -368,6 +374,10 @@ WalkStackMain64(struct WalkStackData* data)
|
||||
data->pcs[data->pc_count] = (void*)addr;
|
||||
++data->pc_count;
|
||||
|
||||
if (data->sp_count < data->sp_size)
|
||||
data->sps[data->sp_count] = (void*)spaddr;
|
||||
++data->sp_count;
|
||||
|
||||
if (frame64.AddrReturn.Offset == 0)
|
||||
break;
|
||||
}
|
||||
@ -484,6 +494,10 @@ NS_StackWalk(NS_WalkStackCallback aCallback, PRUint32 aSkipFrames,
|
||||
data.pcs = local_pcs;
|
||||
data.pc_count = 0;
|
||||
data.pc_size = ArrayLength(local_pcs);
|
||||
void *local_sps[1024];
|
||||
data.sps = local_sps;
|
||||
data.sp_count = 0;
|
||||
data.sp_size = ArrayLength(local_pcs);
|
||||
|
||||
if (aThread) {
|
||||
// If we're walking the stack of another thread, we don't need to
|
||||
@ -512,6 +526,9 @@ NS_StackWalk(NS_WalkStackCallback aCallback, PRUint32 aSkipFrames,
|
||||
data.pcs = (void**) _alloca(data.pc_count * sizeof(void*));
|
||||
data.pc_size = data.pc_count;
|
||||
data.pc_count = 0;
|
||||
data.sps = (void**) _alloca(data.sp_count * sizeof(void*));
|
||||
data.sp_size = data.sp_count;
|
||||
data.sp_count = 0;
|
||||
::PostThreadMessage(gStackWalkThread, WM_USER, 0, (LPARAM)&data);
|
||||
walkerReturn = ::SignalObjectAndWait(data.eventStart,
|
||||
data.eventEnd, INFINITE, FALSE);
|
||||
@ -526,7 +543,10 @@ NS_StackWalk(NS_WalkStackCallback aCallback, PRUint32 aSkipFrames,
|
||||
::CloseHandle(myThread);
|
||||
|
||||
for (PRUint32 i = 0; i < data.pc_count; ++i)
|
||||
(*aCallback)(data.pcs[i], aClosure);
|
||||
(*aCallback)(data.pcs[i], data.sps[i], aClosure);
|
||||
|
||||
if (data.sp_size > ArrayLength(local_sps))
|
||||
free(data.sps);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -823,9 +843,9 @@ static struct bucket * newbucket ( void * pc );
|
||||
static struct frame * cs_getmyframeptr ( void );
|
||||
static void cs_walk_stack ( void * (*read_func)(char * address),
|
||||
struct frame * fp,
|
||||
int (*operate_func)(void *, void *),
|
||||
int (*operate_func)(void *, void *, void *),
|
||||
void * usrarg );
|
||||
static void cs_operate ( void (*operate_func)(void *, void *),
|
||||
static void cs_operate ( void (*operate_func)(void *, void *, void *),
|
||||
void * usrarg );
|
||||
|
||||
#ifndef STACK_BIAS
|
||||
@ -953,13 +973,13 @@ csgetframeptr()
|
||||
|
||||
|
||||
static void
|
||||
cswalkstack(struct frame *fp, int (*operate_func)(void *, void *),
|
||||
cswalkstack(struct frame *fp, int (*operate_func)(void *, void *, void *),
|
||||
void *usrarg)
|
||||
{
|
||||
|
||||
while (fp != 0 && fp->fr_savpc != 0) {
|
||||
|
||||
if (operate_func((void *)fp->fr_savpc, usrarg) != 0)
|
||||
if (operate_func((void *)fp->fr_savpc, NULL, usrarg) != 0)
|
||||
break;
|
||||
/*
|
||||
* watch out - libthread stacks look funny at the top
|
||||
@ -973,7 +993,7 @@ cswalkstack(struct frame *fp, int (*operate_func)(void *, void *),
|
||||
|
||||
|
||||
static void
|
||||
cs_operate(int (*operate_func)(void *, void *), void * usrarg)
|
||||
cs_operate(int (*operate_func)(void *, void *, void *), void * usrarg)
|
||||
{
|
||||
cswalkstack(csgetframeptr(), operate_func, usrarg);
|
||||
}
|
||||
@ -1087,7 +1107,11 @@ FramePointerStackWalk(NS_WalkStackCallback aCallback, PRUint32 aSkipFrames,
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
if (--skip < 0) {
|
||||
(*aCallback)(pc, aClosure);
|
||||
// Assume that the SP points to the BP of the function
|
||||
// it called. We can't know the exact location of the SP
|
||||
// but this should be sufficient for our use the SP
|
||||
// to order elements on the stack.
|
||||
(*aCallback)(pc, (bp), aClosure);
|
||||
}
|
||||
bp = next;
|
||||
}
|
||||
@ -1144,6 +1168,7 @@ unwind_callback (struct _Unwind_Context *context, void *closure)
|
||||
{
|
||||
unwind_info *info = static_cast<unwind_info *>(closure);
|
||||
void *pc = reinterpret_cast<void *>(_Unwind_GetIP(context));
|
||||
// TODO Use something like 'unw_get_reg(&cursor, UNW_REG_SP, &sp)' to get sp
|
||||
if (IsCriticalAddress(pc)) {
|
||||
printf("Aborting stack trace, PC is critical\n");
|
||||
/* We just want to stop the walk, so any error code will do.
|
||||
@ -1152,7 +1177,7 @@ unwind_callback (struct _Unwind_Context *context, void *closure)
|
||||
return _URC_FOREIGN_EXCEPTION_CAUGHT;
|
||||
}
|
||||
if (--info->skip < 0)
|
||||
(*info->callback)(pc, info->closure);
|
||||
(*info->callback)(pc, NULL, info->closure);
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
|
||||
|
@ -15,8 +15,11 @@
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
// aSP will be the best approximation possible of what the stack pointer will be
|
||||
// pointing to when the execution returns to executing that at that PC.
|
||||
// If no approximation can be made it will be NULL.
|
||||
typedef void
|
||||
(* NS_WalkStackCallback)(void *aPC, void *aClosure);
|
||||
(* NS_WalkStackCallback)(void *aPC, void *aSP, void *aClosure);
|
||||
|
||||
/**
|
||||
* Call aCallback for the C/C++ stack frames on the current thread, from
|
||||
|
@ -836,7 +836,7 @@ static void InitTraceLog(void)
|
||||
|
||||
extern "C" {
|
||||
|
||||
static void PrintStackFrame(void *aPC, void *aClosure)
|
||||
static void PrintStackFrame(void *aPC, void *aSP, void *aClosure)
|
||||
{
|
||||
FILE *stream = (FILE*)aClosure;
|
||||
nsCodeAddressDetails details;
|
||||
|
@ -106,7 +106,7 @@ Crash()
|
||||
|
||||
#ifdef REPORT_CHROME_HANGS
|
||||
static void
|
||||
ChromeStackWalker(void *aPC, void *aClosure)
|
||||
ChromeStackWalker(void *aPC, void *aSP, void *aClosure)
|
||||
{
|
||||
MOZ_ASSERT(aClosure);
|
||||
Telemetry::HangStack *callStack =
|
||||
|
Loading…
Reference in New Issue
Block a user