logging.h revision 3b6baaa203fa63f1522b2172a1645f90412afdae
142ee14279065352a4b9a3e8028d02c567e847d05Elliott Hughes/*
242ee14279065352a4b9a3e8028d02c567e847d05Elliott Hughes * Copyright (C) 2011 The Android Open Source Project
342ee14279065352a4b9a3e8028d02c567e847d05Elliott Hughes *
442ee14279065352a4b9a3e8028d02c567e847d05Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
542ee14279065352a4b9a3e8028d02c567e847d05Elliott Hughes * you may not use this file except in compliance with the License.
642ee14279065352a4b9a3e8028d02c567e847d05Elliott Hughes * You may obtain a copy of the License at
742ee14279065352a4b9a3e8028d02c567e847d05Elliott Hughes *
842ee14279065352a4b9a3e8028d02c567e847d05Elliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
942ee14279065352a4b9a3e8028d02c567e847d05Elliott Hughes *
1042ee14279065352a4b9a3e8028d02c567e847d05Elliott Hughes * Unless required by applicable law or agreed to in writing, software
1142ee14279065352a4b9a3e8028d02c567e847d05Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
1242ee14279065352a4b9a3e8028d02c567e847d05Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1342ee14279065352a4b9a3e8028d02c567e847d05Elliott Hughes * See the License for the specific language governing permissions and
1442ee14279065352a4b9a3e8028d02c567e847d05Elliott Hughes * limitations under the License.
1542ee14279065352a4b9a3e8028d02c567e847d05Elliott Hughes */
166c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro
176b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapiro#ifndef ART_SRC_LOGGING_H_
186b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapiro#define ART_SRC_LOGGING_H_
196c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro
20eb4f614f2eb53b92ebd416fa418f550861655887Elliott Hughes#include <cerrno>
21eb4f614f2eb53b92ebd416fa418f550861655887Elliott Hughes#include <cstring>
226c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro#include <iostream>  // NOLINT
23eb4f614f2eb53b92ebd416fa418f550861655887Elliott Hughes#include <sstream>
24eb4f614f2eb53b92ebd416fa418f550861655887Elliott Hughes#include "log_severity.h"
25eb4f614f2eb53b92ebd416fa418f550861655887Elliott Hughes#include "macros.h"
266c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro
276c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro#define CHECK(x) \
28caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers  if (UNLIKELY(!(x))) \
29f5a7a476e7ea63e094ff0f011dccc170607e6f6bElliott Hughes    ::art::LogMessage(__FILE__, __LINE__, FATAL, -1).stream() \
30710a0cbb4b0af03ce8651ed7936437c73250045eElliott Hughes        << "Check failed: " #x << " "
31eb4f614f2eb53b92ebd416fa418f550861655887Elliott Hughes
321f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes#define CHECK_OP(LHS, RHS, OP) \
33caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers  for (::art::EagerEvaluator<typeof(LHS), typeof(RHS)> _values(LHS, RHS); \
34caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers       UNLIKELY(!(_values.lhs OP _values.rhs)); ) \
35f5a7a476e7ea63e094ff0f011dccc170607e6f6bElliott Hughes    ::art::LogMessage(__FILE__, __LINE__, FATAL, -1).stream() \
36f5a7a476e7ea63e094ff0f011dccc170607e6f6bElliott Hughes        << "Check failed: " << #LHS << " " << #OP << " " << #RHS \
37f5a7a476e7ea63e094ff0f011dccc170607e6f6bElliott Hughes        << " (" #LHS "=" << _values.lhs << ", " #RHS "=" << _values.rhs << ") "
381f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
391f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes#define CHECK_EQ(x, y) CHECK_OP(x, y, ==)
401f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes#define CHECK_NE(x, y) CHECK_OP(x, y, !=)
411f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes#define CHECK_LE(x, y) CHECK_OP(x, y, <=)
421f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes#define CHECK_LT(x, y) CHECK_OP(x, y, <)
431f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes#define CHECK_GE(x, y) CHECK_OP(x, y, >=)
441f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes#define CHECK_GT(x, y) CHECK_OP(x, y, >)
45eb4f614f2eb53b92ebd416fa418f550861655887Elliott Hughes
46eb4f614f2eb53b92ebd416fa418f550861655887Elliott Hughes#define CHECK_STROP(s1, s2, sense) \
47caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers  if (UNLIKELY((strcmp(s1, s2) == 0) != sense)) \
48f5a7a476e7ea63e094ff0f011dccc170607e6f6bElliott Hughes    LOG(FATAL) << "Check failed: " \
49f5a7a476e7ea63e094ff0f011dccc170607e6f6bElliott Hughes               << "\"" << s1 << "\"" \
50f5a7a476e7ea63e094ff0f011dccc170607e6f6bElliott Hughes               << (sense ? " == " : " != ") \
51f5a7a476e7ea63e094ff0f011dccc170607e6f6bElliott Hughes               << "\"" << s2 << "\""
526c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro
531f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes#define CHECK_STREQ(s1, s2) CHECK_STROP(s1, s2, true)
541f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes#define CHECK_STRNE(s1, s2) CHECK_STROP(s1, s2, false)
551f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
568d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes#define CHECK_PTHREAD_CALL(call, args, what) \
578d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes  do { \
588d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes    int rc = call args; \
598d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes    if (rc != 0) { \
608d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes      errno = rc; \
618d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes      PLOG(FATAL) << # call << " failed for " << what; \
628d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes    } \
638d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes  } while (false)
648d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes
656c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro#ifndef NDEBUG
666c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro
676c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro#define DCHECK(x) CHECK(x)
686c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro#define DCHECK_EQ(x, y) CHECK_EQ(x, y)
696c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro#define DCHECK_NE(x, y) CHECK_NE(x, y)
706c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro#define DCHECK_LE(x, y) CHECK_LE(x, y)
716c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro#define DCHECK_LT(x, y) CHECK_LT(x, y)
726c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro#define DCHECK_GE(x, y) CHECK_GE(x, y)
736c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro#define DCHECK_GT(x, y) CHECK_GT(x, y)
74eb4f614f2eb53b92ebd416fa418f550861655887Elliott Hughes#define DCHECK_STREQ(s1, s2) CHECK_STREQ(s1, s2)
75eb4f614f2eb53b92ebd416fa418f550861655887Elliott Hughes#define DCHECK_STRNE(s1, s2) CHECK_STRNE(s1, s2)
766c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro
776c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro#else  // NDEBUG
786c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro
796c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro#define DCHECK(condition) \
806c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro  while (false) \
816c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro    CHECK(condition)
826c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro
836c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro#define DCHECK_EQ(val1, val2) \
846c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro  while (false) \
856c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro    CHECK_EQ(val1, val2)
866c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro
876c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro#define DCHECK_NE(val1, val2) \
886c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro  while (false) \
896c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro    CHECK_NE(val1, val2)
906c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro
916c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro#define DCHECK_LE(val1, val2) \
926c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro  while (false) \
936c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro    CHECK_LE(val1, val2)
946c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro
956c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro#define DCHECK_LT(val1, val2) \
966c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro  while (false) \
976c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro    CHECK_LT(val1, val2)
986c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro
996c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro#define DCHECK_GE(val1, val2) \
1006c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro  while (false) \
1016c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro    CHECK_GE(val1, val2)
1026c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro
1036c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro#define DCHECK_GT(val1, val2) \
1046c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro  while (false) \
1056c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro    CHECK_GT(val1, val2)
1066c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro
1076c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro#define DCHECK_STREQ(str1, str2) \
1086c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro  while (false) \
1096c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro    CHECK_STREQ(str1, str2)
1106c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro
111eb4f614f2eb53b92ebd416fa418f550861655887Elliott Hughes#define DCHECK_STRNE(str1, str2) \
112eb4f614f2eb53b92ebd416fa418f550861655887Elliott Hughes  while (false) \
113eb4f614f2eb53b92ebd416fa418f550861655887Elliott Hughes    CHECK_STRNE(str1, str2)
114eb4f614f2eb53b92ebd416fa418f550861655887Elliott Hughes
1156c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro#endif
1166c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro
117f5a7a476e7ea63e094ff0f011dccc170607e6f6bElliott Hughes#define LOG(severity) ::art::LogMessage(__FILE__, __LINE__, severity, -1).stream()
118f5a7a476e7ea63e094ff0f011dccc170607e6f6bElliott Hughes#define PLOG(severity) ::art::LogMessage(__FILE__, __LINE__, severity, errno).stream()
119eb4f614f2eb53b92ebd416fa418f550861655887Elliott Hughes
1206c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro#define LG LOG(INFO)
1216c21dc1bcafd83e90daa42a27dacd285278f3667Carl Shapiro
1228d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes#define UNIMPLEMENTED(level) LOG(level) << __PRETTY_FUNCTION__ << " unimplemented "
12353b61314370c49354ed6f8d616d6a9a182410fc1Elliott Hughes
1243ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes//
1253ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes// Implementation details beyond this point.
1263ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes//
1273ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes
1283ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughesnamespace art {
1293ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes
1303ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughestemplate <typename LHS, typename RHS>
1313ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughesstruct EagerEvaluator {
1323ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes  EagerEvaluator(LHS lhs, RHS rhs) : lhs(lhs), rhs(rhs) { }
1333ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes  LHS lhs;
1343ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes  RHS rhs;
1353ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes};
1363ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes
1373b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes// This indirection greatly reduces the stack impact of having
1383b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes// lots of checks/logging in a function.
1393b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughesstruct LogMessageData {
1403b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes public:
1413b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes  LogMessageData(int line, LogSeverity severity, int error)
1423b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes      : file(NULL),
1433b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes        line_number(line),
1443b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes        severity(severity),
1453b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes        error(error) {
1463b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes  }
1473b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes
1483b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes  std::ostringstream buffer;
1493b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes  const char* file;
1503b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes  int line_number;
1513b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes  LogSeverity severity;
1523b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes  int error;
1533b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes
1543b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes private:
1553b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes  DISALLOW_COPY_AND_ASSIGN(LogMessageData);
1563b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes};
1573b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes
1583ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughesclass LogMessage {
1593ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes public:
1603ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes  LogMessage(const char* file, int line, LogSeverity severity, int error);
1613ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes  ~LogMessage();
1623ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes  std::ostream& stream();
1633ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes
1643ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes private:
1653ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes  void LogLine(const char*);
1663ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes
1673b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes  LogMessageData* data_;
1683ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes
1693ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes  DISALLOW_COPY_AND_ASSIGN(LogMessage);
1703ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes};
1713ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes
1723ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes}  // namespace art
1733ea7e9931149dd852bb6fce241d1da6406125df6Elliott Hughes
1746b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapiro#endif  // ART_SRC_LOGGING_H_
175