From 69d7ad7dc5b8d1281aa8f19e2d0347b3721b96a6 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Tue, 1 Nov 2011 17:16:29 +0000 Subject: [PATCH] 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 --- headers/private/kernel/tracing.h | 19 ++++++++++- src/system/kernel/debug/tracing.cpp | 50 +++++++++++++++++++++++++---- 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/headers/private/kernel/tracing.h b/headers/private/kernel/tracing.h index 52f0cf5c93..49999b1b9b 100644 --- a/headers/private/kernel/tracing.h +++ b/headers/private/kernel/tracing.h @@ -21,7 +21,11 @@ struct trace_entry { uint32 flags : 6; }; -struct tracing_stack_trace; +struct tracing_stack_trace { + int32 depth; + addr_t return_addresses[0]; +}; + #ifdef __cplusplus @@ -134,6 +138,11 @@ public: virtual void DumpStackTrace(TraceOutput& out); + tracing_stack_trace* StackTrace() const + { + return fStackTrace; + } + protected: typedef AbstractTraceEntryWithStackTrace TraceEntryBase; @@ -244,8 +253,11 @@ private: int dump_tracing(int argc, char** argv, WrapperTraceFilter* wrapperFilter); +bool tracing_is_entry_valid(TraceEntry* entry, bigtime_t entryTime); + #endif // __cplusplus + #ifdef __cplusplus extern "C" { #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); char* alloc_tracing_buffer_strcpy(const char* source, size_t maxSize, bool user); + struct tracing_stack_trace* 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); + void lock_tracing_buffer(); void unlock_tracing_buffer(); status_t tracing_init(void); diff --git a/src/system/kernel/debug/tracing.cpp b/src/system/kernel/debug/tracing.cpp index 7d487f5e11..45861833f6 100644 --- a/src/system/kernel/debug/tracing.cpp +++ b/src/system/kernel/debug/tracing.cpp @@ -23,12 +23,6 @@ #include -struct tracing_stack_trace { - int32 depth; - addr_t return_addresses[0]; -}; - - #if ENABLE_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 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(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 lock_tracing_buffer() {