2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2008, Axel Dörfler, axeld@pinc-software.de.
4 * Distributed under the terms of the MIT License.
6 #ifndef KERNEL_TRACING_H
7 #define KERNEL_TRACING_H
10 #include <SupportDefs.h>
11 #include <KernelExport.h>
16 #include "tracing_config.h"
20 uint32 size
: 13; // actual size is *4
21 uint32 previous_size
: 13; // actual size is *4
25 struct tracing_stack_trace
{
27 addr_t return_addresses
[0];
37 #define TRACE_OUTPUT_TEAM_ID 0x01
39 #define TRACE_OUTPUT_DIFF_TIME 0x02
40 // print the difference time to the previously printed entry instead of the
46 TraceOutput(char* buffer
, size_t bufferSize
, uint32 flags
);
49 void Print(const char* format
,...)
50 __attribute__ ((format (__printf__
, 2, 3)));
51 void PrintArgs(const char* format
, va_list args
);
52 void PrintStackTrace(tracing_stack_trace
* stackTrace
);
53 bool IsFull() const { return fSize
>= fCapacity
; }
55 char* Buffer() const { return fBuffer
; }
56 size_t Capacity() const { return fCapacity
; }
57 size_t Size() const { return fSize
; }
59 uint32
Flags() const { return fFlags
; }
61 void SetLastEntryTime(bigtime_t time
);
62 bigtime_t
LastEntryTime() const;
69 bigtime_t fLastEntryTime
;
76 virtual ~TraceEntry();
78 virtual void Dump(TraceOutput
& out
);
79 virtual void DumpStackTrace(TraceOutput
& out
);
81 size_t Size() const { return ToTraceEntry()->size
; }
82 uint16
Flags() const { return ToTraceEntry()->flags
; }
86 void* operator new(size_t size
, const std::nothrow_t
&) throw();
88 trace_entry
* ToTraceEntry() const
90 return (trace_entry
*)this - 1;
93 static TraceEntry
* FromTraceEntry(trace_entry
* entry
)
95 return (TraceEntry
*)(entry
+ 1);
100 class AbstractTraceEntry
: public TraceEntry
{
107 // dummy, ignores all arguments
108 AbstractTraceEntry(size_t, size_t, bool)
113 virtual ~AbstractTraceEntry();
115 virtual void Dump(TraceOutput
& out
);
117 virtual void AddDump(TraceOutput
& out
);
119 thread_id
ThreadID() const { return fThread
; }
120 thread_id
TeamID() const { return fTeam
; }
121 bigtime_t
Time() const { return fTime
; }
124 typedef AbstractTraceEntry TraceEntryBase
;
136 class AbstractTraceEntryWithStackTrace
: public AbstractTraceEntry
{
138 AbstractTraceEntryWithStackTrace(size_t stackTraceDepth
,
139 size_t skipFrames
, bool kernelOnly
);
141 virtual void DumpStackTrace(TraceOutput
& out
);
143 tracing_stack_trace
* StackTrace() const
149 typedef AbstractTraceEntryWithStackTrace TraceEntryBase
;
152 tracing_stack_trace
* fStackTrace
;
156 template<bool stackTraceDepth
>
157 struct AbstractTraceEntrySelector
{
158 typedef AbstractTraceEntryWithStackTrace Type
;
163 struct AbstractTraceEntrySelector
<0> {
164 typedef AbstractTraceEntry Type
;
168 #define TRACE_ENTRY_SELECTOR(stackTraceDepth) \
169 AbstractTraceEntrySelector<stackTraceDepth>::Type
172 class LazyTraceOutput
: public TraceOutput
{
174 LazyTraceOutput(char* buffer
, size_t bufferSize
, uint32 flags
)
175 : TraceOutput(buffer
, bufferSize
, flags
)
179 const char* DumpEntry(const TraceEntry
* entry
)
182 const_cast<TraceEntry
*>(entry
)->Dump(*this);
183 // Dump() should probably be const
193 virtual ~TraceFilter();
195 virtual bool Filter(const TraceEntry
* entry
, LazyTraceOutput
& out
);
211 class WrapperTraceFilter
: public TraceFilter
{
213 virtual void Init(TraceFilter
* filter
, int direction
, bool continued
) = 0;
217 class TraceEntryIterator
{
237 TraceEntry
* Current() const
239 return fEntry
!= NULL
? TraceEntry::FromTraceEntry(fEntry
) : NULL
;
243 TraceEntry
* Previous();
244 TraceEntry
* MoveTo(int32 index
);
247 trace_entry
* _NextNonBufferEntry(trace_entry
* entry
);
248 trace_entry
* _PreviousNonBufferEntry(trace_entry
* entry
);
257 TraceOutput::Print(const char* format
,...)
260 va_start(args
, format
);
261 PrintArgs(format
, args
);
266 int dump_tracing(int argc
, char** argv
, WrapperTraceFilter
* wrapperFilter
);
268 bool tracing_is_entry_valid(AbstractTraceEntry
* entry
,
269 bigtime_t entryTime
= -1);
271 #endif // __cplusplus
278 uint8
* alloc_tracing_buffer(size_t size
);
279 uint8
* alloc_tracing_buffer_memcpy(const void* source
, size_t size
, bool user
);
280 char* alloc_tracing_buffer_strcpy(const char* source
, size_t maxSize
,
283 struct tracing_stack_trace
* capture_tracing_stack_trace(int32 maxCount
,
284 int32 skipFrames
, bool kernelOnly
);
285 addr_t
tracing_find_caller_in_stack_trace(
286 struct tracing_stack_trace
* stackTrace
, const addr_t excludeRanges
[],
287 uint32 excludeRangeCount
);
288 void tracing_print_stack_trace(struct tracing_stack_trace
* stackTrace
);
290 void lock_tracing_buffer();
291 void unlock_tracing_buffer();
292 status_t
tracing_init(void);
294 void _user_ktrace_output(const char *message
);
300 #endif /* KERNEL_TRACING_H */