1 /* 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. 5 */ 6 #ifndef KERNEL_TRACING_H 7 #define KERNEL_TRACING_H 8 9 10 #include <SupportDefs.h> 11 #include <KernelExport.h> 12 13 #include <stdio.h> 14 15 #include "tracing_config.h" 16 17 18 struct trace_entry { 19 uint32 size : 14; // actual size is *4 20 uint32 previous_size : 14; // actual size is *4 21 uint32 flags : 4; 22 }; 23 24 struct tracing_stack_trace; 25 26 #ifdef __cplusplus 27 28 #include <new> 29 30 31 // trace output flags 32 #define TRACE_OUTPUT_TEAM_ID 0x01 33 // print the team ID 34 #define TRACE_OUTPUT_DIFF_TIME 0x02 35 // print the difference time to the previously printed entry instead of the 36 // absolute time 37 38 39 class TraceOutput { 40 public: 41 TraceOutput(char* buffer, size_t bufferSize, uint32 flags); 42 43 void Clear(); 44 void Print(const char* format,...); 45 void PrintStackTrace(tracing_stack_trace* stackTrace); 46 bool IsFull() const { return fSize >= fCapacity; } 47 48 char* Buffer() const { return fBuffer; } 49 size_t Capacity() const { return fCapacity; } 50 size_t Size() const { return fSize; } 51 52 uint32 Flags() const { return fFlags; } 53 54 void SetLastEntryTime(bigtime_t time); 55 bigtime_t LastEntryTime() const; 56 57 private: 58 char* fBuffer; 59 size_t fCapacity; 60 size_t fSize; 61 uint32 fFlags; 62 bigtime_t fLastEntryTime; 63 }; 64 65 class TraceEntry { 66 public: 67 TraceEntry(); 68 virtual ~TraceEntry(); 69 70 virtual void Dump(TraceOutput& out); 71 virtual void DumpStackTrace(TraceOutput& out); 72 73 size_t Size() const { return ToTraceEntry()->size; } 74 uint16 Flags() const { return ToTraceEntry()->flags; } 75 76 void Initialized(); 77 78 void* operator new(size_t size, const std::nothrow_t&) throw(); 79 80 trace_entry* ToTraceEntry() const 81 { 82 return (trace_entry*)this - 1; 83 } 84 85 static TraceEntry* FromTraceEntry(trace_entry* entry) 86 { 87 return (TraceEntry*)(entry + 1); 88 } 89 }; 90 91 class AbstractTraceEntry : public TraceEntry { 92 public: 93 AbstractTraceEntry(); 94 virtual ~AbstractTraceEntry(); 95 96 virtual void Dump(TraceOutput& out); 97 98 virtual void AddDump(TraceOutput& out); 99 100 thread_id Thread() const { return fThread; } 101 thread_id Team() const { return fTeam; } 102 bigtime_t Time() const { return fTime; } 103 104 protected: 105 thread_id fThread; 106 team_id fTeam; 107 bigtime_t fTime; 108 }; 109 110 class LazyTraceOutput : public TraceOutput { 111 public: 112 LazyTraceOutput(char* buffer, size_t bufferSize, uint32 flags) 113 : TraceOutput(buffer, bufferSize, flags) 114 { 115 } 116 117 const char* DumpEntry(const TraceEntry* entry) 118 { 119 if (Size() == 0) { 120 const_cast<TraceEntry*>(entry)->Dump(*this); 121 // Dump() should probably be const 122 } 123 124 return Buffer(); 125 } 126 }; 127 128 class TraceFilter { 129 public: 130 virtual ~TraceFilter(); 131 132 virtual bool Filter(const TraceEntry* entry, LazyTraceOutput& out); 133 134 public: 135 union { 136 thread_id fThread; 137 team_id fTeam; 138 const char* fString; 139 uint64 fValue; 140 struct { 141 TraceFilter* first; 142 TraceFilter* second; 143 } fSubFilters; 144 }; 145 }; 146 147 class WrapperTraceFilter : public TraceFilter { 148 public: 149 virtual void Init(TraceFilter* filter, int direction, bool continued) = 0; 150 }; 151 152 #endif // __cplusplus 153 154 #ifdef __cplusplus 155 extern "C" { 156 #endif 157 158 uint8* alloc_tracing_buffer(size_t size); 159 uint8* alloc_tracing_buffer_memcpy(const void* source, size_t size, bool user); 160 char* alloc_tracing_buffer_strcpy(const char* source, size_t maxSize, 161 bool user); 162 tracing_stack_trace* capture_tracing_stack_trace(int32 maxCount, 163 int32 skipFrames, bool userOnly); 164 int dump_tracing(int argc, char** argv, WrapperTraceFilter* wrapperFilter); 165 status_t tracing_init(void); 166 167 void _user_ktrace_output(const char *message); 168 169 #ifdef __cplusplus 170 } 171 #endif 172 173 #endif /* KERNEL_TRACING_H */ 174