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 23namespace { 24 25const int kEntrySize = 48; 26const int kNumberOfEntries = 5000; // 240 KB. 27 28struct TraceBuffer { 29 int num_traces; 30 int current; 31 char buffer[kNumberOfEntries][kEntrySize]; 32}; 33 34#if ENABLE_TRACING 35void DebugOutput(const char* msg) { 36#if defined(OS_WIN) 37 OutputDebugStringA(msg); 38#else 39 NOTIMPLEMENTED(); 40#endif 41} 42#endif // ENABLE_TRACING 43 44} // namespace 45 46namespace disk_cache { 47 48// s_trace_buffer and s_trace_object are not singletons because I want the 49// buffer to be destroyed and re-created when the last user goes away, and it 50// must be straightforward to access the buffer from the debugger. 51static TraceObject* s_trace_object = NULL; 52 53// Static. 54TraceObject* TraceObject::GetTraceObject() { 55 if (s_trace_object) 56 return s_trace_object; 57 58 s_trace_object = new TraceObject(); 59 return s_trace_object; 60} 61 62TraceObject::TraceObject() { 63 InitTrace(); 64} 65 66TraceObject::~TraceObject() { 67 DestroyTrace(); 68} 69 70#if ENABLE_TRACING 71 72static TraceBuffer* s_trace_buffer = NULL; 73 74void InitTrace(void) { 75 if (s_trace_buffer) 76 return; 77 78 s_trace_buffer = new TraceBuffer; 79 memset(s_trace_buffer, 0, sizeof(*s_trace_buffer)); 80} 81 82void DestroyTrace(void) { 83 delete s_trace_buffer; 84 s_trace_buffer = NULL; 85 s_trace_object = NULL; 86} 87 88void Trace(const char* format, ...) { 89 if (!s_trace_buffer) 90 return; 91 92 va_list ap; 93 va_start(ap, format); 94 95#if defined(OS_WIN) 96 vsprintf_s(s_trace_buffer->buffer[s_trace_buffer->current], format, ap); 97#else 98 vsnprintf(s_trace_buffer->buffer[s_trace_buffer->current], 99 sizeof(s_trace_buffer->buffer[s_trace_buffer->current]), format, 100 ap); 101#endif 102 s_trace_buffer->num_traces++; 103 s_trace_buffer->current++; 104 if (s_trace_buffer->current == kNumberOfEntries) 105 s_trace_buffer->current = 0; 106 107 va_end(ap); 108} 109 110// Writes the last num_traces to the debugger output. 111void DumpTrace(int num_traces) { 112 DCHECK(s_trace_buffer); 113 DebugOutput("Last traces:\n"); 114 115 if (num_traces > kNumberOfEntries || num_traces < 0) 116 num_traces = kNumberOfEntries; 117 118 if (s_trace_buffer->num_traces) { 119 char line[kEntrySize + 2]; 120 121 int current = s_trace_buffer->current - num_traces; 122 if (current < 0) 123 current += kNumberOfEntries; 124 125 for (int i = 0; i < num_traces; i++) { 126 memcpy(line, s_trace_buffer->buffer[current], kEntrySize); 127 line[kEntrySize] = '\0'; 128 size_t length = strlen(line); 129 if (length) { 130 line[length] = '\n'; 131 line[length + 1] = '\0'; 132 DebugOutput(line); 133 } 134 135 current++; 136 if (current == kNumberOfEntries) 137 current = 0; 138 } 139 } 140 141 DebugOutput("End of Traces\n"); 142} 143 144#else // ENABLE_TRACING 145 146void InitTrace(void) { 147 return; 148} 149 150void DestroyTrace(void) { 151 s_trace_object = NULL; 152} 153 154void Trace(const char* format, ...) { 155} 156 157#endif // ENABLE_TRACING 158 159} // namespace disk_cache 160