1*9712c20fSFrederick Mayle // Copyright 2007 Google LLC 2*9712c20fSFrederick Mayle // 3*9712c20fSFrederick Mayle // Redistribution and use in source and binary forms, with or without 4*9712c20fSFrederick Mayle // modification, are permitted provided that the following conditions are 5*9712c20fSFrederick Mayle // met: 6*9712c20fSFrederick Mayle // 7*9712c20fSFrederick Mayle // * Redistributions of source code must retain the above copyright 8*9712c20fSFrederick Mayle // notice, this list of conditions and the following disclaimer. 9*9712c20fSFrederick Mayle // * Redistributions in binary form must reproduce the above 10*9712c20fSFrederick Mayle // copyright notice, this list of conditions and the following disclaimer 11*9712c20fSFrederick Mayle // in the documentation and/or other materials provided with the 12*9712c20fSFrederick Mayle // distribution. 13*9712c20fSFrederick Mayle // * Neither the name of Google LLC nor the names of its 14*9712c20fSFrederick Mayle // contributors may be used to endorse or promote products derived from 15*9712c20fSFrederick Mayle // this software without specific prior written permission. 16*9712c20fSFrederick Mayle // 17*9712c20fSFrederick Mayle // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18*9712c20fSFrederick Mayle // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19*9712c20fSFrederick Mayle // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20*9712c20fSFrederick Mayle // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21*9712c20fSFrederick Mayle // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22*9712c20fSFrederick Mayle // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23*9712c20fSFrederick Mayle // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24*9712c20fSFrederick Mayle // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25*9712c20fSFrederick Mayle // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26*9712c20fSFrederick Mayle // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27*9712c20fSFrederick Mayle // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28*9712c20fSFrederick Mayle 29*9712c20fSFrederick Mayle // logging.h: Breakpad logging 30*9712c20fSFrederick Mayle // 31*9712c20fSFrederick Mayle // Breakpad itself uses Breakpad logging with statements of the form: 32*9712c20fSFrederick Mayle // BPLOG(severity) << "message"; 33*9712c20fSFrederick Mayle // severity may be INFO, ERROR, or other values defined in this file. 34*9712c20fSFrederick Mayle // 35*9712c20fSFrederick Mayle // BPLOG is an overridable macro so that users can customize Breakpad's 36*9712c20fSFrederick Mayle // logging. Left at the default, logging messages are sent to stderr along 37*9712c20fSFrederick Mayle // with a timestamp and the source code location that produced a message. 38*9712c20fSFrederick Mayle // The streams may be changed by redefining BPLOG_*_STREAM, the logging 39*9712c20fSFrederick Mayle // behavior may be changed by redefining BPLOG_*, and the entire logging 40*9712c20fSFrederick Mayle // system may be overridden by redefining BPLOG(severity). These 41*9712c20fSFrederick Mayle // redefinitions may be passed to the preprocessor as a command-line flag 42*9712c20fSFrederick Mayle // (-D). 43*9712c20fSFrederick Mayle // 44*9712c20fSFrederick Mayle // If an additional header is required to override Breakpad logging, it can 45*9712c20fSFrederick Mayle // be specified by the BP_LOGGING_INCLUDE macro. If defined, this header 46*9712c20fSFrederick Mayle // will #include the header specified by that macro. 47*9712c20fSFrederick Mayle // 48*9712c20fSFrederick Mayle // If any initialization is needed before logging, it can be performed by 49*9712c20fSFrederick Mayle // a function called through the BPLOG_INIT macro. Each main function of 50*9712c20fSFrederick Mayle // an executable program in the Breakpad processor library calls 51*9712c20fSFrederick Mayle // BPLOG_INIT(&argc, &argv); before any logging can be performed; define 52*9712c20fSFrederick Mayle // BPLOG_INIT appropriately if initialization is required. 53*9712c20fSFrederick Mayle // 54*9712c20fSFrederick Mayle // Author: Mark Mentovai 55*9712c20fSFrederick Mayle 56*9712c20fSFrederick Mayle #ifndef PROCESSOR_LOGGING_H__ 57*9712c20fSFrederick Mayle #define PROCESSOR_LOGGING_H__ 58*9712c20fSFrederick Mayle 59*9712c20fSFrederick Mayle #include <iostream> 60*9712c20fSFrederick Mayle #include <string> 61*9712c20fSFrederick Mayle 62*9712c20fSFrederick Mayle #include "common/using_std_string.h" 63*9712c20fSFrederick Mayle #include "google_breakpad/common/breakpad_types.h" 64*9712c20fSFrederick Mayle 65*9712c20fSFrederick Mayle #ifdef BP_LOGGING_INCLUDE 66*9712c20fSFrederick Mayle #include BP_LOGGING_INCLUDE 67*9712c20fSFrederick Mayle #endif // BP_LOGGING_INCLUDE 68*9712c20fSFrederick Mayle 69*9712c20fSFrederick Mayle namespace google_breakpad { 70*9712c20fSFrederick Mayle 71*9712c20fSFrederick Mayle // These are defined in Microsoft headers. 72*9712c20fSFrederick Mayle #ifdef SEVERITY_ERROR 73*9712c20fSFrederick Mayle #undef SEVERITY_ERROR 74*9712c20fSFrederick Mayle #endif 75*9712c20fSFrederick Mayle 76*9712c20fSFrederick Mayle #ifdef ERROR 77*9712c20fSFrederick Mayle #undef ERROR 78*9712c20fSFrederick Mayle #endif 79*9712c20fSFrederick Mayle 80*9712c20fSFrederick Mayle class LogStream { 81*9712c20fSFrederick Mayle public: 82*9712c20fSFrederick Mayle enum Severity { 83*9712c20fSFrederick Mayle SEVERITY_INFO, 84*9712c20fSFrederick Mayle SEVERITY_ERROR, 85*9712c20fSFrederick Mayle SEVERITY_CRITICAL 86*9712c20fSFrederick Mayle }; 87*9712c20fSFrederick Mayle 88*9712c20fSFrederick Mayle // Begin logging a message to the stream identified by |stream|, at the 89*9712c20fSFrederick Mayle // indicated severity. The file and line parameters should be set so as to 90*9712c20fSFrederick Mayle // identify the line of source code that is producing a message. 91*9712c20fSFrederick Mayle LogStream(std::ostream& stream, Severity severity, 92*9712c20fSFrederick Mayle const char* file, int line); 93*9712c20fSFrederick Mayle 94*9712c20fSFrederick Mayle // Finish logging by printing a newline and flushing the output stream. 95*9712c20fSFrederick Mayle ~LogStream(); 96*9712c20fSFrederick Mayle 97*9712c20fSFrederick Mayle template<typename T> std::ostream& operator<<(const T& t) { 98*9712c20fSFrederick Mayle return stream_ << t; 99*9712c20fSFrederick Mayle } 100*9712c20fSFrederick Mayle 101*9712c20fSFrederick Mayle private: 102*9712c20fSFrederick Mayle std::ostream& stream_; 103*9712c20fSFrederick Mayle 104*9712c20fSFrederick Mayle // Disallow copy constructor and assignment operator 105*9712c20fSFrederick Mayle explicit LogStream(const LogStream& that); 106*9712c20fSFrederick Mayle void operator=(const LogStream& that); 107*9712c20fSFrederick Mayle }; 108*9712c20fSFrederick Mayle 109*9712c20fSFrederick Mayle // This class is used to explicitly ignore values in the conditional logging 110*9712c20fSFrederick Mayle // macros. This avoids compiler warnings like "value computed is not used" 111*9712c20fSFrederick Mayle // and "statement has no effect". 112*9712c20fSFrederick Mayle class LogMessageVoidify { 113*9712c20fSFrederick Mayle public: LogMessageVoidify()114*9712c20fSFrederick Mayle LogMessageVoidify() {} 115*9712c20fSFrederick Mayle 116*9712c20fSFrederick Mayle // This has to be an operator with a precedence lower than << but higher 117*9712c20fSFrederick Mayle // than ?: 118*9712c20fSFrederick Mayle void operator&(std::ostream&) {} 119*9712c20fSFrederick Mayle }; 120*9712c20fSFrederick Mayle 121*9712c20fSFrederick Mayle // Returns number formatted as a hexadecimal string, such as "0x7b". 122*9712c20fSFrederick Mayle string HexString(uint32_t number); 123*9712c20fSFrederick Mayle string HexString(uint64_t number); 124*9712c20fSFrederick Mayle string HexString(int number); 125*9712c20fSFrederick Mayle 126*9712c20fSFrederick Mayle // Returns the error code as set in the global errno variable, and sets 127*9712c20fSFrederick Mayle // error_string, a required argument, to a string describing that error 128*9712c20fSFrederick Mayle // code. 129*9712c20fSFrederick Mayle int ErrnoString(string* error_string); 130*9712c20fSFrederick Mayle 131*9712c20fSFrederick Mayle } // namespace google_breakpad 132*9712c20fSFrederick Mayle 133*9712c20fSFrederick Mayle #ifndef BPLOG_INIT 134*9712c20fSFrederick Mayle #define BPLOG_INIT(pargc, pargv) 135*9712c20fSFrederick Mayle #endif // BPLOG_INIT 136*9712c20fSFrederick Mayle 137*9712c20fSFrederick Mayle #ifndef BPLOG_LAZY_STREAM 138*9712c20fSFrederick Mayle #define BPLOG_LAZY_STREAM(stream, condition) \ 139*9712c20fSFrederick Mayle !(condition) ? (void) 0 : \ 140*9712c20fSFrederick Mayle google_breakpad::LogMessageVoidify() & (BPLOG_ ## stream) 141*9712c20fSFrederick Mayle #endif 142*9712c20fSFrederick Mayle 143*9712c20fSFrederick Mayle #ifndef BPLOG_MINIMUM_SEVERITY 144*9712c20fSFrederick Mayle #define BPLOG_MINIMUM_SEVERITY SEVERITY_INFO 145*9712c20fSFrederick Mayle #endif 146*9712c20fSFrederick Mayle 147*9712c20fSFrederick Mayle #define BPLOG_LOG_IS_ON(severity) \ 148*9712c20fSFrederick Mayle ((google_breakpad::LogStream::SEVERITY_ ## severity) >= \ 149*9712c20fSFrederick Mayle (google_breakpad::LogStream::BPLOG_MINIMUM_SEVERITY)) 150*9712c20fSFrederick Mayle 151*9712c20fSFrederick Mayle #ifndef BPLOG 152*9712c20fSFrederick Mayle #define BPLOG(severity) BPLOG_LAZY_STREAM(severity, BPLOG_LOG_IS_ON(severity)) 153*9712c20fSFrederick Mayle #endif // BPLOG 154*9712c20fSFrederick Mayle 155*9712c20fSFrederick Mayle #ifndef BPLOG_INFO 156*9712c20fSFrederick Mayle #ifndef BPLOG_INFO_STREAM 157*9712c20fSFrederick Mayle #define BPLOG_INFO_STREAM std::clog 158*9712c20fSFrederick Mayle #endif // BPLOG_INFO_STREAM 159*9712c20fSFrederick Mayle #define BPLOG_INFO google_breakpad::LogStream(BPLOG_INFO_STREAM, \ 160*9712c20fSFrederick Mayle google_breakpad::LogStream::SEVERITY_INFO, \ 161*9712c20fSFrederick Mayle __FILE__, __LINE__) 162*9712c20fSFrederick Mayle #endif // BPLOG_INFO 163*9712c20fSFrederick Mayle 164*9712c20fSFrederick Mayle #ifndef BPLOG_ERROR 165*9712c20fSFrederick Mayle #ifndef BPLOG_ERROR_STREAM 166*9712c20fSFrederick Mayle #define BPLOG_ERROR_STREAM std::cerr 167*9712c20fSFrederick Mayle #endif // BPLOG_ERROR_STREAM 168*9712c20fSFrederick Mayle #define BPLOG_ERROR google_breakpad::LogStream(BPLOG_ERROR_STREAM, \ 169*9712c20fSFrederick Mayle google_breakpad::LogStream::SEVERITY_ERROR, \ 170*9712c20fSFrederick Mayle __FILE__, __LINE__) 171*9712c20fSFrederick Mayle #endif // BPLOG_ERROR 172*9712c20fSFrederick Mayle 173*9712c20fSFrederick Mayle #ifndef BPLOG_CRITICAL 174*9712c20fSFrederick Mayle #ifndef BPLOG_CRITICAL_STREAM 175*9712c20fSFrederick Mayle #define BPLOG_CRITICAL_STREAM std::cerr 176*9712c20fSFrederick Mayle #endif // BPLOG_CRITICAL_STREAM 177*9712c20fSFrederick Mayle #define BPLOG_CRITICAL google_breakpad::LogStream(BPLOG_CRITICAL_STREAM, \ 178*9712c20fSFrederick Mayle google_breakpad::LogStream::SEVERITY_CRITICAL, \ 179*9712c20fSFrederick Mayle __FILE__, __LINE__) 180*9712c20fSFrederick Mayle #endif // BPLOG_CRITICAL 181*9712c20fSFrederick Mayle 182*9712c20fSFrederick Mayle #ifndef BPLOG_IF 183*9712c20fSFrederick Mayle #define BPLOG_IF(severity, condition) \ 184*9712c20fSFrederick Mayle BPLOG_LAZY_STREAM(severity, ((condition) && BPLOG_LOG_IS_ON(severity))) 185*9712c20fSFrederick Mayle #endif // BPLOG_IF 186*9712c20fSFrederick Mayle 187*9712c20fSFrederick Mayle #endif // PROCESSOR_LOGGING_H__ 188