From b3d6c12dbf620c22c071b1a6a4c44dfce88d265c Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sat, 17 May 2008 18:59:19 +0000 Subject: [PATCH] * Fixed kernel tracing for gcc 4. The ABI changed in a way that isn't compatible with what our code assumed (pointers to objects of TraceEntry and its POD base class trace_entry aren't identical anymore). * Added optional stack traces for ktrace_printf() output in the kernel. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25531 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- build/config_headers/tracing_config.h | 1 + headers/private/kernel/tracing.h | 16 ++++++++++--- src/system/kernel/debug/tracing.cpp | 33 +++++++++++++++++++-------- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/build/config_headers/tracing_config.h b/build/config_headers/tracing_config.h index 79165bddfd..818c643d2a 100644 --- a/build/config_headers/tracing_config.h +++ b/build/config_headers/tracing_config.h @@ -23,6 +23,7 @@ #define BLOCK_CACHE_TRANSACTION_TRACING 0 #define BMESSAGE_TRACING 0 #define KERNEL_HEAP_TRACING 0 +#define KTRACE_PRINTF_STACK_TRACE 0 /* stack trace depth */ #define PAGE_ALLOCATION_TRACING 0 #define PARANOIA_TRACING 0 #define PARANOIA_TRACING_STACK_TRACE 0 /* stack trace depth */ diff --git a/headers/private/kernel/tracing.h b/headers/private/kernel/tracing.h index d5204e7599..4e9455bbe2 100644 --- a/headers/private/kernel/tracing.h +++ b/headers/private/kernel/tracing.h @@ -62,7 +62,7 @@ class TraceOutput { bigtime_t fLastEntryTime; }; -class TraceEntry : public trace_entry { +class TraceEntry { public: TraceEntry(); virtual ~TraceEntry(); @@ -70,12 +70,22 @@ class TraceEntry : public trace_entry { virtual void Dump(TraceOutput& out); virtual void DumpStackTrace(TraceOutput& out); - size_t Size() const { return size; } - uint16 Flags() const { return flags; } + size_t Size() const { return ToTraceEntry()->size; } + uint16 Flags() const { return ToTraceEntry()->flags; } void Initialized(); void* operator new(size_t size, const std::nothrow_t&) throw(); + + trace_entry* ToTraceEntry() const + { + return (trace_entry*)this - 1; + } + + static TraceEntry* FromTraceEntry(trace_entry* entry) + { + return (TraceEntry*)(entry + 1); + } }; class AbstractTraceEntry : public TraceEntry { diff --git a/src/system/kernel/debug/tracing.cpp b/src/system/kernel/debug/tracing.cpp index 976441eaac..f1b8136581 100644 --- a/src/system/kernel/debug/tracing.cpp +++ b/src/system/kernel/debug/tracing.cpp @@ -96,7 +96,7 @@ free_first_entry() // a buffer entry -- just skip it } else if (sFirstEntry->flags & ENTRY_INITIALIZED) { // fully initialized TraceEntry -- destroy it - ((TraceEntry*)sFirstEntry)->~TraceEntry(); + TraceEntry::FromTraceEntry(sFirstEntry)->~TraceEntry(); sEntries--; } else { // Not fully initialized TraceEntry. We can't free it, since @@ -326,7 +326,7 @@ void TraceEntry::Initialized() { #if ENABLE_TRACING - flags |= ENTRY_INITIALIZED; + ToTraceEntry()->flags |= ENTRY_INITIALIZED; sWritten++; #endif } @@ -336,7 +336,8 @@ void* TraceEntry::operator new(size_t size, const std::nothrow_t&) throw() { #if ENABLE_TRACING - return allocate_entry(size, 0); + trace_entry* entry = allocate_entry(size + sizeof(trace_entry), 0); + return entry != NULL ? entry + 1 : NULL; #endif return NULL; } @@ -396,6 +397,10 @@ class KernelTraceEntry : public AbstractTraceEntry { { fMessage = alloc_tracing_buffer_strcpy(message, 256, false); +#if KTRACE_PRINTF_STACK_TRACE + fStackTrace = capture_tracing_stack_trace( + KTRACE_PRINTF_STACK_TRACE, 1, false); +#endif Initialized(); } @@ -404,8 +409,18 @@ class KernelTraceEntry : public AbstractTraceEntry { out.Print("kern: %s", fMessage); } +#if KTRACE_PRINTF_STACK_TRACE + virtual void DumpStackTrace(TraceOutput& out) + { + out.PrintStackTrace(fStackTrace); + } +#endif + private: char* fMessage; +#if KTRACE_PRINTF_STACK_TRACE + tracing_stack_trace* fStackTrace; +#endif }; @@ -704,7 +719,7 @@ public: TraceEntry* Current() const { - return (TraceEntry*)fEntry; + return TraceEntry::FromTraceEntry(fEntry); } TraceEntry* Next() @@ -981,10 +996,10 @@ dump_tracing_internal(int argc, char** argv, WrapperTraceFilter* wrapperFilter) lastToDump = -1; while (iterator.Index() > firstToCheck) { TraceEntry* entry = iterator.Previous(); - if ((entry->flags & ENTRY_INITIALIZED) != 0) { + if ((entry->Flags() & ENTRY_INITIALIZED) != 0) { out.Clear(); if (filter->Filter(entry, out)) { - entry->flags |= FILTER_MATCH; + entry->ToTraceEntry()->flags |= FILTER_MATCH; if (lastToDump == -1) lastToDump = iterator.Index(); firstToDump = iterator.Index(); @@ -993,7 +1008,7 @@ dump_tracing_internal(int argc, char** argv, WrapperTraceFilter* wrapperFilter) if (matching >= count) break; } else - entry->flags &= ~FILTER_MATCH; + entry->ToTraceEntry()->flags &= ~FILTER_MATCH; } } @@ -1023,10 +1038,10 @@ dump_tracing_internal(int argc, char** argv, WrapperTraceFilter* wrapperFilter) break; } - if ((entry->flags & ENTRY_INITIALIZED) != 0) { + if ((entry->Flags() & ENTRY_INITIALIZED) != 0) { out.Clear(); if (filter && (markedMatching - ? (entry->flags & FILTER_MATCH) == 0 + ? (entry->Flags() & FILTER_MATCH) == 0 : !filter->Filter(entry, out))) { continue; }