15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2005, Google Inc. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met: 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions of source code must retain the above copyright 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer. 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions in binary form must reproduce the above 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution. 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Neither the name of Google Inc. nor the names of its 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// --- 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: Sanjay Ghemawat <opensource@google.com> 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Internal logging and related utility routines. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef TCMALLOC_INTERNAL_LOGGING_H_ 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TCMALLOC_INTERNAL_LOGGING_H_ 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <config.h> 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stddef.h> // for size_t 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined HAVE_STDINT_H 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdint.h> 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined HAVE_INTTYPES_H 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <inttypes.h> 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h> 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------- 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Utility routines 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------- 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Safe logging helper: we write directly to the stderr file 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// descriptor and avoid FILE buffering because that may invoke 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// malloc(). 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Example: 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Log(kLog, __FILE__, __LINE__, "error", bytes); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace tcmalloc { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum LogMode { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kLog, // Just print the message 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kCrash, // Print the message and crash 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kCrashWithStats // Print the message, some stats, and crash 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Logger; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A LogItem holds any of the argument types that can be passed to Log() 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LogItem { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogItem() : tag_(kEnd) { } 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogItem(const char* v) : tag_(kStr) { u_.str = v; } 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogItem(int v) : tag_(kSigned) { u_.snum = v; } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogItem(long v) : tag_(kSigned) { u_.snum = v; } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogItem(long long v) : tag_(kSigned) { u_.snum = v; } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogItem(unsigned int v) : tag_(kUnsigned) { u_.unum = v; } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogItem(unsigned long v) : tag_(kUnsigned) { u_.unum = v; } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogItem(unsigned long long v) : tag_(kUnsigned) { u_.unum = v; } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogItem(const void* v) : tag_(kPtr) { u_.ptr = v; } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class Logger; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum Tag { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kStr, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kSigned, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kUnsigned, 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kPtr, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kEnd 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tag tag_; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* str; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* ptr; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64_t snum; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t unum; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u_; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern PERFTOOLS_DLL_DECL void Log(LogMode mode, const char* filename, int line, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogItem a, LogItem b = LogItem(), 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogItem c = LogItem(), LogItem d = LogItem()); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests can override this function to collect logging messages. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern PERFTOOLS_DLL_DECL void (*log_message_writer)(const char* msg, int length); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // end tcmalloc namespace 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Like assert(), but executed even in NDEBUG mode 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef CHECK_CONDITION 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_CONDITION(cond) \ 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)do { \ 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(cond)) { \ 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::tcmalloc::Log(::tcmalloc::kCrash, __FILE__, __LINE__, #cond); \ 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } \ 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} while (0) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_CONDITION_PRINT(cond, str) \ 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)do { \ 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(cond)) { \ 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::tcmalloc::Log(::tcmalloc::kCrash, __FILE__, __LINE__, str); \ 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } \ 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} while (0) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Our own version of assert() so we can avoid hanging by trying to do 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// all kinds of goofy printing while holding the malloc lock. 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT(cond) CHECK_CONDITION(cond) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT_PRINT(cond, str) CHECK_CONDITION_PRINT(cond, str) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT(cond) ((void) 0) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT_PRINT(cond, str) ((void) 0) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Print into buffer 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TCMalloc_Printer { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* buf_; // Where should we write next 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int left_; // Space left in buffer (including space for \0) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // REQUIRES: "length > 0" 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TCMalloc_Printer(char* buf, int length) : buf_(buf), left_(length) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buf[0] = '\0'; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void printf(const char* format, ...) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE___ATTRIBUTE__ 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __attribute__ ((__format__ (__printf__, 2, 3))) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // TCMALLOC_INTERNAL_LOGGING_H_ 153