blob: 0c300c3e20dd43235f688f323cd16c3e564a0fd6 [file] [log] [blame]
Austin Schuh745610d2015-09-06 18:19:50 -07001// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
2// Copyright (c) 2005, Google Inc.
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9// * Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11// * Redistributions in binary form must reproduce the above
12// copyright notice, this list of conditions and the following disclaimer
13// in the documentation and/or other materials provided with the
14// distribution.
15// * Neither the name of Google Inc. nor the names of its
16// contributors may be used to endorse or promote products derived from
17// this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31// ---
32// Author: Sanjay Ghemawat <opensource@google.com>
33//
34// Internal logging and related utility routines.
35
36#ifndef TCMALLOC_INTERNAL_LOGGING_H_
37#define TCMALLOC_INTERNAL_LOGGING_H_
38
39#include <config.h>
40#include <stddef.h> // for size_t
41#if defined HAVE_STDINT_H
42#include <stdint.h>
43#elif defined HAVE_INTTYPES_H
44#include <inttypes.h>
45#else
46#include <sys/types.h>
47#endif
48
49//-------------------------------------------------------------------
50// Utility routines
51//-------------------------------------------------------------------
52
53// Safe logging helper: we write directly to the stderr file
54// descriptor and avoid FILE buffering because that may invoke
55// malloc().
56//
57// Example:
58// Log(kLog, __FILE__, __LINE__, "error", bytes);
59
60namespace tcmalloc {
61enum LogMode {
62 kLog, // Just print the message
63 kCrash, // Print the message and crash
64 kCrashWithStats // Print the message, some stats, and crash
65};
66
67class Logger;
68
69// A LogItem holds any of the argument types that can be passed to Log()
70class LogItem {
71 public:
72 LogItem() : tag_(kEnd) { }
73 LogItem(const char* v) : tag_(kStr) { u_.str = v; }
74 LogItem(int v) : tag_(kSigned) { u_.snum = v; }
75 LogItem(long v) : tag_(kSigned) { u_.snum = v; }
76 LogItem(long long v) : tag_(kSigned) { u_.snum = v; }
77 LogItem(unsigned int v) : tag_(kUnsigned) { u_.unum = v; }
78 LogItem(unsigned long v) : tag_(kUnsigned) { u_.unum = v; }
79 LogItem(unsigned long long v) : tag_(kUnsigned) { u_.unum = v; }
80 LogItem(const void* v) : tag_(kPtr) { u_.ptr = v; }
81 private:
82 friend class Logger;
83 enum Tag {
84 kStr,
85 kSigned,
86 kUnsigned,
87 kPtr,
88 kEnd
89 };
90 Tag tag_;
91 union {
92 const char* str;
93 const void* ptr;
94 int64_t snum;
95 uint64_t unum;
96 } u_;
97};
98
99extern PERFTOOLS_DLL_DECL void Log(LogMode mode, const char* filename, int line,
100 LogItem a, LogItem b = LogItem(),
101 LogItem c = LogItem(), LogItem d = LogItem());
102
103// Tests can override this function to collect logging messages.
104extern PERFTOOLS_DLL_DECL void (*log_message_writer)(const char* msg, int length);
105
106} // end tcmalloc namespace
107
108// Like assert(), but executed even in NDEBUG mode
109#undef CHECK_CONDITION
110#define CHECK_CONDITION(cond) \
111do { \
112 if (!(cond)) { \
113 ::tcmalloc::Log(::tcmalloc::kCrash, __FILE__, __LINE__, #cond); \
114 } \
115} while (0)
116
117// Our own version of assert() so we can avoid hanging by trying to do
118// all kinds of goofy printing while holding the malloc lock.
119#ifndef NDEBUG
120#define ASSERT(cond) CHECK_CONDITION(cond)
121#else
122#define ASSERT(cond) ((void) 0)
123#endif
124
125// Print into buffer
126class TCMalloc_Printer {
127 private:
128 char* buf_; // Where should we write next
129 int left_; // Space left in buffer (including space for \0)
130
131 public:
132 // REQUIRES: "length > 0"
133 TCMalloc_Printer(char* buf, int length) : buf_(buf), left_(length) {
134 buf[0] = '\0';
135 }
136
137 void printf(const char* format, ...)
138#ifdef HAVE___ATTRIBUTE__
139 __attribute__ ((__format__ (__printf__, 2, 3)))
140#endif
141;
142};
143
144#endif // TCMALLOC_INTERNAL_LOGGING_H_