GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/debug_utils.h Lines: 18 21 85.7 %
Date: 2020-02-19 22:14:06 Branches: 162 248 65.3 %

Line Branch Exec Source
1
#ifndef SRC_DEBUG_UTILS_H_
2
#define SRC_DEBUG_UTILS_H_
3
4
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
6
#include "async_wrap.h"
7
#include "env.h"
8
9
#include <sstream>
10
#include <string>
11
12
// Use FORCE_INLINE on functions that have a debug-category-enabled check first
13
// and then ideally only a single function call following it, to maintain
14
// performance for the common case (no debugging used).
15
#ifdef __GNUC__
16
#define FORCE_INLINE __attribute__((always_inline))
17
#define COLD_NOINLINE __attribute__((cold, noinline))
18
#else
19
#define FORCE_INLINE
20
#define COLD_NOINLINE
21
#endif
22
23
namespace node {
24
25
template <typename T>
26
inline std::string ToString(const T& value);
27
28
// C++-style variant of sprintf()/fprintf() that:
29
// - Returns an std::string
30
// - Handles \0 bytes correctly
31
// - Supports %p and %s. %d, %i and %u are aliases for %s.
32
// - Accepts any class that has a ToString() method for stringification.
33
template <typename... Args>
34
inline std::string SPrintF(const char* format, Args&&... args);
35
template <typename... Args>
36
inline void FPrintF(FILE* file, const char* format, Args&&... args);
37
void FWrite(FILE* file, const std::string& str);
38
39
template <typename... Args>
40
inline void FORCE_INLINE Debug(Environment* env,
41
                               DebugCategory cat,
42
                               const char* format,
43
                               Args&&... args) {
44




















42542
  if (!UNLIKELY(env->debug_enabled(cat)))
45
    return;
46
571
  FPrintF(stderr, format, std::forward<Args>(args)...);
47
}
48
49
inline void FORCE_INLINE Debug(Environment* env,
50
                               DebugCategory cat,
51
                               const char* message) {
52


8731
  if (!UNLIKELY(env->debug_enabled(cat)))
53
    return;
54
98
  FPrintF(stderr, "%s", message);
55
}
56
57
template <typename... Args>
58
126
inline void Debug(Environment* env,
59
                  DebugCategory cat,
60
                  const std::string& format,
61
                  Args&&... args) {
62
126
  Debug(env, cat, format.c_str(), std::forward<Args>(args)...);
63
126
}
64
65
// Used internally by the 'real' Debug(AsyncWrap*, ...) functions below, so that
66
// the FORCE_INLINE flag on them doesn't apply to the contents of this function
67
// as well.
68
// We apply COLD_NOINLINE to tell the compiler that it's not worth optimizing
69
// this function for speed and it should rather focus on keeping it out of
70
// hot code paths. In particular, we want to keep the string concatenating code
71
// out of the function containing the original `Debug()` call.
72
template <typename... Args>
73
126
void COLD_NOINLINE UnconditionalAsyncWrapDebug(AsyncWrap* async_wrap,
74
                                               const char* format,
75
                                               Args&&... args) {
76
334
  Debug(async_wrap->env(),
77
126
        static_cast<DebugCategory>(async_wrap->provider_type()),
78
126
        async_wrap->diagnostic_name() + " " + format + "\n",
79
        std::forward<Args>(args)...);
80
126
}
81
82
template <typename... Args>
83
inline void FORCE_INLINE Debug(AsyncWrap* async_wrap,
84
                               const char* format,
85
                               Args&&... args) {
86
  DCHECK_NOT_NULL(async_wrap);
87
  DebugCategory cat =
88
1176247
      static_cast<DebugCategory>(async_wrap->provider_type());
89






































1176246
  if (!UNLIKELY(async_wrap->env()->debug_enabled(cat)))
90
    return;
91

126
  UnconditionalAsyncWrapDebug(async_wrap, format, std::forward<Args>(args)...);
92
}
93
94
template <typename... Args>
95
inline void FORCE_INLINE Debug(AsyncWrap* async_wrap,
96
                               const std::string& format,
97
                               Args&&... args) {
98
  Debug(async_wrap, format.c_str(), std::forward<Args>(args)...);
99
}
100
101
// Debug helper for inspecting the currently running `node` executable.
102
class NativeSymbolDebuggingContext {
103
 public:
104
  static std::unique_ptr<NativeSymbolDebuggingContext> New();
105
106
340
  class SymbolInfo {
107
   public:
108
    std::string name;
109
    std::string filename;
110
    size_t line = 0;
111
    size_t dis = 0;
112
113
    std::string Display() const;
114
  };
115
116
23
  NativeSymbolDebuggingContext() = default;
117
23
  virtual ~NativeSymbolDebuggingContext() = default;
118
119
  virtual SymbolInfo LookupSymbol(void* address) { return {}; }
120
  virtual bool IsMapped(void* address) { return false; }
121
  virtual int GetStackTrace(void** frames, int count) { return 0; }
122
123
  NativeSymbolDebuggingContext(const NativeSymbolDebuggingContext&) = delete;
124
  NativeSymbolDebuggingContext(NativeSymbolDebuggingContext&&) = delete;
125
  NativeSymbolDebuggingContext operator=(NativeSymbolDebuggingContext&)
126
    = delete;
127
  NativeSymbolDebuggingContext operator=(NativeSymbolDebuggingContext&&)
128
    = delete;
129
  static std::vector<std::string> GetLoadedLibraries();
130
};
131
132
// Variant of `uv_loop_close` that tries to be as helpful as possible
133
// about giving information on currently existing handles, if there are any,
134
// but still aborts the process.
135
void CheckedUvLoopClose(uv_loop_t* loop);
136
void PrintLibuvHandleInformation(uv_loop_t* loop, FILE* stream);
137
138
}  // namespace node
139
140
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
141
142
#endif  // SRC_DEBUG_UTILS_H_