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
This commit is contained in:
Axel Dörfler
2008-01-13 02:50:32 +00:00
parent a5ec34950d
commit 8e43ece8b8
4 changed files with 128 additions and 76 deletions
+18 -4
View File
@@ -5,6 +5,8 @@
#include <SupportDefs.h> #include <SupportDefs.h>
#include <KernelExport.h> #include <KernelExport.h>
#include <stdio.h>
#define ENABLE_TRACING 0 #define ENABLE_TRACING 0
#define MAX_TRACE_SIZE 1024 * 1024 #define MAX_TRACE_SIZE 1024 * 1024
@@ -23,7 +25,7 @@ class TraceEntry : trace_entry {
TraceEntry(); TraceEntry();
virtual ~TraceEntry(); virtual ~TraceEntry();
virtual void Dump(); virtual void Dump(char* buffer, size_t bufferSize);
size_t Size() const { return size; } size_t Size() const { return size; }
uint16 Flags() const { return flags; } 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; } thread_id Thread() const { return fThread; }
@@ -58,8 +66,14 @@ class AbstractTraceEntry : public TraceEntry {
#endif // __cplusplus #endif // __cplusplus
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C" {
#endif #endif
uint8* alloc_tracing_buffer(size_t size);
status_t tracing_init(void); status_t tracing_init(void);
#ifdef __cplusplus
}
#endif
#endif /* KERNEL_UTIL_TRACING_H */ #endif /* KERNEL_UTIL_TRACING_H */
@@ -48,11 +48,10 @@ class Allocate : public AbstractTraceEntry {
Initialized(); Initialized();
} }
virtual void Dump() virtual void AddDump(char *buffer, size_t size)
{ {
AbstractTraceEntry::Dump(); snprintf(buffer, size, "alloc %lu.%u.%u", fRun.AllocationGroup(),
kprintf("alloc %lu.%u.%u\n", fRun.AllocationGroup(), fRun.Start(), fRun.Start(), fRun.Length());
fRun.Length());
} }
private: private:
@@ -68,11 +67,10 @@ class Free : public AbstractTraceEntry {
Initialized(); Initialized();
} }
virtual void Dump() virtual void AddDump(char *buffer, size_t size)
{ {
AbstractTraceEntry::Dump(); snprintf(buffer, size, "free %lu.%u.%u\n", fRun.AllocationGroup(),
kprintf("free %lu.%u.%u\n", fRun.AllocationGroup(), fRun.Start(), fRun.Start(), fRun.Length());
fRun.Length());
} }
private: private:
+10 -12
View File
@@ -36,12 +36,11 @@ class Create : public AbstractTraceEntry {
Initialized(); Initialized();
} }
virtual void Dump() virtual void AddDump(char *buffer, size_t size)
{ {
AbstractTraceEntry::Dump(); snprintf(buffer, size, "CREATE %Ld (%p), parent %Ld (%p), \"%s\", "
kprintf("CREATE %Ld (%p), parent %Ld (%p), \"%s\", mode %lx, " "mode %lx, omode %x, type %lx\n", fID, fInode, fParentID,
"omode %x, type %lx\n", fID, fInode, fParentID, fParent, fParent, fName, fMode, fOpenMode, fType);
fName, fMode, fOpenMode, fType);
} }
private: private:
@@ -67,10 +66,10 @@ class Remove : public AbstractTraceEntry {
Initialized(); Initialized();
} }
virtual void Dump() virtual void AddDump(char *buffer, size_t size)
{ {
AbstractTraceEntry::Dump(); snprintf(buffer, size, "REMOVE %Ld (%p), \"%s\"\n", fID, fInode,
kprintf("REMOVE %Ld (%p), \"%s\"\n", fID, fInode, fName); fName);
} }
private: private:
@@ -91,11 +90,10 @@ class Resize : public AbstractTraceEntry {
Initialized(); Initialized();
} }
virtual void Dump() virtual void AddDump(char *buffer, size_t size)
{ {
AbstractTraceEntry::Dump(); snprintf(buffer, size, "RESIZE %Ld (%p), %Ld -> %Ld\n", fID, fInode,
kprintf("RESIZE %Ld (%p), %Ld -> %Ld\n", fID, fInode, fOldSize, fOldSize, fNewSize);
fNewSize);
} }
private: private:
+93 -51
View File
@@ -9,7 +9,8 @@
enum { enum {
WRAP_ENTRY = 0x01, WRAP_ENTRY = 0x01,
ENTRY_INITIALIZED = 0x02 ENTRY_INITIALIZED = 0x02,
BUFFER_ENTRY = 0x04
}; };
static const size_t kBufferSize = MAX_TRACE_SIZE / 4 - 1; static const size_t kBufferSize = MAX_TRACE_SIZE / 4 - 1;
@@ -36,9 +37,9 @@ next_entry(trace_entry* entry)
static void 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->size = 0;
sBufferEnd->flags = WRAP_ENTRY; sBufferEnd->flags = WRAP_ENTRY;
sBufferEnd = sBuffer; sBufferEnd = sBuffer;
@@ -48,62 +49,26 @@ make_space(size_t size)
if (diff < 0) if (diff < 0)
sBufferEnd = sBuffer; sBufferEnd = sBuffer;
else else
size -= diff; needed -= diff;
while (true) { while (true) {
uint16 skip = sBufferStart->size; uint16 freed = sBufferStart->size;
sBufferStart = next_entry(sBufferStart); sBufferStart = next_entry(sBufferStart);
if (sBufferStart == NULL) if (sBufferStart == NULL)
sBufferStart = sBuffer; sBufferStart = sBufferEnd;
sEntries--; sEntries--;
if (size <= skip) if (needed <= freed)
break; break;
size -= skip; needed -= freed;
} }
} }
#endif // ENABLE_TRACING trace_entry*
allocate_entry(size_t size)
// #pragma mark -
TraceEntry::TraceEntry()
{ {
}
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) if (sBuffer == NULL)
return NULL; return NULL;
@@ -127,7 +92,50 @@ TraceEntry::operator new(size_t size, const std::nothrow_t&) throw()
sBufferEnd += size >> 2; sBufferEnd += size >> 2;
sEntries++; sEntries++;
return entry; 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; return NULL;
#endif #endif
} }
@@ -142,6 +150,10 @@ TraceEntry::operator new(size_t size, const std::nothrow_t&) throw()
int int
dump_tracing(int argc, char** argv) dump_tracing(int argc, char** argv)
{ {
const char *pattern = NULL;
if (argv[argc - 1][0] == '#')
pattern = argv[--argc] + 1;
int32 count = 30; int32 count = 30;
if (argc == 2) if (argc == 2)
count = strtol(argv[1], NULL, 0); count = strtol(argv[1], NULL, 0);
@@ -152,7 +164,7 @@ dump_tracing(int argc, char** argv)
start = strtol(argv[1], NULL, 0); start = strtol(argv[1], NULL, 0);
count = strtol(argv[2], NULL, 0); count = strtol(argv[2], NULL, 0);
} else if (argc > 3) { } else if (argc > 3) {
kprintf("usage: %s [start] [count]\n", argv[0]); kprintf("usage: %s [start] [count] [#pattern]\n", argv[0]);
return 0; return 0;
} }
// TODO: add pattern matching mechanism for the class name // TODO: add pattern matching mechanism for the class name
@@ -168,11 +180,26 @@ dump_tracing(int argc, char** argv)
continue; continue;
if (index > start + count) if (index > start + count)
break; break;
if ((entry->flags & BUFFER_ENTRY) != 0) {
// skip buffer entries
index--;
continue;
}
if ((current->flags & ENTRY_INITIALIZED) != 0) if ((current->flags & ENTRY_INITIALIZED) != 0) {
((TraceEntry*)current)->Dump(); 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 else
kprintf("** uninitialized entry **\n"); kprintf("%s\n", buffer);
} else
kprintf("%5ld. ** uninitialized entry **\n", index);
} }
kprintf("%ld of %ld entries.\n", count, sEntries); kprintf("%ld of %ld entries.\n", count, sEntries);
@@ -182,6 +209,21 @@ dump_tracing(int argc, char** argv)
#endif // ENABLE_TRACING #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 extern "C" status_t
tracing_init(void) tracing_init(void)