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:
@@ -10,6 +10,7 @@
|
|||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "tracing_config.h"
|
#include "tracing_config.h"
|
||||||
@@ -41,30 +42,31 @@ struct tracing_stack_trace {
|
|||||||
|
|
||||||
|
|
||||||
class TraceOutput {
|
class TraceOutput {
|
||||||
public:
|
public:
|
||||||
TraceOutput(char* buffer, size_t bufferSize, uint32 flags);
|
TraceOutput(char* buffer, size_t bufferSize, uint32 flags);
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
void Print(const char* format,...)
|
void Print(const char* format,...)
|
||||||
__attribute__ ((format (__printf__, 2, 3)));
|
__attribute__ ((format (__printf__, 2, 3)));
|
||||||
void PrintStackTrace(tracing_stack_trace* stackTrace);
|
void PrintArgs(const char* format, va_list args);
|
||||||
bool IsFull() const { return fSize >= fCapacity; }
|
void PrintStackTrace(tracing_stack_trace* stackTrace);
|
||||||
|
bool IsFull() const { return fSize >= fCapacity; }
|
||||||
|
|
||||||
char* Buffer() const { return fBuffer; }
|
char* Buffer() const { return fBuffer; }
|
||||||
size_t Capacity() const { return fCapacity; }
|
size_t Capacity() const { return fCapacity; }
|
||||||
size_t Size() const { return fSize; }
|
size_t Size() const { return fSize; }
|
||||||
|
|
||||||
uint32 Flags() const { return fFlags; }
|
uint32 Flags() const { return fFlags; }
|
||||||
|
|
||||||
void SetLastEntryTime(bigtime_t time);
|
void SetLastEntryTime(bigtime_t time);
|
||||||
bigtime_t LastEntryTime() const;
|
bigtime_t LastEntryTime() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char* fBuffer;
|
char* fBuffer;
|
||||||
size_t fCapacity;
|
size_t fCapacity;
|
||||||
size_t fSize;
|
size_t fSize;
|
||||||
uint32 fFlags;
|
uint32 fFlags;
|
||||||
bigtime_t fLastEntryTime;
|
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);
|
int dump_tracing(int argc, char** argv, WrapperTraceFilter* wrapperFilter);
|
||||||
|
|
||||||
bool tracing_is_entry_valid(TraceEntry* entry, bigtime_t entryTime);
|
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(
|
addr_t tracing_find_caller_in_stack_trace(
|
||||||
struct tracing_stack_trace* stackTrace, const addr_t excludeRanges[],
|
struct tracing_stack_trace* stackTrace, const addr_t excludeRanges[],
|
||||||
uint32 excludeRangeCount);
|
uint32 excludeRangeCount);
|
||||||
|
void tracing_print_stack_trace(struct tracing_stack_trace* stackTrace);
|
||||||
|
|
||||||
void lock_tracing_buffer();
|
void lock_tracing_buffer();
|
||||||
void unlock_tracing_buffer();
|
void unlock_tracing_buffer();
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
#include <tracing.h>
|
#include <tracing.h>
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@@ -59,6 +58,26 @@ static const size_t kMaxTracingEntryByteSize
|
|||||||
= ((1 << 13) - 1) * sizeof(trace_entry);
|
= ((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 {
|
class TracingMetaData {
|
||||||
public:
|
public:
|
||||||
static status_t Create(TracingMetaData*& _metaData);
|
static status_t Create(TracingMetaData*& _metaData);
|
||||||
@@ -112,6 +131,33 @@ static bool sTracingDataRecovered = false;
|
|||||||
// #pragma mark -
|
// #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
|
// #pragma mark - TracingMetaData
|
||||||
|
|
||||||
|
|
||||||
@@ -618,20 +664,14 @@ TraceOutput::Clear()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TraceOutput::Print(const char* format,...)
|
TraceOutput::PrintArgs(const char* format, va_list args)
|
||||||
{
|
{
|
||||||
#if ENABLE_TRACING
|
#if ENABLE_TRACING
|
||||||
if (IsFull())
|
if (IsFull())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (fSize < fCapacity) {
|
size_t length = vsnprintf(fBuffer + fSize, fCapacity - fSize, format, args);
|
||||||
va_list args;
|
fSize += std::min(length, fCapacity - fSize - 1);
|
||||||
va_start(args, format);
|
|
||||||
size_t length = vsnprintf(fBuffer + fSize, fCapacity - fSize, format,
|
|
||||||
args);
|
|
||||||
fSize += std::min(length, fCapacity - fSize - 1);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -640,6 +680,7 @@ void
|
|||||||
TraceOutput::PrintStackTrace(tracing_stack_trace* stackTrace)
|
TraceOutput::PrintStackTrace(tracing_stack_trace* stackTrace)
|
||||||
{
|
{
|
||||||
#if ENABLE_TRACING
|
#if ENABLE_TRACING
|
||||||
|
print_stack_trace(stackTrace, TraceOutputPrint(*this));
|
||||||
if (stackTrace == NULL || stackTrace->depth <= 0)
|
if (stackTrace == NULL || stackTrace->depth <= 0)
|
||||||
return;
|
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
|
int
|
||||||
dump_tracing(int argc, char** argv, WrapperTraceFilter* wrapperFilter)
|
dump_tracing(int argc, char** argv, WrapperTraceFilter* wrapperFilter)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user