fix incorrect stack unwinding for asynchronous stack traces

Our Thread.getStackTrace implementation is tricky because it might be
invoked on a thread executing arbitrary native or Java code, and there
are numerous edge cases to consider.  Unsurprisingly, there were a few
lingering, non-fatal bugs revealed by Valgrind recently, one involving
the brief interval just before and after returning from invokeNative,
and the other involving an off-by-one error in x86.cpp's nextFrame
implementation.  This commit fixes both.
This commit is contained in:
Joel Dice 2012-06-18 14:27:18 +00:00
parent 4512a9a38e
commit 886dd184aa
7 changed files with 42 additions and 38 deletions

View File

@ -23,12 +23,12 @@
#endif #endif
#define THREAD_STACK 2148 #define THREAD_STACK 2148
#define THREAD_SCRATCH 2152 #define THREAD_SCRATCH 2156
#define THREAD_CONTINUATION 2156 #define THREAD_CONTINUATION 2160
#define THREAD_EXCEPTION 44 #define THREAD_EXCEPTION 44
#define THREAD_EXCEPTION_STACK_ADJUSTMENT 2160 #define THREAD_EXCEPTION_STACK_ADJUSTMENT 2164
#define THREAD_EXCEPTION_OFFSET 2164 #define THREAD_EXCEPTION_OFFSET 2168
#define THREAD_EXCEPTION_HANDLER 2168 #define THREAD_EXCEPTION_HANDLER 2172
#define CONTINUATION_NEXT 4 #define CONTINUATION_NEXT 4
#define CONTINUATION_ADDRESS 16 #define CONTINUATION_ADDRESS 16

View File

@ -30,11 +30,11 @@
#define ARGUMENT_BASE BYTES_PER_WORD * LINKAGE_AREA #define ARGUMENT_BASE BYTES_PER_WORD * LINKAGE_AREA
#define THREAD_STACK 2148 #define THREAD_STACK 2148
#define THREAD_CONTINUATION 2156 #define THREAD_CONTINUATION 2160
#define THREAD_EXCEPTION 44 #define THREAD_EXCEPTION 44
#define THREAD_EXCEPTION_STACK_ADJUSTMENT 2160 #define THREAD_EXCEPTION_STACK_ADJUSTMENT 2164
#define THREAD_EXCEPTION_OFFSET 2164 #define THREAD_EXCEPTION_OFFSET 2168
#define THREAD_EXCEPTION_HANDLER 2168 #define THREAD_EXCEPTION_HANDLER 2172
#define CONTINUATION_NEXT 4 #define CONTINUATION_NEXT 4
#define CONTINUATION_ADDRESS 16 #define CONTINUATION_ADDRESS 16

View File

@ -24,7 +24,7 @@
#ifdef __x86_64__ #ifdef __x86_64__
#define THREAD_STACK 2224 #define THREAD_STACK 2224
#define THREAD_SCRATCH 2232 #define THREAD_SCRATCH 2240
#ifdef AVIAN_USE_FRAME_POINTER #ifdef AVIAN_USE_FRAME_POINTER
# define ALIGNMENT_ADJUSTMENT 0 # define ALIGNMENT_ADJUSTMENT 0
@ -300,7 +300,7 @@ LOCAL(vmJumpAndInvoke_argumentTest):
#elif defined __i386__ #elif defined __i386__
#define THREAD_STACK 2148 #define THREAD_STACK 2148
#define THREAD_SCRATCH 2152 #define THREAD_SCRATCH 2156
#ifdef AVIAN_USE_FRAME_POINTER #ifdef AVIAN_USE_FRAME_POINTER
# define ALIGNMENT_ADJUSTMENT 0 # define ALIGNMENT_ADJUSTMENT 0

View File

@ -235,6 +235,7 @@ class MyThread: public Thread {
Thread(m, javaThread, parent), Thread(m, javaThread, parent),
ip(0), ip(0),
stack(0), stack(0),
newStack(0),
scratch(0), scratch(0),
continuation(0), continuation(0),
exceptionStackAdjustment(0), exceptionStackAdjustment(0),
@ -261,6 +262,7 @@ class MyThread: public Thread {
void* ip; void* ip;
void* stack; void* stack;
void* newStack;
void* scratch; void* scratch;
object continuation; object continuation;
uintptr_t exceptionStackAdjustment; uintptr_t exceptionStackAdjustment;
@ -7620,11 +7622,11 @@ invokeNative(MyThread* t)
stack += t->arch->frameReturnAddressSize(); stack += t->arch->frameReturnAddressSize();
transition(t, getIp(t), stack, t->continuation, t->trace);
t->trace->targetMethod = 0; t->trace->targetMethod = 0;
t->trace->nativeMethod = 0; t->trace->nativeMethod = 0;
t->newStack = stack;
return result; return result;
} }
@ -9903,7 +9905,7 @@ compileThunks(MyThread* t, FixedAllocator* allocator)
compileCall(t, &context, invokeNativeIndex); compileCall(t, &context, invokeNativeIndex);
a->popFrameAndUpdateStackAndReturn a->popFrameAndUpdateStackAndReturn
(t->arch->alignFrameSize(1), TargetThreadStack); (t->arch->alignFrameSize(1), TargetThreadNewStack);
p->thunks.native.length = a->endBlock(false)->resolve(0, 0); p->thunks.native.length = a->endBlock(false)->resolve(0, 0);

