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