kernel/x86_64: stacktrace for threads in compatibility mode.
* add compat_stack_frame struct. * user symbols are't yet looked up in compatibility mode. Change-Id: I94b45f25564c246bb174f9491f4abc4aa8676549
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright 2018, Jérôme Duval, [email protected].
|
||||||
* Copyright 2009-2011, Ingo Weinhold, [email protected].
|
* Copyright 2009-2011, Ingo Weinhold, [email protected].
|
||||||
* Copyright 2002-2008, Axel Dörfler, [email protected].
|
* Copyright 2002-2008, Axel Dörfler, [email protected].
|
||||||
* Copyright 2012, Alex Smith, [email protected].
|
* Copyright 2012, Alex Smith, [email protected].
|
||||||
@@ -35,6 +36,20 @@ struct stack_frame {
|
|||||||
addr_t return_address;
|
addr_t return_address;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _COMPAT_MODE
|
||||||
|
|
||||||
|
|
||||||
|
typedef uint32 compat_addr_t;
|
||||||
|
struct compat_stack_frame {
|
||||||
|
compat_addr_t previous;
|
||||||
|
compat_addr_t return_address;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _COMPAT_MODE
|
||||||
|
|
||||||
|
|
||||||
#define NUM_PREVIOUS_LOCATIONS 32
|
#define NUM_PREVIOUS_LOCATIONS 32
|
||||||
|
|
||||||
|
|
||||||
@@ -100,6 +115,28 @@ get_next_frame_debugger(addr_t bp, addr_t* _next, addr_t* _ip)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _COMPAT_MODE
|
||||||
|
|
||||||
|
|
||||||
|
/*! Safe to be called only from inside the debugger.
|
||||||
|
*/
|
||||||
|
static status_t
|
||||||
|
compat_get_next_frame_debugger(addr_t bp, addr_t* _next, addr_t* _ip)
|
||||||
|
{
|
||||||
|
compat_stack_frame frame;
|
||||||
|
if (debug_memcpy(B_CURRENT_TEAM, &frame, (void*)bp, sizeof(frame)) != B_OK)
|
||||||
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
|
*_ip = (addr_t)frame.return_address;
|
||||||
|
*_next = (addr_t)frame.previous;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _COMPAT_MODE
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
lookup_symbol(Thread* thread, addr_t address, addr_t* _baseAddress,
|
lookup_symbol(Thread* thread, addr_t address, addr_t* _baseAddress,
|
||||||
const char** _symbolName, const char** _imageName, bool* _exactMatch)
|
const char** _symbolName, const char** _imageName, bool* _exactMatch)
|
||||||
@@ -375,7 +412,7 @@ print_stack_frame(Thread* thread, addr_t ip, addr_t bp, addr_t nextBp,
|
|||||||
const char* image;
|
const char* image;
|
||||||
addr_t baseAddress;
|
addr_t baseAddress;
|
||||||
bool exactMatch;
|
bool exactMatch;
|
||||||
status_t status;
|
status_t status = B_ERROR;
|
||||||
addr_t diff;
|
addr_t diff;
|
||||||
|
|
||||||
diff = nextBp - bp;
|
diff = nextBp - bp;
|
||||||
@@ -384,8 +421,18 @@ print_stack_frame(Thread* thread, addr_t ip, addr_t bp, addr_t nextBp,
|
|||||||
if (diff & ~((addr_t)-1 >> 1))
|
if (diff & ~((addr_t)-1 >> 1))
|
||||||
diff = 0;
|
diff = 0;
|
||||||
|
|
||||||
|
#ifdef _COMPAT_MODE
|
||||||
|
// only lookup kernel symbols in compatibility mode
|
||||||
|
// TODO: support lookup user symbols in compatibility mode
|
||||||
|
if ((thread->flags & THREAD_FLAGS_COMPAT_MODE) == 0
|
||||||
|
|| IS_KERNEL_ADDRESS(ip)) {
|
||||||
|
status = lookup_symbol(thread, ip, &baseAddress, &symbol, &image,
|
||||||
|
&exactMatch);
|
||||||
|
}
|
||||||
|
#else
|
||||||
status = lookup_symbol(thread, ip, &baseAddress, &symbol, &image,
|
status = lookup_symbol(thread, ip, &baseAddress, &symbol, &image,
|
||||||
&exactMatch);
|
&exactMatch);
|
||||||
|
#endif
|
||||||
|
|
||||||
kprintf("%2" B_PRId32 " %0*lx (+%4ld) %0*lx ", callIndex,
|
kprintf("%2" B_PRId32 " %0*lx (+%4ld) %0*lx ", callIndex,
|
||||||
B_PRINTF_POINTER_WIDTH, bp, diff, B_PRINTF_POINTER_WIDTH, ip);
|
B_PRINTF_POINTER_WIDTH, bp, diff, B_PRINTF_POINTER_WIDTH, ip);
|
||||||
@@ -724,6 +771,16 @@ stack_trace(int argc, char** argv)
|
|||||||
} else {
|
} else {
|
||||||
addr_t ip, nextBp;
|
addr_t ip, nextBp;
|
||||||
|
|
||||||
|
#ifdef _COMPAT_MODE
|
||||||
|
if ((thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0
|
||||||
|
&& !is_kernel_stack_address(thread, bp)) {
|
||||||
|
if (compat_get_next_frame_debugger(bp, &nextBp, &ip) != B_OK) {
|
||||||
|
kprintf("%0*lx -- read fault\n", B_PRINTF_POINTER_WIDTH,
|
||||||
|
bp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
if (get_next_frame_debugger(bp, &nextBp, &ip) != B_OK) {
|
if (get_next_frame_debugger(bp, &nextBp, &ip) != B_OK) {
|
||||||
kprintf("%0*lx -- read fault\n", B_PRINTF_POINTER_WIDTH, bp);
|
kprintf("%0*lx -- read fault\n", B_PRINTF_POINTER_WIDTH, bp);
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user