From 8e43ece8b85e5842fad76f130eae4dfd7e5eacd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 13 Jan 2008 02:50:32 +0000 Subject: [PATCH] Some more work on the tracing API: * Added function to allocate space in the buffer. * Dump() now fills a buffer instead of printing its data directly. * This allows the new "#pattern" argument of the "traced" command to work. When you're using that, the index of the trace entry is printed out, too, so that you can then get a full dump around the hits. * Added an AddDump() method to the AbstractTraceEntry class so that there is no need to call the inherited function anymore. * Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23479 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/tracing.h | 22 ++- .../file_systems/bfs/BlockAllocator.cpp | 14 +- src/add-ons/kernel/file_systems/bfs/Inode.cpp | 22 ++- src/system/kernel/debug/tracing.cpp | 146 +++++++++++------- 4 files changed, 128 insertions(+), 76 deletions(-) diff --git a/headers/private/kernel/tracing.h b/headers/private/kernel/tracing.h index d8eaacb537..9c393ba51d 100644 --- a/headers/private/kernel/tracing.h +++ b/headers/private/kernel/tracing.h @@ -5,6 +5,8 @@ #include #include +#include + #define ENABLE_TRACING 0 #define MAX_TRACE_SIZE 1024 * 1024 @@ -23,7 +25,7 @@ class TraceEntry : trace_entry { TraceEntry(); virtual ~TraceEntry(); - virtual void Dump(); + virtual void Dump(char* buffer, size_t bufferSize); size_t Size() const { return size; } uint16 Flags() const { return flags; } @@ -42,9 +44,15 @@ class AbstractTraceEntry : public TraceEntry { { } - virtual void Dump() + virtual void Dump(char* buffer, size_t bufferSize) + { + int length = snprintf(buffer, bufferSize, "[%6ld] %Ld: ", + fThread, fTime); + AddDump(buffer + length, bufferSize - length); + } + + virtual void AddDump(char* buffer, size_t bufferSize) { - kprintf("[%6ld] %Ld: ", fThread, fTime); } thread_id Thread() const { return fThread; } @@ -58,8 +66,14 @@ class AbstractTraceEntry : public TraceEntry { #endif // __cplusplus #ifdef __cplusplus -extern "C" +extern "C" { #endif + +uint8* alloc_tracing_buffer(size_t size); status_t tracing_init(void); +#ifdef __cplusplus +} +#endif + #endif /* KERNEL_UTIL_TRACING_H */ diff --git a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp index 3227bad7f8..06daa40c90 100644 --- a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp +++ b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp @@ -48,11 +48,10 @@ class Allocate : public AbstractTraceEntry { Initialized(); } - virtual void Dump() + virtual void AddDump(char *buffer, size_t size) { - AbstractTraceEntry::Dump(); - kprintf("alloc %lu.%u.%u\n", fRun.AllocationGroup(), fRun.Start(), - fRun.Length()); + snprintf(buffer, size, "alloc %lu.%u.%u", fRun.AllocationGroup(), + fRun.Start(), fRun.Length()); } private: @@ -68,11 +67,10 @@ class Free : public AbstractTraceEntry { Initialized(); } - virtual void Dump() + virtual void AddDump(char *buffer, size_t size) { - AbstractTraceEntry::Dump(); - kprintf("free %lu.%u.%u\n", fRun.AllocationGroup(), fRun.Start(), - fRun.Length()); + snprintf(buffer, size, "free %lu.%u.%u\n", fRun.AllocationGroup(), + fRun.Start(), fRun.Length()); } private: diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.cpp b/src/add-ons/kernel/file_systems/bfs/Inode.cpp index 10a36ddfda..2aa5139697 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Inode.cpp @@ -36,12 +36,11 @@ class Create : public AbstractTraceEntry { Initialized(); } - virtual void Dump() + virtual void AddDump(char *buffer, size_t size) { - AbstractTraceEntry::Dump(); - kprintf("CREATE %Ld (%p), parent %Ld (%p), \"%s\", mode %lx, " - "omode %x, type %lx\n", fID, fInode, fParentID, fParent, - fName, fMode, fOpenMode, fType); + snprintf(buffer, size, "CREATE %Ld (%p), parent %Ld (%p), \"%s\", " + "mode %lx, omode %x, type %lx\n", fID, fInode, fParentID, + fParent, fName, fMode, fOpenMode, fType); } private: @@ -67,10 +66,10 @@ class Remove : public AbstractTraceEntry { Initialized(); } - virtual void Dump() + virtual void AddDump(char *buffer, size_t size) { - AbstractTraceEntry::Dump(); - kprintf("REMOVE %Ld (%p), \"%s\"\n", fID, fInode, fName); + snprintf(buffer, size, "REMOVE %Ld (%p), \"%s\"\n", fID, fInode, + fName); } private: @@ -91,11 +90,10 @@ class Resize : public AbstractTraceEntry { Initialized(); } - virtual void Dump() + virtual void AddDump(char *buffer, size_t size) { - AbstractTraceEntry::Dump(); - kprintf("RESIZE %Ld (%p), %Ld -> %Ld\n", fID, fInode, fOldSize, - fNewSize); + snprintf(buffer, size, "RESIZE %Ld (%p), %Ld -> %Ld\n", fID, fInode, + fOldSize, fNewSize); } private: diff --git a/src/system/kernel/debug/tracing.cpp b/src/system/kernel/debug/tracing.cpp index 4b62035ee8..8bb53d15f0 100644 --- a/src/system/kernel/debug/tracing.cpp +++ b/src/system/kernel/debug/tracing.cpp @@ -9,7 +9,8 @@ enum { WRAP_ENTRY = 0x01, - ENTRY_INITIALIZED = 0x02 + ENTRY_INITIALIZED = 0x02, + BUFFER_ENTRY = 0x04 }; static const size_t kBufferSize = MAX_TRACE_SIZE / 4 - 1; @@ -36,9 +37,9 @@ next_entry(trace_entry* entry) static void -make_space(size_t size) +make_space(size_t needed) { - if (sBufferEnd + size / 4 > sBuffer + kBufferSize - 1) { + if (sBufferEnd + needed / 4 > sBuffer + kBufferSize - 1) { sBufferEnd->size = 0; sBufferEnd->flags = WRAP_ENTRY; sBufferEnd = sBuffer; @@ -48,62 +49,26 @@ make_space(size_t size) if (diff < 0) sBufferEnd = sBuffer; else - size -= diff; + needed -= diff; while (true) { - uint16 skip = sBufferStart->size; + uint16 freed = sBufferStart->size; sBufferStart = next_entry(sBufferStart); if (sBufferStart == NULL) - sBufferStart = sBuffer; + sBufferStart = sBufferEnd; sEntries--; - if (size <= skip) + if (needed <= freed) break; - size -= skip; + needed -= freed; } } -#endif // ENABLE_TRACING - - -// #pragma mark - - - -TraceEntry::TraceEntry() +trace_entry* +allocate_entry(size_t size) { -} - - -TraceEntry::~TraceEntry() -{ -} - - -void -TraceEntry::Dump() -{ -#if ENABLE_TRACING - // to be overloaded by subclasses - kprintf("ENTRY %p\n", this); -#endif -} - - -void -TraceEntry::Initialized() -{ -#if ENABLE_TRACING - flags |= ENTRY_INITIALIZED; -#endif -} - - -void* -TraceEntry::operator new(size_t size, const std::nothrow_t&) throw() -{ -#if ENABLE_TRACING if (sBuffer == NULL) return NULL; @@ -127,7 +92,50 @@ TraceEntry::operator new(size_t size, const std::nothrow_t&) throw() sBufferEnd += size >> 2; sEntries++; return entry; -#else // !ENABLE_TRACING +} + + +#endif // ENABLE_TRACING + + +// #pragma mark - + + +TraceEntry::TraceEntry() +{ +} + + +TraceEntry::~TraceEntry() +{ +} + + +void +TraceEntry::Dump(char* buffer, size_t bufferSize) +{ +#if ENABLE_TRACING + // to be overloaded by subclasses + snprintf(buffer, bufferSize, "ENTRY %p", this); +#endif +} + + +void +TraceEntry::Initialized() +{ +#if ENABLE_TRACING + flags |= ENTRY_INITIALIZED; +#endif +} + + +void* +TraceEntry::operator new(size_t size, const std::nothrow_t&) throw() +{ +#if ENABLE_TRACING + return allocate_entry(size); +#else return NULL; #endif } @@ -142,6 +150,10 @@ TraceEntry::operator new(size_t size, const std::nothrow_t&) throw() int dump_tracing(int argc, char** argv) { + const char *pattern = NULL; + if (argv[argc - 1][0] == '#') + pattern = argv[--argc] + 1; + int32 count = 30; if (argc == 2) count = strtol(argv[1], NULL, 0); @@ -152,7 +164,7 @@ dump_tracing(int argc, char** argv) start = strtol(argv[1], NULL, 0); count = strtol(argv[2], NULL, 0); } else if (argc > 3) { - kprintf("usage: %s [start] [count]\n", argv[0]); + kprintf("usage: %s [start] [count] [#pattern]\n", argv[0]); return 0; } // TODO: add pattern matching mechanism for the class name @@ -168,11 +180,26 @@ dump_tracing(int argc, char** argv) continue; if (index > start + count) break; + if ((entry->flags & BUFFER_ENTRY) != 0) { + // skip buffer entries + index--; + continue; + } - if ((current->flags & ENTRY_INITIALIZED) != 0) - ((TraceEntry*)current)->Dump(); - else - kprintf("** uninitialized entry **\n"); + if ((current->flags & ENTRY_INITIALIZED) != 0) { + char buffer[256]; + buffer[0] = '\0'; + ((TraceEntry*)current)->Dump(buffer, sizeof(buffer)); + + if (pattern != NULL && strstr(buffer, pattern) == NULL) + continue; + + if (pattern != NULL) + kprintf("%5ld. %s\n", index, buffer); + else + kprintf("%s\n", buffer); + } else + kprintf("%5ld. ** uninitialized entry **\n", index); } kprintf("%ld of %ld entries.\n", count, sEntries); @@ -182,6 +209,21 @@ dump_tracing(int argc, char** argv) #endif // ENABLE_TRACING +extern "C" uint8* +alloc_tracing_buffer(size_t size) +{ +#if ENABLE_TRACING + trace_entry* entry = allocate_entry(size + sizeof(trace_entry)); + if (entry == NULL) + return NULL; + + entry->flags = BUFFER_ENTRY; + return (uint8*)(entry + 1); +#else + return NULL; +#endif +} + extern "C" status_t tracing_init(void)