View File

@ -10,11 +10,11 @@
#ifdef __x86_64__ #ifdef __x86_64__
#define THREAD_CONTINUATION 2240 #define THREAD_CONTINUATION 2248
#define THREAD_EXCEPTION 80 #define THREAD_EXCEPTION 80
#define THREAD_EXCEPTION_STACK_ADJUSTMENT 2248 #define THREAD_EXCEPTION_STACK_ADJUSTMENT 2256
#define THREAD_EXCEPTION_OFFSET 2256 #define THREAD_EXCEPTION_OFFSET 2264
#define THREAD_EXCEPTION_HANDLER 2264 #define THREAD_EXCEPTION_HANDLER 2272
#define CONTINUATION_NEXT 8 #define CONTINUATION_NEXT 8
#define CONTINUATION_ADDRESS 32 #define CONTINUATION_ADDRESS 32
@ -91,11 +91,11 @@ LOCAL(vmInvoke_exit):
#elif defined __i386__ #elif defined __i386__
#define THREAD_CONTINUATION 2156 #define THREAD_CONTINUATION 2160
#define THREAD_EXCEPTION 44 #define THREAD_EXCEPTION 44
#define THREAD_EXCEPTION_STACK_ADJUSTMENT 2160 #define THREAD_EXCEPTION_STACK_ADJUSTMENT 2164
#define THREAD_EXCEPTION_OFFSET 2164 #define THREAD_EXCEPTION_OFFSET 2168
#define THREAD_EXCEPTION_HANDLER 2168 #define THREAD_EXCEPTION_HANDLER 2172
#define CONTINUATION_NEXT 4 #define CONTINUATION_NEXT 4
#define CONTINUATION_ADDRESS 16 #define CONTINUATION_ADDRESS 16

View File

@ -94,13 +94,14 @@ const unsigned TargetBytesPerWord = 8;
const unsigned TargetThreadIp = 2216; const unsigned TargetThreadIp = 2216;
const unsigned TargetThreadStack = 2224; const unsigned TargetThreadStack = 2224;
const unsigned TargetThreadTailAddress = 2272; const unsigned TargetThreadNewStack = 2232;
const unsigned TargetThreadVirtualCallTarget = 2280; const unsigned TargetThreadTailAddress = 2280;
const unsigned TargetThreadVirtualCallIndex = 2288; const unsigned TargetThreadVirtualCallTarget = 2288;
const unsigned TargetThreadHeapImage = 2296; const unsigned TargetThreadVirtualCallIndex = 2296;
const unsigned TargetThreadCodeImage = 2304; const unsigned TargetThreadHeapImage = 2304;
const unsigned TargetThreadThunkTable = 2312; const unsigned TargetThreadCodeImage = 2312;
const unsigned TargetThreadStackLimit = 2360; const unsigned TargetThreadThunkTable = 2320;
const unsigned TargetThreadStackLimit = 2368;
const unsigned TargetClassFixedSize = 12; const unsigned TargetClassFixedSize = 12;
const unsigned TargetClassArrayElementSize = 14; const unsigned TargetClassArrayElementSize = 14;
@ -124,13 +125,14 @@ const unsigned TargetBytesPerWord = 4;
const unsigned TargetThreadIp = 2144; const unsigned TargetThreadIp = 2144;
const unsigned TargetThreadStack = 2148; const unsigned TargetThreadStack = 2148;
const unsigned TargetThreadTailAddress = 2172; const unsigned TargetThreadNewStack = 2152;
const unsigned TargetThreadVirtualCallTarget = 2176; const unsigned TargetThreadTailAddress = 2176;
const unsigned TargetThreadVirtualCallIndex = 2180; const unsigned TargetThreadVirtualCallTarget = 2180;
const unsigned TargetThreadHeapImage = 2184; const unsigned TargetThreadVirtualCallIndex = 2184;
const unsigned TargetThreadCodeImage = 2188; const unsigned TargetThreadHeapImage = 2188;
const unsigned TargetThreadThunkTable = 2192; const unsigned TargetThreadCodeImage = 2192;
const unsigned TargetThreadStackLimit = 2216; const unsigned TargetThreadThunkTable = 2198;
const unsigned TargetThreadStackLimit = 2220;
const unsigned TargetClassFixedSize = 8; const unsigned TargetClassFixedSize = 8;
const unsigned TargetClassArrayElementSize = 10; const unsigned TargetClassArrayElementSize = 10;

View File

@ -2524,10 +2524,10 @@ nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED,
// skip stack overflow check, if present: // skip stack overflow check, if present:
if (TargetBytesPerWord == 4) { if (TargetBytesPerWord == 4) {
if (*start == 0x39) { if (*start == 0x39) {
start += 11; start += 12;
} }
} else if (*start == 0x48 and start[1] == 0x39) { } else if (*start == 0x48 and start[1] == 0x39) {
start += 12; start += 13;
} }
if (instruction <= start) { if (instruction <= start) {