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-05-27 22:15:15 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(WASI)
49
50
enum class DebugCategory {
51
#define V(name) name,
52
  DEBUG_CATEGORY_NAMES(V)
53
#undef V
54
      CATEGORY_COUNT
55
};
56
57
4594
class EnabledDebugList {
58
 public:
59
1243283
  bool enabled(DebugCategory category) const {
60
    DCHECK_GE(static_cast<int>(category), 0);
61
    DCHECK_LT(static_cast<int>(category),
62
              static_cast<int>(DebugCategory::CATEGORY_COUNT));
63
1243283
    return enabled_[static_cast<int>(category)];
64
  }
65
66
  // Uses NODE_DEBUG_NATIVE to initialize the categories. When env is not a
67
  // nullptr, the environment variables set in the Environment are used.
68
  // Otherwise the system environment variables are used.
69
  void Parse(Environment* env);
70
71
 private:
72
  // Set all categories matching cats to the value of enabled.
73
  void Parse(const std::string& cats, bool enabled);
74
94
  void set_enabled(DebugCategory category, bool enabled) {
75
    DCHECK_GE(static_cast<int>(category), 0);
76
    DCHECK_LT(static_cast<int>(category),
77
              static_cast<int>(DebugCategory::CATEGORY_COUNT));
78
94
    enabled_[static_cast<int>(category)] = true;
79
94
  }
80
81
  bool enabled_[static_cast<int>(DebugCategory::CATEGORY_COUNT)] = {false};
82
};
83
84
template <typename... Args>
85
inline void FORCE_INLINE Debug(EnabledDebugList* list,
86
                               DebugCategory cat,
87
                               const char* format,
88
                               Args&&... args);
89
90
inline void FORCE_INLINE Debug(EnabledDebugList* list,
91
                               DebugCategory cat,
92
                               const char* message);
93
94
template <typename... Args>
95
inline void FORCE_INLINE
96
Debug(Environment* env, DebugCategory cat, const char* format, Args&&... args);
97
98
inline void FORCE_INLINE Debug(Environment* env,
99
                               DebugCategory cat,
100
                               const char* message);
101
102
template <typename... Args>
103
inline void Debug(Environment* env,
104
                  DebugCategory cat,
105
                  const std::string& format,
106
                  Args&&... args);
107
108
// Used internally by the 'real' Debug(AsyncWrap*, ...) functions below, so that
109
// the FORCE_INLINE flag on them doesn't apply to the contents of this function
110
// as well.
111
// We apply COLD_NOINLINE to tell the compiler that it's not worth optimizing
112
// this function for speed and it should rather focus on keeping it out of
113
// hot code paths. In particular, we want to keep the string concatenating code
114
// out of the function containing the original `Debug()` call.
115
template <typename... Args>
116
void COLD_NOINLINE UnconditionalAsyncWrapDebug(AsyncWrap* async_wrap,
117
                                               const char* format,
118
                                               Args&&... args);
119
120
template <typename... Args>
121
inline void FORCE_INLINE Debug(AsyncWrap* async_wrap,
122
                               const char* format,
123
                               Args&&... args);
124
125
template <typename... Args>
126
inline void FORCE_INLINE Debug(AsyncWrap* async_wrap,
127
                               const std::string& format,
128
                               Args&&... args);
129
130
// Debug helper for inspecting the currently running `node` executable.
131
class NativeSymbolDebuggingContext {
132
 public:
133
  static std::unique_ptr<NativeSymbolDebuggingContext> New();
134
135
370
  class SymbolInfo {
136
   public:
137
    std::string name;
138
    std::string filename;
139
    size_t line = 0;
140
    size_t dis = 0;
141
142
    std::string Display() const;
143
  };
144
145
24
  NativeSymbolDebuggingContext() = default;
146
24
  virtual ~NativeSymbolDebuggingContext() = default;
147
148
  virtual SymbolInfo LookupSymbol(void* address) { return {}; }
149
  virtual bool IsMapped(void* address) { return false; }
150
  virtual int GetStackTrace(void** frames, int count) { return 0; }
151
152
  NativeSymbolDebuggingContext(const NativeSymbolDebuggingContext&) = delete;
153
  NativeSymbolDebuggingContext(NativeSymbolDebuggingContext&&) = delete;
154
  NativeSymbolDebuggingContext operator=(NativeSymbolDebuggingContext&)
155
    = delete;
156
  NativeSymbolDebuggingContext operator=(NativeSymbolDebuggingContext&&)
157
    = delete;
158
  static std::vector<std::string> GetLoadedLibraries();
159
};
160
161
// Variant of `uv_loop_close` that tries to be as helpful as possible
162
// about giving information on currently existing handles, if there are any,
163
// but still aborts the process.
164
void CheckedUvLoopClose(uv_loop_t* loop);
165
void PrintLibuvHandleInformation(uv_loop_t* loop, FILE* stream);
166
167
namespace per_process {
168
extern EnabledDebugList enabled_debug_list;
169
170
template <typename... Args>
171
inline void FORCE_INLINE Debug(DebugCategory cat,
172
                               const char* format,
173
                               Args&&... args);
174
175
inline void FORCE_INLINE Debug(DebugCategory cat, const char* message);
176
}  // namespace per_process
177
}  // namespace node
178
179
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
180
181
#endif  // SRC_DEBUG_UTILS_H_