1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2011 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_LIBARTBASE_BASE_LOGGING_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_LIBARTBASE_BASE_LOGGING_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include <sstream> 21*795d594fSAndroid Build Coastguard Worker #include <variant> 22*795d594fSAndroid Build Coastguard Worker 23*795d594fSAndroid Build Coastguard Worker #include "android-base/logging.h" 24*795d594fSAndroid Build Coastguard Worker #include "macros.h" 25*795d594fSAndroid Build Coastguard Worker 26*795d594fSAndroid Build Coastguard Worker namespace art { 27*795d594fSAndroid Build Coastguard Worker 28*795d594fSAndroid Build Coastguard Worker // Make libbase's LogSeverity more easily available. 29*795d594fSAndroid Build Coastguard Worker using ::android::base::LogSeverity; 30*795d594fSAndroid Build Coastguard Worker using ::android::base::ScopedLogSeverity; 31*795d594fSAndroid Build Coastguard Worker 32*795d594fSAndroid Build Coastguard Worker // Abort function. 33*795d594fSAndroid Build Coastguard Worker using AbortFunction = void(const char*); 34*795d594fSAndroid Build Coastguard Worker 35*795d594fSAndroid Build Coastguard Worker // The members of this struct are the valid arguments to VLOG and VLOG_IS_ON in code, 36*795d594fSAndroid Build Coastguard Worker // and the "-verbose:" command line argument. 37*795d594fSAndroid Build Coastguard Worker struct LogVerbosity { 38*795d594fSAndroid Build Coastguard Worker bool class_linker; // Enabled with "-verbose:class". 39*795d594fSAndroid Build Coastguard Worker bool collector; 40*795d594fSAndroid Build Coastguard Worker bool compiler; 41*795d594fSAndroid Build Coastguard Worker bool deopt; 42*795d594fSAndroid Build Coastguard Worker bool gc; 43*795d594fSAndroid Build Coastguard Worker bool heap; 44*795d594fSAndroid Build Coastguard Worker bool interpreter; // Enabled with "-verbose:interpreter". 45*795d594fSAndroid Build Coastguard Worker bool jdwp; 46*795d594fSAndroid Build Coastguard Worker bool jit; 47*795d594fSAndroid Build Coastguard Worker bool jni; 48*795d594fSAndroid Build Coastguard Worker bool monitor; 49*795d594fSAndroid Build Coastguard Worker bool oat; 50*795d594fSAndroid Build Coastguard Worker bool profiler; 51*795d594fSAndroid Build Coastguard Worker bool signals; 52*795d594fSAndroid Build Coastguard Worker bool simulator; 53*795d594fSAndroid Build Coastguard Worker bool startup; 54*795d594fSAndroid Build Coastguard Worker bool third_party_jni; // Enabled with "-verbose:third-party-jni". 55*795d594fSAndroid Build Coastguard Worker bool threads; 56*795d594fSAndroid Build Coastguard Worker bool verifier; 57*795d594fSAndroid Build Coastguard Worker bool verifier_debug; // Only works in debug builds. 58*795d594fSAndroid Build Coastguard Worker bool image; 59*795d594fSAndroid Build Coastguard Worker bool systrace_lock_logging; // Enabled with "-verbose:systrace-locks". 60*795d594fSAndroid Build Coastguard Worker bool agents; 61*795d594fSAndroid Build Coastguard Worker bool dex; // Some dex access output etc. 62*795d594fSAndroid Build Coastguard Worker bool plugin; // Used by some plugins. 63*795d594fSAndroid Build Coastguard Worker }; 64*795d594fSAndroid Build Coastguard Worker 65*795d594fSAndroid Build Coastguard Worker // Global log verbosity setting, initialized by InitLogging. 66*795d594fSAndroid Build Coastguard Worker extern LogVerbosity gLogVerbosity; 67*795d594fSAndroid Build Coastguard Worker 68*795d594fSAndroid Build Coastguard Worker // Configure logging based on ANDROID_LOG_TAGS environment variable. 69*795d594fSAndroid Build Coastguard Worker // We need to parse a string that looks like 70*795d594fSAndroid Build Coastguard Worker // 71*795d594fSAndroid Build Coastguard Worker // *:v jdwp:d dalvikvm:d dalvikvm-gc:i dalvikvmi:i 72*795d594fSAndroid Build Coastguard Worker // 73*795d594fSAndroid Build Coastguard Worker // The tag (or '*' for the global level) comes first, followed by a colon 74*795d594fSAndroid Build Coastguard Worker // and a letter indicating the minimum priority level we're expected to log. 75*795d594fSAndroid Build Coastguard Worker // This can be used to reveal or conceal logs with specific tags. 76*795d594fSAndroid Build Coastguard Worker extern void InitLogging(char* argv[], AbortFunction& default_aborter); 77*795d594fSAndroid Build Coastguard Worker 78*795d594fSAndroid Build Coastguard Worker // Returns the command line used to invoke the current tool or null if InitLogging hasn't been 79*795d594fSAndroid Build Coastguard Worker // performed. 80*795d594fSAndroid Build Coastguard Worker extern const char* GetCmdLine(); 81*795d594fSAndroid Build Coastguard Worker 82*795d594fSAndroid Build Coastguard Worker // The command used to start the ART runtime, such as "/apex/com.android.art/bin/dalvikvm". If 83*795d594fSAndroid Build Coastguard Worker // InitLogging hasn't been performed then just returns "art". 84*795d594fSAndroid Build Coastguard Worker extern const char* ProgramInvocationName(); 85*795d594fSAndroid Build Coastguard Worker 86*795d594fSAndroid Build Coastguard Worker // A short version of the command used to start the ART runtime, such as "dalvikvm". If InitLogging 87*795d594fSAndroid Build Coastguard Worker // hasn't been performed then just returns "art". 88*795d594fSAndroid Build Coastguard Worker extern const char* ProgramInvocationShortName(); 89*795d594fSAndroid Build Coastguard Worker 90*795d594fSAndroid Build Coastguard Worker class LogHelper { 91*795d594fSAndroid Build Coastguard Worker public: 92*795d594fSAndroid Build Coastguard Worker // A logging helper for logging a single line. Can be used with little stack. 93*795d594fSAndroid Build Coastguard Worker static void LogLineLowStack(const char* file, 94*795d594fSAndroid Build Coastguard Worker unsigned int line, 95*795d594fSAndroid Build Coastguard Worker android::base::LogSeverity severity, 96*795d594fSAndroid Build Coastguard Worker const char* msg); 97*795d594fSAndroid Build Coastguard Worker 98*795d594fSAndroid Build Coastguard Worker private: 99*795d594fSAndroid Build Coastguard Worker DISALLOW_ALLOCATION(); 100*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(LogHelper); 101*795d594fSAndroid Build Coastguard Worker }; 102*795d594fSAndroid Build Coastguard Worker 103*795d594fSAndroid Build Coastguard Worker // Copy the contents of file_name to the log stream for level. 104*795d594fSAndroid Build Coastguard Worker bool PrintFileToLog(const std::string& file_name, android::base::LogSeverity level); 105*795d594fSAndroid Build Coastguard Worker 106*795d594fSAndroid Build Coastguard Worker // Is verbose logging enabled for the given module? Where the module is defined in LogVerbosity. 107*795d594fSAndroid Build Coastguard Worker #define VLOG_IS_ON(module) UNLIKELY(::art::gLogVerbosity.module) 108*795d594fSAndroid Build Coastguard Worker 109*795d594fSAndroid Build Coastguard Worker // Variant of LOG that logs when verbose logging is enabled for a module. For example, 110*795d594fSAndroid Build Coastguard Worker // VLOG(jni) << "A JNI operation was performed"; 111*795d594fSAndroid Build Coastguard Worker #define VLOG(module) if (VLOG_IS_ON(module)) LOG(INFO) 112*795d594fSAndroid Build Coastguard Worker 113*795d594fSAndroid Build Coastguard Worker // Holder to implement VLOG_STREAM. 114*795d594fSAndroid Build Coastguard Worker class VlogMessage { 115*795d594fSAndroid Build Coastguard Worker public: 116*795d594fSAndroid Build Coastguard Worker // TODO Taken from android_base. VlogMessage(bool enable,const char * file,unsigned int line,::android::base::LogSeverity severity,const char * tag,int error)117*795d594fSAndroid Build Coastguard Worker VlogMessage(bool enable, 118*795d594fSAndroid Build Coastguard Worker const char* file, 119*795d594fSAndroid Build Coastguard Worker unsigned int line, 120*795d594fSAndroid Build Coastguard Worker ::android::base::LogSeverity severity, 121*795d594fSAndroid Build Coastguard Worker const char* tag, 122*795d594fSAndroid Build Coastguard Worker int error) 123*795d594fSAndroid Build Coastguard Worker : msg_(std::in_place_type<std::ostringstream>) { 124*795d594fSAndroid Build Coastguard Worker if (enable) { 125*795d594fSAndroid Build Coastguard Worker msg_.emplace<::android::base::LogMessage>(file, line, severity, tag, error); 126*795d594fSAndroid Build Coastguard Worker } 127*795d594fSAndroid Build Coastguard Worker } 128*795d594fSAndroid Build Coastguard Worker stream()129*795d594fSAndroid Build Coastguard Worker std::ostream& stream() { 130*795d594fSAndroid Build Coastguard Worker if (std::holds_alternative<std::ostringstream>(msg_)) { 131*795d594fSAndroid Build Coastguard Worker return std::get<std::ostringstream>(msg_); 132*795d594fSAndroid Build Coastguard Worker } else { 133*795d594fSAndroid Build Coastguard Worker return std::get<::android::base::LogMessage>(msg_).stream(); 134*795d594fSAndroid Build Coastguard Worker } 135*795d594fSAndroid Build Coastguard Worker } 136*795d594fSAndroid Build Coastguard Worker 137*795d594fSAndroid Build Coastguard Worker private: 138*795d594fSAndroid Build Coastguard Worker std::variant<::android::base::LogMessage, std::ostringstream> msg_; 139*795d594fSAndroid Build Coastguard Worker }; 140*795d594fSAndroid Build Coastguard Worker 141*795d594fSAndroid Build Coastguard Worker // Return the stream associated with logging for the given module. NB Unlike VLOG function calls 142*795d594fSAndroid Build Coastguard Worker // will still be performed. Output will be suppressed if the module is not on. 143*795d594fSAndroid Build Coastguard Worker #define VLOG_STREAM(module) \ 144*795d594fSAndroid Build Coastguard Worker ::art::VlogMessage(VLOG_IS_ON(module), \ 145*795d594fSAndroid Build Coastguard Worker __FILE__, \ 146*795d594fSAndroid Build Coastguard Worker __LINE__, \ 147*795d594fSAndroid Build Coastguard Worker ::android::base::INFO, \ 148*795d594fSAndroid Build Coastguard Worker _LOG_TAG_INTERNAL, \ 149*795d594fSAndroid Build Coastguard Worker -1) \ 150*795d594fSAndroid Build Coastguard Worker .stream() 151*795d594fSAndroid Build Coastguard Worker 152*795d594fSAndroid Build Coastguard Worker // Check whether an implication holds between x and y, LOG(FATAL) if not. The value 153*795d594fSAndroid Build Coastguard Worker // of the expressions x and y is evaluated once. Extra logging can be appended 154*795d594fSAndroid Build Coastguard Worker // using << after. For example: 155*795d594fSAndroid Build Coastguard Worker // 156*795d594fSAndroid Build Coastguard Worker // CHECK_IMPLIES(1==1, 0==1) results in 157*795d594fSAndroid Build Coastguard Worker // "Check failed: 1==1 (true) implies 0==1 (false) ". 158*795d594fSAndroid Build Coastguard Worker // clang-format off 159*795d594fSAndroid Build Coastguard Worker #define CHECK_IMPLIES(LHS, RHS) \ 160*795d594fSAndroid Build Coastguard Worker LIKELY(!(LHS) || (RHS)) || ABORT_AFTER_LOG_FATAL_EXPR(false) || \ 161*795d594fSAndroid Build Coastguard Worker ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::FATAL, _LOG_TAG_INTERNAL, \ 162*795d594fSAndroid Build Coastguard Worker -1) \ 163*795d594fSAndroid Build Coastguard Worker .stream() \ 164*795d594fSAndroid Build Coastguard Worker << "Check failed: " #LHS << " (true) implies " #RHS << " (false)" 165*795d594fSAndroid Build Coastguard Worker // clang-format on 166*795d594fSAndroid Build Coastguard Worker 167*795d594fSAndroid Build Coastguard Worker #define DCHECK_IMPLIES(a, b) \ 168*795d594fSAndroid Build Coastguard Worker if (::android::base::kEnableDChecks) CHECK_IMPLIES(a, b) 169*795d594fSAndroid Build Coastguard Worker 170*795d594fSAndroid Build Coastguard Worker } // namespace art 171*795d594fSAndroid Build Coastguard Worker 172*795d594fSAndroid Build Coastguard Worker #endif // ART_LIBARTBASE_BASE_LOGGING_H_ 173