1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/disk_cache/trace.h" 6 7 #include <stdio.h> 8 #if defined(OS_WIN) 9 #include <windows.h> 10 #endif 11 12 #include "base/logging.h" 13 14 // Change this value to 1 to enable tracing on a release build. By default, 15 // tracing is enabled only on debug builds. 16 #define ENABLE_TRACING 0 17 18 #ifndef NDEBUG 19 #undef ENABLE_TRACING 20 #define ENABLE_TRACING 1 21 #endif 22 23 namespace { 24 25 const int kEntrySize = 48; 26 const int kNumberOfEntries = 5000; // 240 KB. 27 28 struct TraceBuffer { 29 int num_traces; 30 int current; 31 char buffer[kNumberOfEntries][kEntrySize]; 32 }; 33 34 void DebugOutput(const char* msg) { 35 #if defined(OS_WIN) 36 OutputDebugStringA(msg); 37 #else 38 NOTIMPLEMENTED(); 39 #endif 40 } 41 42 } // namespace 43 44 namespace disk_cache { 45 46 // s_trace_buffer and s_trace_object are not singletons because I want the 47 // buffer to be destroyed and re-created when the last user goes away, and it 48 // must be straightforward to access the buffer from the debugger. 49 static TraceObject* s_trace_object = NULL; 50 51 // Static. 52 TraceObject* TraceObject::GetTraceObject() { 53 if (s_trace_object) 54 return s_trace_object; 55 56 s_trace_object = new TraceObject(); 57 return s_trace_object; 58 } 59 60 #if ENABLE_TRACING 61 62 static TraceBuffer* s_trace_buffer = NULL; 63 64 void InitTrace(void) { 65 if (s_trace_buffer) 66 return; 67 68 s_trace_buffer = new TraceBuffer; 69 memset(s_trace_buffer, 0, sizeof(*s_trace_buffer)); 70 } 71 72 void DestroyTrace(void) { 73 DCHECK(s_trace_buffer); 74 delete s_trace_buffer; 75 s_trace_buffer = NULL; 76 s_trace_object = NULL; 77 } 78 79 void Trace(const char* format, ...) { 80 DCHECK(s_trace_buffer); 81 va_list ap; 82 va_start(ap, format); 83 84 #if defined(OS_WIN) 85 vsprintf_s(s_trace_buffer->buffer[s_trace_buffer->current], format, ap); 86 #else 87 vsnprintf(s_trace_buffer->buffer[s_trace_buffer->current], 88 sizeof(s_trace_buffer->buffer[s_trace_buffer->current]), format, 89 ap); 90 #endif 91 s_trace_buffer->num_traces++; 92 s_trace_buffer->current++; 93 if (s_trace_buffer->current == kNumberOfEntries) 94 s_trace_buffer->current = 0; 95 96 va_end(ap); 97 } 98 99 // Writes the last num_traces to the debugger output. 100 void DumpTrace(int num_traces) { 101 DCHECK(s_trace_buffer); 102 DebugOutput("Last traces:\n"); 103 104 if (num_traces > kNumberOfEntries || num_traces < 0) 105 num_traces = kNumberOfEntries; 106 107 if (s_trace_buffer->num_traces) { 108 char line[kEntrySize + 2]; 109 110 int current = s_trace_buffer->current - num_traces; 111 if (current < 0) 112 current += kNumberOfEntries; 113 114 for (int i = 0; i < num_traces; i++) { 115 memcpy(line, s_trace_buffer->buffer[current], kEntrySize); 116 line[kEntrySize] = '\0'; 117 size_t length = strlen(line); 118 if (length) { 119 line[length] = '\n'; 120 line[length + 1] = '\0'; 121 DebugOutput(line); 122 } 123 124 current++; 125 if (current == kNumberOfEntries) 126 current = 0; 127 } 128 } 129 130 DebugOutput("End of Traces\n"); 131 } 132 133 #else // ENABLE_TRACING 134 135 void InitTrace(void) { 136 return; 137 } 138 139 void DestroyTrace(void) { 140 s_trace_object = NULL; 141 } 142 143 void Trace(const char* format, ...) { 144 } 145 146 #endif // ENABLE_TRACING 147 148 } // namespace disk_cache 149