mmlr + bonefish:
* Move struct tracing_stack_trace to tracing.h header. * Add tracing_find_caller_in_stack_trace(). Helper function to get the first return address of a stack trace that is not in one of the given address ranges. * Add AbstractTracingEntryWithStackTrace::StackTrace() getter. * Add tracing_is_entry_valid(). Checks, based on the additionally given time, whether a tracing entry is (probably) still in the tracing buffer. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@43070 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -21,7 +21,11 @@ struct trace_entry {
|
|||||||
uint32 flags : 6;
|
uint32 flags : 6;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tracing_stack_trace;
|
struct tracing_stack_trace {
|
||||||
|
int32 depth;
|
||||||
|
addr_t return_addresses[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
@@ -134,6 +138,11 @@ public:
|
|||||||
|
|
||||||
virtual void DumpStackTrace(TraceOutput& out);
|
virtual void DumpStackTrace(TraceOutput& out);
|
||||||
|
|
||||||
|
tracing_stack_trace* StackTrace() const
|
||||||
|
{
|
||||||
|
return fStackTrace;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef AbstractTraceEntryWithStackTrace TraceEntryBase;
|
typedef AbstractTraceEntryWithStackTrace TraceEntryBase;
|
||||||
|
|
||||||
@@ -244,8 +253,11 @@ private:
|
|||||||
|
|
||||||
int dump_tracing(int argc, char** argv, WrapperTraceFilter* wrapperFilter);
|
int dump_tracing(int argc, char** argv, WrapperTraceFilter* wrapperFilter);
|
||||||
|
|
||||||
|
bool tracing_is_entry_valid(TraceEntry* entry, bigtime_t entryTime);
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -254,8 +266,13 @@ uint8* alloc_tracing_buffer(size_t size);
|
|||||||
uint8* alloc_tracing_buffer_memcpy(const void* source, size_t size, bool user);
|
uint8* alloc_tracing_buffer_memcpy(const void* source, size_t size, bool user);
|
||||||
char* alloc_tracing_buffer_strcpy(const char* source, size_t maxSize,
|
char* alloc_tracing_buffer_strcpy(const char* source, size_t maxSize,
|
||||||
bool user);
|
bool user);
|
||||||
|
|
||||||
struct tracing_stack_trace* capture_tracing_stack_trace(int32 maxCount,
|
struct tracing_stack_trace* capture_tracing_stack_trace(int32 maxCount,
|
||||||
int32 skipFrames, bool kernelOnly);
|
int32 skipFrames, bool kernelOnly);
|
||||||
|
addr_t tracing_find_caller_in_stack_trace(
|
||||||
|
struct tracing_stack_trace* stackTrace, const addr_t excludeRanges[],
|
||||||
|
uint32 excludeRangeCount);
|
||||||
|
|
||||||
void lock_tracing_buffer();
|
void lock_tracing_buffer();
|
||||||
void unlock_tracing_buffer();
|
void unlock_tracing_buffer();
|
||||||
status_t tracing_init(void);
|
status_t tracing_init(void);
|
||||||
|
|||||||
@@ -23,12 +23,6 @@
|
|||||||
#include <vm/vm.h>
|
#include <vm/vm.h>
|
||||||
|
|
||||||
|
|
||||||
struct tracing_stack_trace {
|
|
||||||
int32 depth;
|
|
||||||
addr_t return_addresses[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#if ENABLE_TRACING
|
#if ENABLE_TRACING
|
||||||
|
|
||||||
//#define TRACE_TRACING
|
//#define TRACE_TRACING
|
||||||
@@ -1616,6 +1610,30 @@ capture_tracing_stack_trace(int32 maxCount, int32 skipFrames, bool kernelOnly)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
addr_t
|
||||||
|
tracing_find_caller_in_stack_trace(struct tracing_stack_trace* stackTrace,
|
||||||
|
const addr_t excludeRanges[], uint32 excludeRangeCount)
|
||||||
|
{
|
||||||
|
for (int32 i = 0; i < stackTrace->depth; i++) {
|
||||||
|
addr_t returnAddress = stackTrace->return_addresses[i];
|
||||||
|
|
||||||
|
bool inRange = false;
|
||||||
|
for (uint32 j = 0; j < excludeRangeCount; j++) {
|
||||||
|
if (returnAddress >= excludeRanges[j * 2 + 0]
|
||||||
|
&& returnAddress < excludeRanges[j * 2 + 1]) {
|
||||||
|
inRange = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inRange)
|
||||||
|
return returnAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
dump_tracing(int argc, char** argv, WrapperTraceFilter* wrapperFilter)
|
dump_tracing(int argc, char** argv, WrapperTraceFilter* wrapperFilter)
|
||||||
{
|
{
|
||||||
@@ -1627,6 +1645,26 @@ dump_tracing(int argc, char** argv, WrapperTraceFilter* wrapperFilter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
tracing_is_entry_valid(TraceEntry* candidate, bigtime_t entryTime)
|
||||||
|
{
|
||||||
|
#if ENABLE_TRACING
|
||||||
|
TraceEntryIterator iterator;
|
||||||
|
while (TraceEntry* entry = iterator.Next()) {
|
||||||
|
AbstractTraceEntry* abstract = dynamic_cast<AbstractTraceEntry*>(entry);
|
||||||
|
if (abstract == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// TODO: This could be better by additionally checking if the
|
||||||
|
// candidate entry address falls within the valid entry range.
|
||||||
|
return abstract == candidate || abstract->Time() < entryTime;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
lock_tracing_buffer()
|
lock_tracing_buffer()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user