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:
Ingo Weinhold 2008-09-15 13:09:14 +00:00
parent 7bc02c61bd
commit e670fc6f63
7 changed files with 39 additions and 8 deletions

View File

@ -22,7 +22,7 @@ extern "C" {
status_t arch_debug_init(kernel_args *args);
void *arch_debug_get_caller(void);
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();
bool arch_debug_contains_call(struct thread *thread, const char *symbol,
addr_t start, addr_t end);

View File

@ -286,8 +286,9 @@ arch_debug_get_caller(void)
int32
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;
addr_t framePointer;
int32 count = 0;

View File

@ -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*
arch_debug_get_interrupt_pc()
{

View File

@ -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
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
skipFrames++;
// Keep skipping normal stack frames until we've skipped the iframes we're
// supposed to skip.
if (skipIframes > 0) {
skipFrames = INT_MAX;
} else {
// always skip our own frame
skipFrames++;
}
struct thread* thread = thread_get_current_thread();
int32 count = 0;
@ -769,6 +784,11 @@ arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount,
struct iframe *frame = (struct iframe*)ebp;
eip = frame->eip;
nextEbp = frame->ebp;
if (skipIframes > 0) {
if (--skipIframes == 0)
skipFrames = 1;
}
} else {
if (get_next_frame(ebp, &nextEbp, &eip) != B_OK)
break;

View File

@ -1158,7 +1158,8 @@ capture_tracing_stack_trace(int32 maxCount, int32 skipFrames, bool userOnly)
if (stackTrace != NULL) {
stackTrace->depth = arch_debug_get_stack_trace(
stackTrace->return_addresses, maxCount, skipFrames + 1, userOnly);
stackTrace->return_addresses, maxCount, 0, skipFrames + 1,
userOnly);
}
return stackTrace;

View File

@ -1224,7 +1224,7 @@ get_caller()
// this makes certain assumptions about how the code for the functions
// ends up in the kernel object.
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
int32 i = 0;

View File

@ -267,7 +267,7 @@ get_caller()
// this makes certain assumptions about how the code for the functions
// ends up in the kernel object.
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++) {
if (returnAddresses[i] < (addr_t)&get_caller
|| returnAddresses[i] > (addr_t)&malloc_referenced_release) {