| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 3f4e254 commit d82b0d4
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -734,7 +734,7 @@ Maybe<bool> InitializeContextRuntime(Local<Context> context) { | |||
| 734 | 734 | } | |
| 735 | 735 | } else if (per_process::cli_options->disable_proto != "") { | |
| 736 | 736 | // Validated in ProcessGlobalArgs | |
| 737 | - OnFatalError("InitializeContextRuntime()", "invalid --disable-proto mode"); | ||
| 737 | + UNREACHABLE("invalid --disable-proto mode"); | ||
| 738 | 738 | } | |
| 739 | 739 | ||
| 740 | 740 | return Just(true); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -36,9 +36,6 @@ | |||
| 36 | 36 | namespace node { | |
| 37 | 37 | namespace inspector { | |
| 38 | 38 | namespace { | |
| 39 | - | ||
| 40 | - using node::OnFatalError; | ||
| 41 | - | ||
| 42 | 39 | using v8::Context; | |
| 43 | 40 | using v8::Function; | |
| 44 | 41 | using v8::HandleScope; | |
@@ -917,8 +914,7 @@ void Agent::ToggleAsyncHook(Isolate* isolate, Local<Function> fn) { | |||
| 917 | 914 | USE(fn->Call(context, Undefined(isolate), 0, nullptr)); | |
| 918 | 915 | if (try_catch.HasCaught() && !try_catch.HasTerminated()) { | |
| 919 | 916 | PrintCaughtException(isolate, context, try_catch); | |
| 920 | - OnFatalError("\nnode::inspector::Agent::ToggleAsyncHook", | ||
| 921 | - "Cannot toggle Inspector's AsyncHook, please report this."); | ||
| 917 | + UNREACHABLE("Cannot toggle Inspector's AsyncHook, please report this."); | ||
| 922 | 918 | } | |
| 923 | 919 | } | |
| 924 | 920 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -376,14 +376,7 @@ void AppendExceptionLine(Environment* env, | |||
| 376 | 376 | .FromMaybe(false)); | |
| 377 | 377 | } | |
| 378 | 378 | ||
| 379 | - [[noreturn]] void Abort() { | ||
| 380 | - DumpNativeBacktrace(stderr); | ||
| 381 | - DumpJavaScriptBacktrace(stderr); | ||
| 382 | - fflush(stderr); | ||
| 383 | - ABORT_NO_BACKTRACE(); | ||
| 384 | - } | ||
| 385 | - | ||
| 386 | - [[noreturn]] void Assert(const AssertionInfo& info) { | ||
| 379 | + void Assert(const AssertionInfo& info) { | ||
| 387 | 380 | std::string name = GetHumanReadableProcessName(); | |
| 388 | 381 | ||
| 389 | 382 | fprintf(stderr, | |
@@ -396,15 +389,15 @@ void AppendExceptionLine(Environment* env, | |||
| 396 | 389 | info.message); | |
| 397 | 390 | ||
| 398 | 391 | fflush(stderr); | |
| 399 | - Abort(); | ||
| 392 | + ABORT(); | ||
| 400 | 393 | } | |
| 401 | 394 | ||
| 402 | 395 | enum class EnhanceFatalException { kEnhance, kDontEnhance }; | |
| 403 | 396 | ||
| 404 | 397 | /** | |
| 405 | 398 | * Report the exception to the inspector, then print it to stderr. | |
| 406 | 399 | * This should only be used when the Node.js instance is about to exit | |
| 407 | - * (i.e. this should be followed by a env->Exit() or an Abort()). | ||
| 400 | + * (i.e. this should be followed by a env->Exit() or an ABORT()). | ||
| 408 | 401 | * | |
| 409 | 402 | * Use enhance_stack = EnhanceFatalException::kDontEnhance | |
| 410 | 403 | * when it's unsafe to call into JavaScript. | |
@@ -576,8 +569,7 @@ static void ReportFatalException(Environment* env, | |||
| 576 | 569 | ABORT(); | |
| 577 | 570 | } | |
| 578 | 571 | ||
| 579 | - [[noreturn]] void OOMErrorHandler(const char* location, | ||
| 580 | - const v8::OOMDetails& details) { | ||
| 572 | + void OOMErrorHandler(const char* location, const v8::OOMDetails& details) { | ||
| 581 | 573 | // We should never recover from this handler so once it's true it's always | |
| 582 | 574 | // true. | |
| 583 | 575 | is_in_oom.store(true); | |
@@ -1063,7 +1055,7 @@ static void TriggerUncaughtException(const FunctionCallbackInfo<Value>& args) { | |||
| 1063 | 1055 | if (env != nullptr && env->abort_on_uncaught_exception()) { | |
| 1064 | 1056 | ReportFatalException( | |
| 1065 | 1057 | env, exception, message, EnhanceFatalException::kEnhance); | |
| 1066 | - Abort(); | ||
| 1058 | + ABORT(); | ||
| 1067 | 1059 | } | |
| 1068 | 1060 | bool from_promise = args[1]->IsTrue(); | |
| 1069 | 1061 | errors::TriggerUncaughtException(isolate, exception, message, from_promise); | |
@@ -1174,7 +1166,7 @@ void TriggerUncaughtException(Isolate* isolate, | |||
| 1174 | 1166 | // much we can do, so we just print whatever is useful and crash. | |
| 1175 | 1167 | PrintToStderrAndFlush( | |
| 1176 | 1168 | FormatCaughtException(isolate, context, error, message)); | |
| 1177 | - Abort(); | ||
| 1169 | + ABORT(); | ||
| 1178 | 1170 | } | |
| 1179 | 1171 | ||
| 1180 | 1172 | // Invoke process._fatalException() to give user a chance to handle it. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -19,9 +19,14 @@ void AppendExceptionLine(Environment* env, | |||
| 19 | 19 | v8::Local<v8::Message> message, | |
| 20 | 20 | enum ErrorHandlingMode mode); | |
| 21 | 21 | ||
| 22 | + // This function calls backtrace, it should have not be marked as [[noreturn]]. | ||
| 23 | + // But it is a public API, removing the attribute can break. | ||
| 24 | + // Prefer UNREACHABLE() internally instead, it doesn't need manually set | ||
| 25 | + // location. | ||
| 22 | 26 | [[noreturn]] void OnFatalError(const char* location, const char* message); | |
| 23 | - [[noreturn]] void OOMErrorHandler(const char* location, | ||
| 24 | - const v8::OOMDetails& details); | ||
| 27 | + // This function calls backtrace, do not mark as [[noreturn]]. Read more in the | ||
| 28 | + // ABORT macro. | ||
| 29 | + void OOMErrorHandler(const char* location, const v8::OOMDetails& details); | ||
| 25 | 30 | ||
| 26 | 31 | // Helpers to construct errors similar to the ones provided by | |
| 27 | 32 | // lib/internal/errors.js. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -64,7 +64,7 @@ Mutex umask_mutex; | |||
| 64 | 64 | #define NANOS_PER_SEC 1000000000 | |
| 65 | 65 | ||
| 66 | 66 | static void Abort(const FunctionCallbackInfo<Value>& args) { | |
| 67 | - Abort(); | ||
| 67 | + ABORT(); | ||
| 68 | 68 | } | |
| 69 | 69 | ||
| 70 | 70 | // For internal testing only, not exposed to userland. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -45,7 +45,7 @@ Watchdog::Watchdog(v8::Isolate* isolate, uint64_t ms, bool* timed_out) | |||
| 45 | 45 | int rc; | |
| 46 | 46 | rc = uv_loop_init(&loop_); | |
| 47 | 47 | if (rc != 0) { | |
| 48 | - OnFatalError("node::Watchdog::Watchdog()", "Failed to initialize uv loop."); | ||
| 48 | + UNREACHABLE("Failed to initialize uv loop."); | ||
| 49 | 49 | } | |
| 50 | 50 | ||
| 51 | 51 | rc = uv_async_init(&loop_, &async_, [](uv_async_t* signal) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -113,8 +113,9 @@ struct AssertionInfo { | |||
| 113 | 113 | const char* message; | |
| 114 | 114 | const char* function; | |
| 115 | 115 | }; | |
| 116 | - [[noreturn]] void NODE_EXTERN_PRIVATE Assert(const AssertionInfo& info); | ||
| 117 | - [[noreturn]] void NODE_EXTERN_PRIVATE Abort(); | ||
| 116 | + | ||
| 117 | + // This indirectly calls backtrace so it can not be marked as [[noreturn]]. | ||
| 118 | + void NODE_EXTERN_PRIVATE Assert(const AssertionInfo& info); | ||
| 118 | 119 | void DumpNativeBacktrace(FILE* fp); | |
| 119 | 120 | void DumpJavaScriptBacktrace(FILE* fp); | |
| 120 | 121 | ||
@@ -125,16 +126,32 @@ void DumpJavaScriptBacktrace(FILE* fp); | |||
| 125 | 126 | #define ABORT_NO_BACKTRACE() abort() | |
| 126 | 127 | #endif | |
| 127 | 128 | ||
| 128 | - #define ABORT() node::Abort() | ||
| 129 | + // Caller of this macro must not be marked as [[noreturn]]. Printing of | ||
| 130 | + // backtraces may not work correctly in [[noreturn]] functions because | ||
| 131 | + // when generating code for them the compiler can choose not to | ||
| 132 | + // maintain the frame pointers or link registers that are necessary for | ||
| 133 | + // correct backtracing. | ||
| 134 | + // `ABORT` must be a macro and not a [[noreturn]] function to make sure the | ||
| 135 | + // backtrace is correct. | ||
| 136 | + #define ABORT() \ | ||
| 137 | + do { \ | ||
| 138 | + node::DumpNativeBacktrace(stderr); \ | ||
| 139 | + node::DumpJavaScriptBacktrace(stderr); \ | ||
| 140 | + fflush(stderr); \ | ||
| 141 | + ABORT_NO_BACKTRACE(); \ | ||
| 142 | + } while (0) | ||
| 129 | 143 | ||
| 130 | - #define ERROR_AND_ABORT(expr) \ | ||
| 131 | - do { \ | ||
| 132 | - /* Make sure that this struct does not end up in inline code, but */ \ | ||
| 133 | - /* rather in a read-only data section when modifying this code. */ \ | ||
| 134 | - static const node::AssertionInfo args = { \ | ||
| 135 | - __FILE__ ":" STRINGIFY(__LINE__), #expr, PRETTY_FUNCTION_NAME \ | ||
| 136 | - }; \ | ||
| 137 | - node::Assert(args); \ | ||
| 144 | + #define ERROR_AND_ABORT(expr) \ | ||
| 145 | + do { \ | ||
| 146 | + /* Make sure that this struct does not end up in inline code, but */ \ | ||
| 147 | + /* rather in a read-only data section when modifying this code. */ \ | ||
| 148 | + static const node::AssertionInfo args = { \ | ||
| 149 | + __FILE__ ":" STRINGIFY(__LINE__), #expr, PRETTY_FUNCTION_NAME}; \ | ||
| 150 | + node::Assert(args); \ | ||
| 151 | + /* `node::Assert` doesn't return. Add an [[noreturn]] abort() here to */ \ | ||
| 152 | + /* make the compiler happy about no return value in the caller */ \ | ||
| 153 | + /* function when calling ERROR_AND_ABORT. */ \ | ||
| 154 | + ABORT_NO_BACKTRACE(); \ | ||
| 138 | 155 | } while (0) | |
| 139 | 156 | ||
| 140 | 157 | #ifdef __GNUC__ | |
| Back | FazBrowse Home | New Git URL |
0 commit comments