Added new parameter "skipIframes" to arch_debug_get_stack_trace(). That
many iframes are supposed to be skipped before recording the stack trace. Currently implemented for x86 only. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27529 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -22,7 +22,7 @@ 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 arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount,
|
||||||
int32 skipFrames, bool userOnly);
|
int32 skipIframes, int32 skipFrames, bool userOnly);
|
||||||
void *arch_debug_get_interrupt_pc();
|
void *arch_debug_get_interrupt_pc();
|
||||||
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);
|
||||||
|
|||||||
@@ -286,8 +286,9 @@ arch_debug_get_caller(void)
|
|||||||
|
|
||||||
int32
|
int32
|
||||||
arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount,
|
arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount,
|
||||||
int32 skipFrames, bool userOnly)
|
int32 skipIframes, int32 skipFrames, bool userOnly)
|
||||||
{
|
{
|
||||||
|
// TODO: Support skipIframes!
|
||||||
struct iframe_stack *frameStack;
|
struct iframe_stack *frameStack;
|
||||||
addr_t framePointer;
|
addr_t framePointer;
|
||||||
int32 count = 0;
|
int32 count = 0;
|
||||||
|
|||||||
@@ -286,6 +286,15 @@ arch_debug_get_caller(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount,
|
||||||
|
int32 skipIframes, int32 skipFrames, bool userOnly)
|
||||||
|
{
|
||||||
|
// TODO: Implement!
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void*
|
void*
|
||||||
arch_debug_get_interrupt_pc()
|
arch_debug_get_interrupt_pc()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -746,12 +746,27 @@ arch_debug_get_caller(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Captures a stack trace (the return addresses) of the current thread.
|
||||||
|
\param returnAddresses The array the return address shall be written to.
|
||||||
|
\param maxCount The maximum number of return addresses to be captured.
|
||||||
|
\param skipIframes The number of interrupt frames that shall be skipped. If
|
||||||
|
greater than 0, \a skipFrames is ignored.
|
||||||
|
\param skipFrames The number of stack frames that shall be skipped.
|
||||||
|
\param userOnly If \c true, only userland return addresses are captured.
|
||||||
|
\return The number of return addresses written to the given array.
|
||||||
|
*/
|
||||||
int32
|
int32
|
||||||
arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount,
|
arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount,
|
||||||
int32 skipFrames, bool userOnly)
|
int32 skipIframes, int32 skipFrames, bool userOnly)
|
||||||
{
|
{
|
||||||
// always skip our own frame
|
// Keep skipping normal stack frames until we've skipped the iframes we're
|
||||||
skipFrames++;
|
// supposed to skip.
|
||||||
|
if (skipIframes > 0) {
|
||||||
|
skipFrames = INT_MAX;
|
||||||
|
} else {
|
||||||
|
// always skip our own frame
|
||||||
|
skipFrames++;
|
||||||
|
}
|
||||||
|
|
||||||
struct thread* thread = thread_get_current_thread();
|
struct thread* thread = thread_get_current_thread();
|
||||||
int32 count = 0;
|
int32 count = 0;
|
||||||
@@ -769,6 +784,11 @@ arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount,
|
|||||||
struct iframe *frame = (struct iframe*)ebp;
|
struct iframe *frame = (struct iframe*)ebp;
|
||||||
eip = frame->eip;
|
eip = frame->eip;
|
||||||
nextEbp = frame->ebp;
|
nextEbp = frame->ebp;
|
||||||
|
|
||||||
|
if (skipIframes > 0) {
|
||||||
|
if (--skipIframes == 0)
|
||||||
|
skipFrames = 1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (get_next_frame(ebp, &nextEbp, &eip) != B_OK)
|
if (get_next_frame(ebp, &nextEbp, &eip) != B_OK)
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1158,7 +1158,8 @@ capture_tracing_stack_trace(int32 maxCount, int32 skipFrames, bool userOnly)
|
|||||||
|
|
||||||
if (stackTrace != NULL) {
|
if (stackTrace != NULL) {
|
||||||
stackTrace->depth = arch_debug_get_stack_trace(
|
stackTrace->depth = arch_debug_get_stack_trace(
|
||||||
stackTrace->return_addresses, maxCount, skipFrames + 1, userOnly);
|
stackTrace->return_addresses, maxCount, 0, skipFrames + 1,
|
||||||
|
userOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
return stackTrace;
|
return stackTrace;
|
||||||
|
|||||||
@@ -1224,7 +1224,7 @@ get_caller()
|
|||||||
// this makes certain assumptions about how the code for the functions
|
// this makes certain assumptions about how the code for the functions
|
||||||
// ends up in the kernel object.
|
// ends up in the kernel object.
|
||||||
addr_t returnAddresses[5];
|
addr_t returnAddresses[5];
|
||||||
int32 depth = arch_debug_get_stack_trace(returnAddresses, 5, 1, false);
|
int32 depth = arch_debug_get_stack_trace(returnAddresses, 5, 0, 1, false);
|
||||||
|
|
||||||
// find the first return address inside the VIP allocator
|
// find the first return address inside the VIP allocator
|
||||||
int32 i = 0;
|
int32 i = 0;
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ get_caller()
|
|||||||
// this makes certain assumptions about how the code for the functions
|
// this makes certain assumptions about how the code for the functions
|
||||||
// ends up in the kernel object.
|
// ends up in the kernel object.
|
||||||
addr_t returnAddresses[5];
|
addr_t returnAddresses[5];
|
||||||
int32 depth = arch_debug_get_stack_trace(returnAddresses, 5, 1, false);
|
int32 depth = arch_debug_get_stack_trace(returnAddresses, 5, 0, 1, false);
|
||||||
for (int32 i = 0; i < depth; i++) {
|
for (int32 i = 0; i < depth; i++) {
|
||||||
if (returnAddresses[i] < (addr_t)&get_caller
|
if (returnAddresses[i] < (addr_t)&get_caller
|
||||||
|| returnAddresses[i] > (addr_t)&malloc_referenced_release) {
|
|| returnAddresses[i] > (addr_t)&malloc_referenced_release) {
|
||||||
|
|||||||
Reference in New Issue
Block a user