8000
We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
There was an error while loading. Please reload this page.
1 parent 2388a40 commit 5127c70Copy full SHA for 5127c70
src/debug_utils-inl.h
@@ -4,6 +4,7 @@
4
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
6
#include "debug_utils.h"
7
+#include "env.h"
8
9
#include <type_traits>
10
@@ -90,6 +91,79 @@ void COLD_NOINLINE FPrintF(FILE* file, const char* format, Args&&... args) {
90
91
FWrite(file, SPrintF(format, std::forward<Args>(args)...));
92
}
93
94
+template <typename... Args>
95
+inline void FORCE_INLINE Debug(EnabledDebugList* list,
96
+ DebugCategory cat,
97
+ const char* format,
98
+ Args&&... args) {
99
+ if (!UNLIKELY(list->enabled(cat))) return;
100
+ FPrintF(stderr, format, std::forward<Args>(args)...);
101
+}
102
+
103
104
105
+ const char* message) {
106
107
+ FPrintF(stderr, "%s", message);
108
109
110
111
+inline void FORCE_INLINE
112
+Debug(Environment* env, DebugCategory cat, const char* format, Args&&... args) {
113 8000
+ Debug(env->enabled_debug_list(), cat, format, std::forward<Args>(args)...);
114
115
116
+inline void FORCE_INLINE Debug(Environment* env,
117
118
119
+ Debug(env->enabled_debug_list(), cat, message);
120
121
122
123
+inline void Debug(Environment* env,
124
125
+ const std::string& format,
126
127
+ Debug(env->enabled_debug_list(),
128
+ cat,
129
+ format.c_str(),
130
+ std::forward<Args>(args)...);
131
132
133
+// Used internally by the 'real' Debug(AsyncWrap*, ...) functions below, so that
134
+// the FORCE_INLINE flag on them doesn't apply to the contents of this function
135
+// as well.
136
+// We apply COLD_NOINLINE to tell the compiler that it's not worth optimizing
137
+// this function for speed and it should rather focus on keeping it out of
138
+// hot code paths. In particular, we want to keep the string concatenating code
139
+// out of the function containing the original `Debug()` call.
140
141
+void COLD_NOINLINE UnconditionalAsyncWrapDebug(AsyncWrap* async_wrap,
142
143
144
+ Debug(async_wrap->env(),
145
+ static_cast<DebugCategory>(async_wrap->provider_type()),
146
+ async_wrap->diagnostic_name() + " " + format + "\n",
147
148
149
150
151
+inline void FORCE_INLINE Debug(AsyncWrap* async_wrap,
152
153
154
+ DCHECK_NOT_NULL(async_wrap);
155
+ DebugCategory cat = static_cast<DebugCategory>(async_wrap->provider_type());
156
+ if (!UNLIKELY(async_wrap->env()->enabled_debug_list()->enabled(cat))) return;
157
+ UnconditionalAsyncWrapDebug(async_wrap, format, std::forward<Args>(args)...);
158
159
160
161
162
163
164
+ Debug(async_wrap, format.c_str(), std::forward<Args>(args)...);
165
166
167
} // namespace node
168
169
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
src/debug_utils.cc
@@ -1,5 +1,6 @@
1
#include "debug_utils-inl.h" // NOLINT(build/include)
2
#include "env-inl.h"
3
+#include "node_internals.h"
#ifdef __POSIX__
#if defined(__linux__)
@@ -54,6 +55,34 @@
54
55
56
namespace node {
57
58
+void EnabledDebugList::Parse(Environment* env) {
59
+ std::string cats;
60
+ credentials::SafeGetenv("NODE_DEBUG_NATIVE", &cats, env);
61
+ Parse(cats, true);
62
63
64
+void EnabledDebugList::Parse(const std::string& cats, bool enabled) {
65
+ std::string debug_categories = cats;
66
+ while (!debug_categories.empty()) {
67
+ std::string::size_type comma_pos = debug_categories.find(',');
68
+ std::string wanted = ToLower(debug_categories.substr(0, comma_pos));
69
70
+#define V(name) \
71
+ { \
72
+ static const std::string available_category = ToLower(#name); \
73
+ if (available_category.find(wanted) != std::string::npos) \
74
+ set_enabled(DebugCategory::name, enabled); \
75
+ }
76
77
+ DEBUG_CATEGORY_NAMES(V)
78
+#undef V
79
80
+ if (comma_pos == std::string::npos) break;
81
+ // Use everything after the `,` as the list for the next iteration.
82
+ debug_categories = debug_categories.substr(comma_pos + 1);
83
84
85
86
87
#if HAVE_EXECINFO_H
88
class PosixSymbolDebuggingContext final : public NativeSymbolDebuggingContext {
src/debug_utils.h
@@ -4,7 +4,6 @@
#include "async_wrap.h"
-#include "env.h"
#include <sstream>
#include <string>
@@ -21,6 +20,7 @@
21
20
#endif
22
23
+class Environment;
24
25
template <typename T>
26
inline std::string ToString(const T& value);
@@ -36,31 +36,71 @@ 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
+// Listing the AsyncWrap provider types first enables us to cast directly
40
+// from a provider type to a debug category.
41
+#define DEBUG_CATEGORY_NAMES(V) \
42
+ NODE_ASYNC_PROVIDER_TYPES(V) \
43
+ V(INSPECTOR_SERVER) \
44
+ V(INSPECTOR_PROFILER) \
45
+ V(WASI)
46
47
+enum class DebugCategory {
48
+#define V(name) name,
49
50
51
+ CATEGORY_COUNT
52
+};
53
+class EnabledDebugList {
+ public:
+ bool enabled(DebugCategory category) const {
+ DCHECK_GE(static_cast<int>(category), 0);
+ DCHECK_LT(static_cast<int>(category),
+ static_cast<int>(DebugCategory::CATEGORY_COUNT));
+ return enabled_[static_cast<int>(category)];
+ // Uses NODE_DEBUG_NATIVE to initialize the categories. When env is not a
+ // nullptr, the environment variables set in the Environment are used.
+ // Otherwise the system environment variables are used.
+ void Parse(Environment* env);
+ private:
+ // Set all categories matching cats to the value of enabled.
+ void Parse(const std::string& cats, bool enabled);
+ void set_enabled(DebugCategory category, bool enabled) {
+ enabled_[static_cast<int>(category)] = true;
+ bool enabled_[static_cast<int>(DebugCategory::CATEGORY_COUNT)] = {false};
template <typename... Args>
-inline void FORCE_INLINE Debug(Environment* env,
DebugCategory cat,
const char* format,
- Args&&... args) {
- if (!UNLIKELY(env->debug_enabled(cat)))
- return;
- FPrintF(stderr, format, std::forward<Args>(args)...);
-}
+ Args&&... args);
89
+ const char* message);
+Debug(Environment* env, DebugCategory cat, const char* format, Args&&... args);
inline void FORCE_INLINE Debug(Environment* env,
- const char* message) {
- FPrintF(stderr, "%s", message);
inline void Debug(Environment* env,
const std::string& format,
- Debug(env, cat, format.c_str(), std::forward<Args>(args)...);
// Used internally by the 'real' Debug(AsyncWrap*, ...) functions below, so that
// the FORCE_INLINE flag on them doesn't apply to the contents of this function
@@ -72,31 +112,17 @@ inline void Debug(Environment* env,
113
void COLD_NOINLINE UnconditionalAsyncWrapDebug(AsyncWrap* async_wrap,
- Debug(async_wrap->env(),
- static_cast<DebugCategory>(async_wrap->provider_type()),
- async_wrap->diagnostic_name() + " " + format + "\n",
- std::forward<Args>(args)...);
inline void FORCE_INLINE Debug(AsyncWrap* async_wrap,
- DCHECK_NOT_NULL(async_wrap);
- DebugCategory cat =
- static_cast<DebugCategory>(async_wrap->provider_type());
- if (!UNLIKELY(async_wrap->env()->debug_enabled(cat)))
- UnconditionalAsyncWrapDebug(async_wrap, format, std::forward<Args>(args)...);
- Debug(async_wrap, format.c_str(), std::forward<Args>(args)...);
// Debug helper for inspecting the currently running `node` executable.
class NativeSymbolDebuggingContext {
src/env-inl.h
@@ -606,20 +606,6 @@ inline void Environment::set_http2_state(
606
http2_state_ = std::move(buffer);
607
608
609
-bool Environment::debug_enabled(DebugCategory category) const {
610
- DCHECK_GE(static_cast<int>(category), 0);
611
- DCHECK_LT(static_cast<int>(category),
612
- static_cast<int>(DebugCategory::CATEGORY_COUNT));
613
- return debug_enabled_[static_cast<int>(category)];
614
615
-
616
-void Environment::set_debug_enabled(DebugCategory category, bool enabled) {
617
618
619
620
- debug_enabled_[static_cast<int>(category)] = enabled;
621
622
623
inline AliasedFloat64Array* Environment::fs_stats_field_array() {
624
return &fs_stats_field_array_;
625
src/env.cc
@@ -1,6 +1,7 @@
#include "env.h"
+#include "debug_utils-inl.h"
#include "memory_tracker-inl.h"
#include "node_buffer.h"
#include "node_context_data.h"
@@ -315,6 +316,7 @@ Environment::Environment(IsolateData* isolate_data,
315
316
Context::Scope context_scope(context);
317
318
set_env_vars(per_process::system_environment);
319
+ enabled_debug_list_.Parse(this);
320
321
// We create new copies of the per-Environment option sets, so that it is
322
// easier to modify them after Environment creation. The defaults are
@@ -375,10 +377,6 @@ Environment::Environment(IsolateData* isolate_data,
375
377
// By default, always abort when --abort-on-uncaught-exception was passed.
376
378
should_abort_on_uncaught_toggle_[0] = 1;
379
- std::string debug_cats;
- credentials::SafeGetenv("NODE_DEBUG_NATIVE", &debug_cats, this);
380
- set_debug_categories(debug_cats, true);
381
382
if (options_->no_force_async_hooks_checks) {
383
async_hooks_.no_force_checks();
384
@@ -867,29 +865,6 @@ Local<Value> Environment::GetNow() {
867
865
return Number::New(isolate(), static_cast<double>(now));
868
866
869
870
-void Environment::set_debug_categories(const std::string& cats, bool enabled) {
871
- std::string debug_categories = cats;
872
- while (!debug_categories.empty()) {
873
- std::string::size_type comma_pos = debug_categories.find(',');
874
- std::string wanted = ToLower(debug_categories.substr(0, comma_pos));
875
876
-#define V(name) \
877
- { \
878
- static const std::string available_category = ToLower(#name); \
879
- if (available_category.find(wanted) != std::string::npos) \
880
- set_debug_enabled(DebugCategory::name, enabled); \
881
- }
882
883
- DEBUG_CATEGORY_NAMES(V)
884
-#undef V
885
886
- if (comma_pos == std::string::npos)
887
- break;
888
- // Use everything after the `,` as the list for the next iteration.
889
- debug_categories = debug_categories.substr(comma_pos + 1);
890
891
892
893
void CollectExceptionInfo(Environment* env,
894
Local<Object> obj,
895
int errorno,
src/env.h
@@ -29,6 +29,7 @@
29
#include "inspector_agent.h"
30
#include "inspector_profiler.h"
31
32
+#include "debug_utils.h"
33
#include "handle_wrap.h"
34
#include "node.h"
35
#include "node_binding.h"
@@ -550,20 +551,7 @@ struct ContextInfo {
550
551
bool is_default = false;
552
};
553
-// Listing the AsyncWrap provider types first enables us to cast directly
554
-// from a provider type to a debug category.
555
-#define DEBUG_CATEGORY_NAMES(V) \
556
- NODE_ASYNC_PROVIDER_TYPES(V) \
557
- V(INSPECTOR_SERVER) \
558
- V(INSPECTOR_PROFILER) \
559
- V(WASI)
560
561
-enum class DebugCategory {
562
-#define V(name) name,
563
564
565
- CATEGORY_COUNT
566
-};
+class EnabledDebugList;
567
568
// A unique-pointer-ish object that is compatible with the JS engine's
569
// ArrayBuffer::Allocator.
@@ -1024,9 +1012,7 @@ class Environment : public MemoryRetainer {
1024
1012
inline http2::Http2State* http2_state() const;
1025
1013
inline void set_http2_state(std::unique_ptr<http2::Http2State> state);
1026
1014
1027
- inline bool debug_enabled(DebugCategory category) const;
1028
- inline void set_debug_enabled(DebugCategory category, bool enabled);
1029
- void set_debug_categories(const std::string& cats, bool enabled);
1015
+ EnabledDebugList* enabled_debug_list() { return &enabled_debug_list_; }
1030
1016
1031
1017
inline AliasedFloat64Array* fs_stats_field_array();
1032
1018
inline AliasedBigUint64Array* fs_stats_field_bigint_array();
@@ -1382,9 +1368,7 @@ class Environment : public MemoryRetainer {
1382
1368
bool http_parser_buffer_in_use_ = false;
1383
1369
std::unique_ptr<http2::Http2State> http2_state_;
1384
1370
1385
- bool debug_enabled_[static_cast<int>(DebugCategory::CATEGORY_COUNT)] = {
1386
- false};
1387
1371
+ EnabledDebugList enabled_debug_list_;
1388
1372
AliasedFloat64Array fs_stats_field_array_;
1389
1373
AliasedBigUint64Array fs_stats_field_bigint_array_;
1390
1374