mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
30950864d3
This patch: - Introduce an internal GetCurrentStackTrace() utility to get the current JavaScript stack trace with best effort. - Indent the assertion message so that is separated from the native stack trace for redability - Print the JS stack trace when it's available Previoiusly the abort message looks like this: ``` out/Release/node[24458]: ../../src/node_file.cc:2008:void node::fs::Ope n(const FunctionCallbackInfo<v8::Value> &): Assertion `(argc) >= (3)' f ailed. 1: 0x1043fb9a4 node::Abort() [node] 2: 0x1043fb6e4 node::PrintCaughtException(v8::Isolate*, v8::Local<v8:: Context>, v8::TryCatch const&) [node] 3: 0x104407708 node::fs::Open(v8::FunctionCallbackInfo<v8::Value> cons t&) [node] 4: 0x104611e74 v8::internal::MaybeHandle<v8::internal::Object> v8::int ernal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal:: Isolate*, v8::internal::Handle<v8::internal::HeapObject >, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::intern al::Handle<v8::internal::Object>, unsigned long*, int) [node ] 5: 0x1046116c8 v8::internal::Builtin_HandleApiCall(int, unsigned long* , v8::internal::Isolate*) [node] 6: 0x104e9cb24 Builtins_CEntry_Return1_ArgvOnStack_BuiltinExit [node] 7: 0x104e143e4 Builtins_InterpreterEntryTrampoline [node] 8: 0x104e1250c Builtins_JSEntryTrampoline [node] 9: 0x104e121f4 Builtins_JSEntry [node] 10: 0x1046ed54c v8::internal::(anonymous namespace)::Invoke(v8::interna l::Isolate*, v8::internal::(anonymous namespace)::InvokeParams const&) [node] 11: 0x1046edb60 v8::internal::Execution::CallScript(v8::internal::Isola te*, v8::internal::Handle<v8::internal::JSFunction>, v8::internal::Hand le<v8::internal::Object>, v8::internal::Handle<v8::in ternal::Object>) [node] 12: 0x1045a9fa0 v8::Script::Run(v8::Local<v8::Context>, v8::Local<v8::D ata>) [node] 13: 0x1043efb68 node::contextify::ContextifyScript::EvalMachine(v8::Loc al<v8::Context>, node::Environment*, long long, bool, bool, bool, v8::M icrotaskQueue*, v8::FunctionCallbackInfo<v8::Value> const&) [node ] 14: 0x1043ef3e0 node::contextify::ContextifyScript::RunInContext(v8::Fu nctionCallbackInfo<v8::Value> const&) [node] 15: 0x104611e74 v8::internal::MaybeHandle<v8::internal::Object> v8::int ernal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal:: Isolate*, v8::internal::Handle<v8::internal::HeapObject> , v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::interna l::Handle<v8::internal::Object>, unsigned long*, int) [node ] 16: 0x1046116c8 v8::internal::Builtin_HandleApiCall(int, unsigned long* , v8::internal::Isolate*) [node] 17: 0x104e9cb24 Builtins_CEntry_Return1_ArgvOnStack_BuiltinExit [node] 18: 0x104e143e4 Builtins_InterpreterEntryTrampoline [node] 19: 0x104e143e4 Builtins_InterpreterEntryTrampoline [node] 20: 0x104e143e4 Builtins_InterpreterEntryTrampoline [node] 21: 0x104e143e4 Builtins_InterpreterEntryTrampoline [node] 22: 0x104e143e4 Builtins_InterpreterEntryTrampoline [node] 23: 0x104e143e4 Builtins_InterpreterEntryTrampoline [node] 24: 0x104e143e4 Builtins_InterpreterEntryTrampoline [node] 25: 0x104e1250c Builtins_JSEntryTrampoline [node] 26: 0x104e121f4 Builtins_JSEntry [node] 27: 0x1046ed54c v8::internal::(anonymous namespace)::Invoke(v8::interna l::Isolate*, v8::internal::(anonymous namespace)::InvokeParams const&) [node] 28: 0x1046ecdc8 v8::internal::Execution::Call(v8::internal::Isolate*, v 8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::int ernal::Object>, int, v8::internal::Handle<v 8::internal::Object>*) [node] 29: 0x1045be23c v8::Function::Call(v8::Local<v8::Context>, v8::Local<v8 ::Value>, int, v8::Local<v8::Value>*) [node] 30: 0x1043df704 node::builtins::BuiltinLoader::CompileAndCall(v8::Local <v8::Context>, char const*, node::Realm*) [node] 31: 0x10446f2d4 node::Realm::ExecuteBootstrapper(char const*) [node] 32: 0x1043c3378 node::StartExecution(node::Environment*, std::__1::func tion<v8::MaybeLocal<v8::Value> (node::StartExecutionCallbackInfo const& )>) [node] 33: 0x10432dc28 node::LoadEnvironment(node::Environment*, std::__1::fun ction<v8::MaybeLocal<v8::Value> (node::StartExecutionCallbackInfo const &)>) [node] 34: 0x10443d1f4 node::NodeMainInstance::Run(node::ExitCode*, node::Envi ronment*) [node] 35: 0x10443cfd0 node::NodeMainInstance::Run() [node] 36: 0x1043c5d18 node::Start(int, char**) [node] 37: 0x19a027f28 start [/usr/lib/dyld] [1] 24458 abort out/Release/node -p "process.binding('fs').open ()" ``` Now it looks like this: ``` # out/Release/node[24856]: void node::fs::Open(const FunctionCallbac kInfo<v8::Value> &) at ../../src/node_file.cc:2008 # Assertion failed: (argc) >= (3) ----- Native stack trace ----- 1: 0x1001efe64 node::Abort() [node] 2: 0x1001efba4 node::PrintCaughtException(v8::Isolate*, v8::Local<v8:: Context>, v8::TryCatch const&) [node] 3: 0x1001fb868 node::fs::Open(v8::FunctionCallbackInfo<v8::Value> cons t&) [node] 4: 0x100405fd4 v8::internal::MaybeHandle<v8::internal::Object> v8::int ernal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal:: Isolate*, v8::internal::Handle<v8::internal::HeapObject >, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::intern al::Handle<v8::internal::Object>, unsigned long*, int) [node ] 5: 0x100405828 v8::internal::Builtin_HandleApiCall(int, unsigned long* , v8::internal::Isolate*) [node] 6: 0x100c90b24 Builtins_CEntry_Return1_ArgvOnStack_BuiltinExit [node] 7: 0x100c083e4 Builtins_InterpreterEntryTrampoline [node] 8: 0x100c0650c Builtins_JSEntryTrampoline [node] 9: 0x100c061f4 Builtins_JSEntry [node] 10: 0x1004e16ac v8::internal::(anonymous namespace)::Invoke(v8::interna l::Isolate*, v8::internal::(anonymous namespace)::InvokeParams const&) [node] 11: 0x1004e1cc0 v8::internal::Execution::CallScript(v8::internal::Isola te*, v8::internal::Handle<v8::internal::JSFunction>, v8::internal::Hand le<v8::internal::Object>, v8::internal::Handle<v8::in ternal::Object>) [node] 12: 0x10039e100 v8::Script::Run(v8::Local<v8::Context>, v8::Local<v8::D ata>) [node] 13: 0x1001e4028 node::contextify::ContextifyScript::EvalMachine(v8::Loc al<v8::Context>, node::Environment*, long long, bool, bool, bool, v8::M icrotaskQueue*, v8::FunctionCallbackInfo<v8::Value> const&) [node ] 14: 0x1001e38a0 node::contextify::ContextifyScript::RunInContext(v8::Fu nctionCallbackInfo<v8::Value> const&) [node] 15: 0x100405fd4 v8::internal::MaybeHandle<v8::internal::Object> v8::int ernal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal:: Isolate*, v8::internal::Handle<v8::internal::HeapObject> , v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::interna l::Handle<v8::internal::Object>, unsigned long*, int) [node ] 16: 0x100405828 v8::internal::Builtin_HandleApiCall(int, unsigned long* , v8::internal::Isolate*) [node] 17: 0x100c90b24 Builtins_CEntry_Return1_ArgvOnStack_BuiltinExit [node] 18: 0x100c083e4 Builtins_InterpreterEntryTrampoline [node] 19: 0x100c083e4 Builtins_InterpreterEntryTrampoline [node] 20: 0x100c083e4 Builtins_InterpreterEntryTrampoline [node] 21: 0x100c083e4 Builtins_InterpreterEntryTrampoline [node] 22: 0x100c083e4 Builtins_InterpreterEntryTrampoline [node] 23: 0x100c083e4 Builtins_InterpreterEntryTrampoline [node] 24: 0x100c083e4 Builtins_InterpreterEntryTrampoline [node] 25: 0x100c0650c Builtins_JSEntryTrampoline [node] 26: 0x100c061f4 Builtins_JSEntry [node] 27: 0x1004e16ac v8::internal::(anonymous namespace)::Invoke(v8::interna l::Isolate*, v8::internal::(anonymous namespace)::InvokeParams const&) [node] 28: 0x1004e0f28 v8::internal::Execution::Call(v8::internal::Isolate*, v 8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::int ernal::Object>, int, v8::internal::Handle<v 8::internal::Object>*) [node] 29: 0x1003b239c v8::Function::Call(v8::Local<v8::Context>, v8::Local<v8 ::Value>, int, v8::Local<v8::Value>*) [node] 30: 0x1001d3bc4 node::builtins::BuiltinLoader::CompileAndCall(v8::Local <v8::Context>, char const*, node::Realm*) [node] 31: 0x100263434 node::Realm::ExecuteBootstrapper(char const*) [node] 32: 0x1001b7838 node::StartExecution(node::Environment*, std::__1::func tion<v8::MaybeLocal<v8::Value> (node::StartExecutionCallbackInfo const& )>) [node] 33: 0x100121c28 node::LoadEnvironment(node::Environment*, std::__1::fun ction<v8::MaybeLocal<v8::Value> (node::StartExecutionCallbackInfo const &)>) [node] 34: 0x100231354 node::NodeMainInstance::Run(node::ExitCode*, node::Envi ronment*) [node] 35: 0x100231130 node::NodeMainInstance::Run() [node] 36: 0x1001ba1d8 node::Start(int, char**) [node] 37: 0x19a027f28 start [/usr/lib/dyld] ----- JavaScript stack trace ----- 1: [eval]:1:23 2: runScriptInThisContext (node:internal/vm:144:10) 3: node:internal/process/execution:109:14 4: [eval]-wrapper:6:24 5: runScript (node:internal/process/execution:92:62) 6: evalScript (node:internal/process/execution:123:10) 7: node:internal/main/eval_string:51:3 [1] 24856 abort out/Release/node -p "process.binding('fs').open ()" ``` PR-URL: https://github.com/nodejs/node/pull/50242 Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
32 lines
1.1 KiB
JavaScript
32 lines
1.1 KiB
JavaScript
'use strict';
|
|
const common = require('../common');
|
|
const assert = require('assert');
|
|
const cp = require('child_process');
|
|
|
|
if (process.argv[2] === 'child') {
|
|
process.abort();
|
|
} else {
|
|
const child = cp.spawnSync(`${process.execPath}`, [`${__filename}`, 'child']);
|
|
const stderr = child.stderr.toString();
|
|
|
|
assert.strictEqual(child.stdout.toString(), '');
|
|
const { nativeStack, jsStack } = common.getPrintedStackTrace(stderr);
|
|
|
|
if (!nativeStack.every((frame, index) => frame.startsWith(`${index + 1}:`))) {
|
|
assert.fail(`Each frame should start with a frame number:\n${stderr}`);
|
|
}
|
|
|
|
// For systems that don't support backtraces, the native stack is
|
|
// going to be empty.
|
|
if (!common.isWindows && nativeStack.length > 0) {
|
|
const { getBinaryPath } = require('../common/shared-lib-util');
|
|
if (!nativeStack.some((frame) => frame.includes(`[${getBinaryPath()}]`))) {
|
|
assert.fail(`Some native stack frame include the binary name:\n${stderr}`);
|
|
}
|
|
}
|
|
|
|
if (jsStack.length > 0) {
|
|
assert(jsStack.some((frame) => frame.includes(__filename)));
|
|
}
|
|
}
|