mmlr + bonefish:

* Add TraceOutput::PrintArgs(), a va_list version of Print().
* Move code of TraceOutput::Print() to new private template function
  print_stack_trace().
* Add public tracing_print_stack_trace().


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@43085 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2011-11-01 22:22:14 +00:00
parent a5e2a43050
commit 328df922e6
2 changed files with 90 additions and 29 deletions

View File

@ -10,6 +10,7 @@
#include <SupportDefs.h>
#include <KernelExport.h>
#include <stdarg.h>
#include <stdio.h>
#include "tracing_config.h"
@ -41,30 +42,31 @@ struct tracing_stack_trace {
class TraceOutput {
public:
TraceOutput(char* buffer, size_t bufferSize, uint32 flags);
public:
TraceOutput(char* buffer, size_t bufferSize, uint32 flags);
void Clear();
void Print(const char* format,...)
__attribute__ ((format (__printf__, 2, 3)));
void PrintStackTrace(tracing_stack_trace* stackTrace);
bool IsFull() const { return fSize >= fCapacity; }
void Clear();
void Print(const char* format,...)
__attribute__ ((format (__printf__, 2, 3)));
void PrintArgs(const char* format, va_list args);
void PrintStackTrace(tracing_stack_trace* stackTrace);
bool IsFull() const { return fSize >= fCapacity; }
char* Buffer() const { return fBuffer; }
size_t Capacity() const { return fCapacity; }
size_t Size() const { return fSize; }
char* Buffer() const { return fBuffer; }
size_t Capacity() const { return fCapacity; }
size_t Size() const { return fSize; }
uint32 Flags() const { return fFlags; }
uint32 Flags() const { return fFlags; }
void SetLastEntryTime(bigtime_t time);
bigtime_t LastEntryTime() const;
void SetLastEntryTime(bigtime_t time);
bigtime_t LastEntryTime() const;
private:
char* fBuffer;
size_t fCapacity;
size_t fSize;
uint32 fFlags;
bigtime_t fLastEntryTime;
private:
char* fBuffer;
size_t fCapacity;
size_t fSize;
uint32 fFlags;
bigtime_t fLastEntryTime;
};
@ -251,6 +253,16 @@ private:
};
inline void
TraceOutput::Print(const char* format,...)
{
va_list args;
va_start(args, format);
PrintArgs(format, args);
va_end(args);
}
int dump_tracing(int argc, char** argv, WrapperTraceFilter* wrapperFilter);
bool tracing_is_entry_valid(TraceEntry* entry, bigtime_t entryTime);
@ -272,6 +284,7 @@ struct tracing_stack_trace* capture_tracing_stack_trace(int32 maxCount,
addr_t tracing_find_caller_in_stack_trace(
struct tracing_stack_trace* stackTrace, const addr_t excludeRanges[],
uint32 excludeRangeCount);
void tracing_print_stack_trace(struct tracing_stack_trace* stackTrace);
void lock_tracing_buffer();
void unlock_tracing_buffer();

View File

@ -7,7 +7,6 @@
#include <tracing.h>
#include <stdarg.h>
#include <stdlib.h>
#include <algorithm>
@ -59,6 +58,26 @@ static const size_t kMaxTracingEntryByteSize
= ((1 << 13) - 1) * sizeof(trace_entry);
struct TraceOutputPrint {
TraceOutputPrint(TraceOutput& output)
:
fOutput(output)
{
}
void operator()(const char* format,...) const
{
va_list args;
va_start(args, format);
fOutput.PrintArgs(format, args);
va_end(args);
}
private:
TraceOutput& fOutput;
};
class TracingMetaData {
public:
static status_t Create(TracingMetaData*& _metaData);
@ -112,6 +131,33 @@ static bool sTracingDataRecovered = false;
// #pragma mark -
template<typename Print>
static void
print_stack_trace(struct tracing_stack_trace* stackTrace,
const Print& print)
{
if (stackTrace == NULL || stackTrace->depth <= 0)
return;
for (int32 i = 0; i < stackTrace->depth; i++) {
addr_t address = stackTrace->return_addresses[i];
const char* symbol;
const char* imageName;
bool exactMatch;
addr_t baseAddress;
if (elf_debug_lookup_symbol_address(address, &baseAddress, &symbol,
&imageName, &exactMatch) == B_OK) {
print(" %p %s + 0x%lx (%s)%s\n", (void*)address, symbol,
address - baseAddress, imageName,
exactMatch ? "" : " (nearest)");
} else
print(" %p\n", (void*)address);
}
}
// #pragma mark - TracingMetaData
@ -618,20 +664,14 @@ TraceOutput::Clear()
void
TraceOutput::Print(const char* format,...)
TraceOutput::PrintArgs(const char* format, va_list args)
{
#if ENABLE_TRACING
if (IsFull())
return;
if (fSize < fCapacity) {
va_list args;
va_start(args, format);
size_t length = vsnprintf(fBuffer + fSize, fCapacity - fSize, format,
args);
fSize += std::min(length, fCapacity - fSize - 1);
va_end(args);
}
size_t length = vsnprintf(fBuffer + fSize, fCapacity - fSize, format, args);
fSize += std::min(length, fCapacity - fSize - 1);
#endif
}
@ -640,6 +680,7 @@ void
TraceOutput::PrintStackTrace(tracing_stack_trace* stackTrace)
{
#if ENABLE_TRACING
print_stack_trace(stackTrace, TraceOutputPrint(*this));
if (stackTrace == NULL || stackTrace->depth <= 0)
return;
@ -1634,6 +1675,13 @@ tracing_find_caller_in_stack_trace(struct tracing_stack_trace* stackTrace,
}
void
tracing_print_stack_trace(struct tracing_stack_trace* stackTrace)
{
print_stack_trace(stackTrace, kprintf);
}
int
dump_tracing(int argc, char** argv, WrapperTraceFilter* wrapperFilter)
{