Home | History | Annotate | Download | only in disk_cache
      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