MercuryDPM  Beta
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Logger.cc
Go to the documentation of this file.
1 #include <Logger.h>
2 
3 #include <CMakeDefinitions.h>
4 #if MERCURY_STACKTRACE_SHOW
5 //To create stacktraces, we need the
6 // backtrace(3)
7 //function calls.. (really, we don't want to do this by hand)
8 #include <execinfo.h>
9 
10 #if MERCURY_STACKTRACE_DEMANGLE
11 //However, we would end up with mangled function names...
12 //So, instead we'll use the abi::__cxa_demangle function call..
13 #include <cxxabi.h>
14 //Oh, and we really want to get the function names as well..
15 #include <dlfcn.h>
16 #endif
17 
18 #endif
19 #include <cstdlib>
20 #include <iostream>
21 /*
22 * We need these to actually exists. These are used as tags in the template metaprogramming for
23 * the Logger class.
24 */
32 
33 /* Actual definition of the default logger. */
34 Logger<MERCURY_LOGLEVEL> logger("MercuryKernel");
35 
36 /* Default implementation for logging warnings / messages */
37 static void printMessage(std::string module, std::string msg) {
38  std::cout << "Module " << module << ":\n" << msg << std::endl;
39 }
40 
41 /* Default implementation for logging errors / fatals */
42 static void printError(std::string module, std::string msg) {
43  std::cerr << "Module " << module << ":\n" << msg << std::endl;
44 #if MERCURY_STACKTRACE_SHOW
45  std::cerr << "\n-----------------[Stack Trace]-----------------\n";
46 
47 
48  void* stackBuffer[64]; //This should be enough for all purposes..
49  //First, we retrieve the addresses of the entire stack...
50  int nStackFrames = backtrace(stackBuffer, 64);
51 #if !MERCURY_STACKTRACE_DEMANGLE
52  //We don't have the demangling infra, so just use backtrace_symbols.
53  char** functionNames = backtrace_symbols(stackBuffer, nStackFrames);
54  for( int i = 0; i < nStackFrames; i++ )
55  {
56  std::cerr << '\t' << functionNames[i] << '\n';
57  }
58  std::cerr << "Exiting.\n" << std::endl;
59 
60  //DO NOT USE DELETE HERE. THIS SHOULD BE free()'d!
61  // -- dducks
62  free(functionNames);
63 #else
64  //We request the symbol information ourselves, in order to be able to demangle it.
65  //And request the function names using dladdr.
66  Dl_info infoStruct;
67  for ( int i = 4; i < nStackFrames; i++ )
68  {
69  if (dladdr(stackBuffer[i], &infoStruct))
70  { // We succesfully loaded the address...
71  int demangleStatus;
72  char* fnDemangled = abi::__cxa_demangle(infoStruct.dli_sname, NULL, NULL, &demangleStatus);
73  if (infoStruct.dli_sname == nullptr)
74  continue;
75 
76  //We even succesfully demangled the symbol...
77  if (demangleStatus == 0)
78  {
79  std::cerr << fnDemangled << " +" << (void*)((char*)stackBuffer[i] - (char*)infoStruct.dli_saddr) << "\t("
80  << infoStruct.dli_fname << ")\n";
81  free(fnDemangled);
82  }
83  else
84  { //Well, we tried. Lets output at least our raw symbol name.
85  std::cerr << infoStruct.dli_sname << " +" << (void*)((char*)stackBuffer[i] - (char*)infoStruct.dli_saddr) << "\t("
86  << infoStruct.dli_fname << ")\n";
87  }
88  }
89  else
90  { //Name lookup failed.
91  std::cerr << stackBuffer[i] << ": ?????" << std::endl;
92  }
93  }
94 #endif
95 #endif
96  std::exit(2);
97 }
98 
99 // Default output methods.
101  printError, //onFatal
102  printError, //onError
103  printMessage, //onWarn
104  printMessage, //onInfo
105  printMessage, //onVerbose
106  printMessage //onDebug
107 };
108 
109 //And we assign them.
Logger.
Definition: Logger.h:161
static void printError(std::string module, std::string msg)
Definition: Logger.cc:42
LL< Log::DEBUG > DEBUG
Debug information.
Definition: Logger.cc:31
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
LL< Log::INFO > INFO
Info log level.
Definition: Logger.cc:28
LoggerOutput loggerOutputDefaultImpl
Definition: Logger.cc:100
LL< Log::ERROR > ERROR
Error log level.
Definition: Logger.cc:26
LL< Log::WARN > WARN
Warning log level.
Definition: Logger.cc:27
static void printMessage(std::string module, std::string msg)
Definition: Logger.cc:37
Default functions for output generation.
Definition: Logger.h:140
LL< Log::DEFAULT > DEFAULT
Default log level.
Definition: Logger.cc:29
LL< Log::FATAL > FATAL
Fatal log level.
Definition: Logger.cc:25
LL< Log::VERBOSE > VERBOSE
Verbose information.
Definition: Logger.cc:30
LoggerOutput * loggerOutput
Declaration of the output functions. If the output needs to be redirected, please swap the loggerOutp...
Definition: Logger.cc:110
Tag for template metaprogramming.
Definition: Logger.h:173