libroot: Add private __arch_get_stack_trace().
It can be used to get a stack trace of the current thread. Note that this works by walking frame pointers and will not produce anything useful if an application is compiled with the frame pointers omitted. The stack base and end addresses have to be provided as arguments and are used to check that the frame pointers fall within that range. These values are thread specific and can be retrieved with get_thread_info(). No other sanity checks (like checking for loops in the linked list) are done. This is a simplified rewrite of the stack trace code from the kernel debugger. As this code is common to x86 and x86_64 but is not generic across architectures I introduced x86_common as a directory to put such sources.
This commit is contained in:
parent
9ac1c4c25e
commit
c012e7e930
@ -44,6 +44,8 @@ bigtime_t __get_system_time_offset();
|
||||
void __init_pwd_backend(void);
|
||||
void __reinit_pwd_backend_after_fork(void);
|
||||
void* __arch_get_caller(void);
|
||||
int32 __arch_get_stack_trace(addr_t* returnAddresses, int32 maxCount,
|
||||
int32 skipFrames, addr_t stackBase, addr_t stackEnd);
|
||||
|
||||
void __set_stack_protection(void);
|
||||
|
||||
|
@ -17,6 +17,8 @@ for architectureObject in [ MultiArchSubDirSetup x86 x86_gcc2 ] {
|
||||
;
|
||||
}
|
||||
|
||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) x86_common ] ;
|
||||
|
||||
MergeObject <$(architecture)>os_arch_$(TARGET_ARCH).o :
|
||||
atomic.S
|
||||
byteorder.S
|
||||
@ -28,6 +30,9 @@ for architectureObject in [ MultiArchSubDirSetup x86 x86_gcc2 ] {
|
||||
tls.c
|
||||
|
||||
$(compatibilitySources)
|
||||
|
||||
# sources from x86_common
|
||||
stack_trace.cpp
|
||||
;
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,10 @@ for architectureObject in [ MultiArchSubDirSetup x86_64 ] {
|
||||
# TODO in time.c!
|
||||
UsePrivateSystemHeaders ;
|
||||
|
||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ;
|
||||
SEARCH_SOURCE +=
|
||||
[ FDirName $(SUBDIR) $(DOTDOT) generic ]
|
||||
[ FDirName $(SUBDIR) $(DOTDOT) x86_common ]
|
||||
;
|
||||
|
||||
MergeObject <$(architecture)>os_arch_$(TARGET_ARCH).o :
|
||||
byteorder.S
|
||||
@ -23,6 +26,10 @@ for architectureObject in [ MultiArchSubDirSetup x86_64 ] {
|
||||
time.cpp
|
||||
tls.cpp
|
||||
|
||||
# sources from x86_common
|
||||
stack_trace.cpp
|
||||
|
||||
# sources from generic
|
||||
generic_atomic.cpp
|
||||
;
|
||||
}
|
||||
|
47
src/system/libroot/os/arch/x86_common/stack_trace.cpp
Normal file
47
src/system/libroot/os/arch/x86_common/stack_trace.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2015 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Lotz, mmlr@mlotz.ch
|
||||
*/
|
||||
|
||||
#include <libroot_private.h>
|
||||
|
||||
|
||||
/*! 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 skipFrames The number of stack frames that shall be skipped.
|
||||
\param stackBase The base address of the thread stack.
|
||||
\param stackEnd The first address past the thread stack.
|
||||
\return The number of return addresses written to the given array.
|
||||
*/
|
||||
int32
|
||||
__arch_get_stack_trace(addr_t* returnAddresses, int32 maxCount,
|
||||
int32 skipFrames, addr_t stackBase, addr_t stackEnd)
|
||||
{
|
||||
int32 count = 0;
|
||||
addr_t basePointer = (addr_t)get_stack_frame();
|
||||
|
||||
while (basePointer != 0 && count < maxCount) {
|
||||
if (basePointer < stackBase || basePointer >= stackEnd)
|
||||
break;
|
||||
|
||||
struct stack_frame {
|
||||
addr_t previous;
|
||||
addr_t return_address;
|
||||
};
|
||||
|
||||
stack_frame* frame = (stack_frame*)basePointer;
|
||||
|
||||
if (skipFrames <= 0)
|
||||
returnAddresses[count++] = frame->return_address;
|
||||
else
|
||||
skipFrames--;
|
||||
|
||||
basePointer = frame->previous;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
Loading…
Reference in New Issue
Block a user