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: 9 12 75.0 %
Date: 2020-07-19 22:14:24 Branches: 0 0 - %

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
8
#include <algorithm>
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
class Environment;
25
26
template <typename T>
27
inline std::string ToString(const T& value);
28
29
// C++-style variant of sprintf()/fprintf() that:
30
// - Returns an std::string
31
// - Handles \0 bytes correctly
32
// - Supports %p and %s. %d, %i and %u are aliases for %s.
33
// - Accepts any class that has a ToString() method for stringification.
34
template <typename... Args>
35
inline std::string SPrintF(const char* format, Args&&... args);
36
template <typename... Args>
37
inline void FPrintF(FILE* file, const char* format, Args&&... args);
38
void FWrite(FILE* file, const std::string& str);
39
40
// Listing the AsyncWrap provider types first enables us to cast directly
41
// from a provider type to a debug category.
42
#define DEBUG_CATEGORY_NAMES(V)                                                \
43
  NODE_ASYNC_PROVIDER_TYPES(V)                                                 \
44
  V(HUGEPAGES)                                                                 \
45
  V(INSPECTOR_SERVER)                                                          \
46
  V(INSPECTOR_PROFILER)                                                        \
47
  V(CODE_CACHE)                                                                \
48
  V(NGTCP2_DEBUG)                                                              \
49
  V(WASI)                                                                      \
50
  V(MKSNAPSHOT)
51
52
enum class DebugCategory {
53
#define V(name) name,
54
  DEBUG_CATEGORY_NAMES(V)
55
#undef V
56
      CATEGORY_COUNT
57
};
58
59
5303
class EnabledDebugList {
60
 public:
61
1291838
  bool enabled(DebugCategory category) const {
62
    DCHECK_GE(static_cast<int>(category), 0);
63
    DCHECK_LT(static_cast<int>(category),
64
              static_cast<int>(DebugCategory::CATEGORY_COUNT));
65
1291838
    return enabled_[static_cast<int>(category)];
66
  }
67
68
  // Uses NODE_DEBUG_NATIVE to initialize the categories. When env is not a
69
  // nullptr, the environment variables set in the Environment are used.
70
  // Otherwise the system environment variables are used.
71
  void Parse(Environment* env);
72
73
 private:
74
  // Set all categories matching cats to the value of enabled.
75
  void Parse(const std::string& cats, bool enabled);
76
96
  void set_enabled(DebugCategory category, bool enabled) {
77
    DCHECK_GE(static_cast<int>(category), 0);
78
    DCHECK_LT(static_cast<int>(category),
79
              static_cast<int>(DebugCategory::CATEGORY_COUNT));
80
96
    enabled_[static_cast<int>(category)] = true;
81
96
  }
82
83
  bool enabled_[static_cast<int>(DebugCategory::CATEGORY_COUNT)] = {false};
84
};
85
86
template <typename... Args>
87
inline void FORCE_INLINE Debug(EnabledDebugList* list,
88
                               DebugCategory cat,
89
                               const char* format,
90
                               Args&&... args);
91
92
inline void FORCE_INLINE Debug(EnabledDebugList* list,
93
                               DebugCategory cat,
94
                               const char* message);
95
96
template <typename... Args>
97
inline void FORCE_INLINE
98
Debug(Environment* env, DebugCategory cat, const char* format, Args&&... args);
99
100
inline void FORCE_INLINE Debug(Environment* env,
101
                               DebugCategory cat,
102
                               const char* message);
103
104
template <typename... Args>
105
inline void Debug(Environment* env,
106
                  DebugCategory cat,
107
                  const std::string& format,
108
                  Args&&... args);
109
110
// Used internally by the 'real' Debug(AsyncWrap*, ...) functions below, so that
111
// the FORCE_INLINE flag on them doesn't apply to the contents of this function
112
// as well.
113
// We apply COLD_NOINLINE to tell the compiler that it's not worth optimizing
114
// this function for speed and it should rather focus on keeping it out of
115
// hot code paths. In particular, we want to keep the string concatenating code
116
// out of the function containing the original `Debug()` call.
117
template <typename... Args>
118
void COLD_NOINLINE UnconditionalAsyncWrapDebug(AsyncWrap* async_wrap,
119
                                               const char* format,
120
                                               Args&&... args);
121
122
template <typename... Args>
123
inline void FORCE_INLINE Debug(AsyncWrap* async_wrap,
124
                               const char* format,
125
                               Args&&... args);
126
127
template <typename... Args>
128
inline void FORCE_INLINE Debug(AsyncWrap* async_wrap,
129
                               const std::string& format,
130
                               Args&&... args);
131
132
// Debug helper for inspecting the currently running `node` executable.
133
class NativeSymbolDebuggingContext {
134
 public:
135
  static std::unique_ptr<NativeSymbolDebuggingContext> New();
136
137
398
  class SymbolInfo {
138
   public:
139
    std::string name;
140
    std::string filename;
141
    size_t line = 0;
142
    size_t dis = 0;
143
144
    std::string Display() const;
145
  };
146
147
26
  NativeSymbolDebuggingContext() = default;
148
26
  virtual ~NativeSymbolDebuggingContext() = default;
149
150
  virtual SymbolInfo LookupSymbol(void* address) { return {}; }
151
  virtual bool IsMapped(void* address) { return false; }
152
  virtual int GetStackTrace(void** frames, int count) { return 0; }
153
154
  NativeSymbolDebuggingContext(const NativeSymbolDebuggingContext&) = delete;
155
  NativeSymbolDebuggingContext(NativeSymbolDebuggingContext&&) = delete;
156
  NativeSymbolDebuggingContext operator=(NativeSymbolDebuggingContext&)
157
    = delete;
158
  NativeSymbolDebuggingContext operator=(NativeSymbolDebuggingContext&&)
159
    = delete;
160
  static std::vector<std::string> GetLoadedLibraries();
161
};
162
163
// Variant of `uv_loop_close` that tries to be as helpful as possible
164
// about giving information on currently existing handles, if there are any,
165
// but still aborts the process.
166
void CheckedUvLoopClose(uv_loop_t* loop);
167
void PrintLibuvHandleInformation(uv_loop_t* loop, FILE* stream);
168
169
namespace per_process {
170
extern EnabledDebugList enabled_debug_list;
171
172
template <typename... Args>
173
inline void FORCE_INLINE Debug(DebugCategory cat,
174
                               const char* format,
175
                               Args&&... args);
176
177
inline void FORCE_INLINE Debug(DebugCategory cat, const char* message);
178
}  // namespace per_process
179
}  // namespace node
180
181
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
182
183
#endif  // SRC_DEBUG_UTILS_H_