* 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
This commit is contained in:
Ingo Weinhold
2008-05-17 18:59:19 +00:00
parent ec1f43f304
commit b3d6c12dbf
3 changed files with 38 additions and 12 deletions
+1
View File
@@ -23,6 +23,7 @@
#define BLOCK_CACHE_TRANSACTION_TRACING 0 #define BLOCK_CACHE_TRANSACTION_TRACING 0
#define BMESSAGE_TRACING 0 #define BMESSAGE_TRACING 0
#define KERNEL_HEAP_TRACING 0 #define KERNEL_HEAP_TRACING 0
#define KTRACE_PRINTF_STACK_TRACE 0 /* stack trace depth */
#define PAGE_ALLOCATION_TRACING 0 #define PAGE_ALLOCATION_TRACING 0
#define PARANOIA_TRACING 0 #define PARANOIA_TRACING 0
#define PARANOIA_TRACING_STACK_TRACE 0 /* stack trace depth */ #define PARANOIA_TRACING_STACK_TRACE 0 /* stack trace depth */
+13 -3
View File
@@ -62,7 +62,7 @@ class TraceOutput {
bigtime_t fLastEntryTime; bigtime_t fLastEntryTime;
}; };
class TraceEntry : public trace_entry { class TraceEntry {
public: public:
TraceEntry(); TraceEntry();
virtual ~TraceEntry(); virtual ~TraceEntry();
@@ -70,12 +70,22 @@ class TraceEntry : public trace_entry {
virtual void Dump(TraceOutput& out); virtual void Dump(TraceOutput& out);
virtual void DumpStackTrace(TraceOutput& out); virtual void DumpStackTrace(TraceOutput& out);
size_t Size() const { return size; } size_t Size() const { return ToTraceEntry()->size; }
uint16 Flags() const { return flags; } uint16 Flags() const { return ToTraceEntry()->flags; }
void Initialized(); void Initialized();
void* operator new(size_t size, const std::nothrow_t&) throw(); 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 { class AbstractTraceEntry : public TraceEntry {
+24 -9
View File
@@ -96,7 +96,7 @@ free_first_entry()
// a buffer entry -- just skip it // a buffer entry -- just skip it
} else if (sFirstEntry->flags & ENTRY_INITIALIZED) { } else if (sFirstEntry->flags & ENTRY_INITIALIZED) {
// fully initialized TraceEntry -- destroy it // fully initialized TraceEntry -- destroy it
((TraceEntry*)sFirstEntry)->~TraceEntry(); TraceEntry::FromTraceEntry(sFirstEntry)->~TraceEntry();
sEntries--; sEntries--;
} else { } else {
// Not fully initialized TraceEntry. We can't free it, since // Not fully initialized TraceEntry. We can't free it, since
@@ -326,7 +326,7 @@ void
TraceEntry::Initialized() TraceEntry::Initialized()
{ {
#if ENABLE_TRACING #if ENABLE_TRACING
flags |= ENTRY_INITIALIZED; ToTraceEntry()->flags |= ENTRY_INITIALIZED;
sWritten++; sWritten++;
#endif #endif
} }
@@ -336,7 +336,8 @@ void*
TraceEntry::operator new(size_t size, const std::nothrow_t&) throw() TraceEntry::operator new(size_t size, const std::nothrow_t&) throw()
{ {
#if ENABLE_TRACING #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 #endif
return NULL; return NULL;
} }
@@ -396,6 +397,10 @@ class KernelTraceEntry : public AbstractTraceEntry {
{ {
fMessage = alloc_tracing_buffer_strcpy(message, 256, false); 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(); Initialized();
} }
@@ -404,8 +409,18 @@ class KernelTraceEntry : public AbstractTraceEntry {
out.Print("kern: %s", fMessage); out.Print("kern: %s", fMessage);
} }
#if KTRACE_PRINTF_STACK_TRACE
virtual void DumpStackTrace(TraceOutput& out)
{
out.PrintStackTrace(fStackTrace);
}
#endif
private: private:
char* fMessage; char* fMessage;
#if KTRACE_PRINTF_STACK_TRACE
tracing_stack_trace* fStackTrace;
#endif
}; };
@@ -704,7 +719,7 @@ public:
TraceEntry* Current() const TraceEntry* Current() const
{ {
return (TraceEntry*)fEntry; return TraceEntry::FromTraceEntry(fEntry);
} }
TraceEntry* Next() TraceEntry* Next()
@@ -981,10 +996,10 @@ dump_tracing_internal(int argc, char** argv, WrapperTraceFilter* wrapperFilter)
lastToDump = -1; lastToDump = -1;
while (iterator.Index() > firstToCheck) { while (iterator.Index() > firstToCheck) {
TraceEntry* entry = iterator.Previous(); TraceEntry* entry = iterator.Previous();
if ((entry->flags & ENTRY_INITIALIZED) != 0) { if ((entry->Flags() & ENTRY_INITIALIZED) != 0) {
out.Clear(); out.Clear();
if (filter->Filter(entry, out)) { if (filter->Filter(entry, out)) {
entry->flags |= FILTER_MATCH; entry->ToTraceEntry()->flags |= FILTER_MATCH;
if (lastToDump == -1) if (lastToDump == -1)
lastToDump = iterator.Index(); lastToDump = iterator.Index();
firstToDump = iterator.Index(); firstToDump = iterator.Index();
@@ -993,7 +1008,7 @@ dump_tracing_internal(int argc, char** argv, WrapperTraceFilter* wrapperFilter)
if (matching >= count) if (matching >= count)
break; break;
} else } else
entry->flags &= ~FILTER_MATCH; entry->ToTraceEntry()->flags &= ~FILTER_MATCH;
} }
} }
@@ -1023,10 +1038,10 @@ dump_tracing_internal(int argc, char** argv, WrapperTraceFilter* wrapperFilter)
break; break;
} }
if ((entry->flags & ENTRY_INITIALIZED) != 0) { if ((entry->Flags() & ENTRY_INITIALIZED) != 0) {
out.Clear(); out.Clear();
if (filter && (markedMatching if (filter && (markedMatching
? (entry->flags & FILTER_MATCH) == 0 ? (entry->Flags() & FILTER_MATCH) == 0
: !filter->Filter(entry, out))) { : !filter->Filter(entry, out))) {
continue; continue;
} }