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 __attribute__ ((format (__printf__, 2, 3))); 46 void PrintStackTrace(tracing_stack_trace* stackTrace); 47 bool IsFull() const { return fSize >= fCapacity; } 48 49 char* Buffer() const { return fBuffer; } 50 size_t Capacity() const { return fCapacity; } 51 size_t Size() const { return fSize; } 52 53 uint32 Flags() const { return fFlags; } 54 55 void SetLastEntryTime(bigtime_t time); 56 bigtime_t LastEntryTime() const; 57 58 private: 59 char* fBuffer; 60 size_t fCapacity; 61 size_t fSize; 62 uint32 fFlags; 63 bigtime_t fLastEntryTime; 64 }; 65 66 67 class TraceEntry { 68 public: 69 TraceEntry(); 70 virtual ~TraceEntry(); 71 72 virtual void Dump(TraceOutput& out); 73 virtual void DumpStackTrace(TraceOutput& out); 74 75 size_t Size() const { return ToTraceEntry()->size; } 76 uint16 Flags() const { return ToTraceEntry()->flags; } 77 78 void Initialized(); 79 80 void* operator new(size_t size, const std::nothrow_t&) throw(); 81 82 trace_entry* ToTraceEntry() const 83 { 84 return (trace_entry*)this - 1; 85 } 86 87 static TraceEntry* FromTraceEntry(trace_entry* entry) 88 { 89 return (TraceEntry*)(entry + 1); 90 } 91 }; 92 93 94 class AbstractTraceEntry : public TraceEntry { 95 public: 96 AbstractTraceEntry(); 97 virtual ~AbstractTraceEntry(); 98 99 virtual void Dump(TraceOutput& out); 100 101 virtual void AddDump(TraceOutput& out); 102 103 thread_id Thread() const { return fThread; } 104 thread_id Team() const { return fTeam; } 105 bigtime_t Time() const { return fTime; } 106 107 protected: 108 thread_id fThread; 109 team_id fTeam; 110 bigtime_t fTime; 111 }; 112 113 114 class LazyTraceOutput : public TraceOutput { 115 public: 116 LazyTraceOutput(char* buffer, size_t bufferSize, uint32 flags) 117 : TraceOutput(buffer, bufferSize, flags) 118 { 119 } 120 121 const char* DumpEntry(const TraceEntry* entry) 122 { 123 if (Size() == 0) { 124 const_cast<TraceEntry*>(entry)->Dump(*this); 125 // Dump() should probably be const 126 } 127 128 return Buffer(); 129 } 130 }; 131 132 133 class TraceFilter { 134 public: 135 virtual ~TraceFilter(); 136 137 virtual bool Filter(const TraceEntry* entry, LazyTraceOutput& out); 138 139 public: 140 union { 141 thread_id fThread; 142 team_id fTeam; 143 const char* fString; 144 uint64 fValue; 145 struct { 146 TraceFilter* first; 147 TraceFilter* second; 148 } fSubFilters; 149 }; 150 }; 151 152 153 class WrapperTraceFilter : public TraceFilter { 154 public: 155 virtual void Init(TraceFilter* filter, int direction, bool continued) = 0; 156 }; 157 158 159 class TraceEntryIterator { 160 public: 161 TraceEntryIterator() 162 : 163 fEntry(NULL), 164 fIndex(0) 165 { 166 } 167 168 void Reset() 169 { 170 fEntry = NULL; 171 fIndex = 0; 172 } 173 174 int32 Index() const 175 { 176 return fIndex; 177 } 178 179 TraceEntry* Current() const 180 { 181 return fEntry != NULL ? TraceEntry::FromTraceEntry(fEntry) : NULL; 182 } 183 184 TraceEntry* Next(); 185 TraceEntry* Previous(); 186 TraceEntry* MoveTo(int32 index); 187 188 private: 189 trace_entry* _NextNonBufferEntry(trace_entry* entry); 190 trace_entry* _PreviousNonBufferEntry(trace_entry* entry); 191 192 private: 193 trace_entry* fEntry; 194 int32 fIndex; 195 }; 196 197 198 int dump_tracing(int argc, char** argv, WrapperTraceFilter* wrapperFilter); 199 200 #endif // __cplusplus 201 202 #ifdef __cplusplus 203 extern "C" { 204 #endif 205 206 uint8* alloc_tracing_buffer(size_t size); 207 uint8* alloc_tracing_buffer_memcpy(const void* source, size_t size, bool user); 208 char* alloc_tracing_buffer_strcpy(const char* source, size_t maxSize, 209 bool user); 210 struct tracing_stack_trace* capture_tracing_stack_trace(int32 maxCount, 211 int32 skipFrames, bool userOnly); 212 void lock_tracing_buffer(); 213 void unlock_tracing_buffer(); 214 status_t tracing_init(void); 215 216 void _user_ktrace_output(const char *message); 217 218 #ifdef __cplusplus 219 } 220 #endif 221 222 #endif /* KERNEL_TRACING_H */ 223