Added arch_debug_get_stack_trace() that can be used to get a stack trace
(the list of return addresses) for the current stack. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25204 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -21,8 +21,10 @@ extern "C" {
|
|||||||
|
|
||||||
status_t arch_debug_init(kernel_args *args);
|
status_t arch_debug_init(kernel_args *args);
|
||||||
void *arch_debug_get_caller(void);
|
void *arch_debug_get_caller(void);
|
||||||
|
int32 arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount,
|
||||||
|
int32 skipFrames, bool userOnly);
|
||||||
bool arch_debug_contains_call(struct thread *thread, const char *symbol,
|
bool arch_debug_contains_call(struct thread *thread, const char *symbol,
|
||||||
addr_t start, addr_t end);
|
addr_t start, addr_t end);
|
||||||
void arch_debug_save_registers(int *);
|
void arch_debug_save_registers(int *);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -582,15 +582,51 @@ arch_debug_contains_call(struct thread *thread, const char *symbol,
|
|||||||
void *
|
void *
|
||||||
arch_debug_get_caller(void)
|
arch_debug_get_caller(void)
|
||||||
{
|
{
|
||||||
// It looks like you would get the wrong stack frame here, but
|
|
||||||
// since read_ebp() is an assembler inline macro, GCC seems to
|
|
||||||
// be smart enough to save its original value.
|
|
||||||
struct stack_frame *frame = (struct stack_frame *)x86_read_ebp();
|
struct stack_frame *frame = (struct stack_frame *)x86_read_ebp();
|
||||||
|
|
||||||
return (void *)frame->previous->return_address;
|
return (void *)frame->previous->return_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount,
|
||||||
|
int32 skipFrames, bool userOnly)
|
||||||
|
{
|
||||||
|
// always skip our own frame
|
||||||
|
skipFrames++;
|
||||||
|
|
||||||
|
struct thread* thread = thread_get_current_thread();
|
||||||
|
int32 count = 0;
|
||||||
|
addr_t ebp = x86_read_ebp();
|
||||||
|
bool onKernelStack = true;
|
||||||
|
|
||||||
|
while (ebp != 0 && count < maxCount) {
|
||||||
|
onKernelStack = onKernelStack
|
||||||
|
&& is_kernel_stack_address(thread, ebp);
|
||||||
|
|
||||||
|
addr_t eip;
|
||||||
|
addr_t nextEbp;
|
||||||
|
|
||||||
|
if (onKernelStack && is_iframe(thread, ebp)) {
|
||||||
|
struct iframe *frame = (struct iframe*)ebp;
|
||||||
|
eip = frame->eip;
|
||||||
|
nextEbp = frame->ebp;
|
||||||
|
} else {
|
||||||
|
if (get_next_frame(ebp, &nextEbp, &eip) != B_OK)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skipFrames <= 0 && (!userOnly || IS_USER_ADDRESS(ebp)))
|
||||||
|
returnAddresses[count++] = eip;
|
||||||
|
else
|
||||||
|
skipFrames--;
|
||||||
|
|
||||||
|
ebp = nextEbp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
arch_debug_init(kernel_args *args)
|
arch_debug_init(kernel_args *args)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user