我如何逐行调试 v8 中的 CodeStubAssembler(CSA) 代码
How can i debug the CodeStubAssembler(CSA) code in v8 line by line
我从 那里看到了对我的问题的很好的回答。然而,我真的无法理解结果 one.Can 中的“然后你可以逐步执行 CSA 代码,因为它会发出 Turbofan IR 图,然后 Turbofan 后端将其转换为机器代码”这一点 one.Can 我逐行调试 CSA 根据源代码怎么样?
为了更清楚地表达我的需求,我使用了一些代码示例:
2864 TNode<Smi> CodeStubAssembler::BuildAppendJSArray(ElementsKind kind,
2865 TNode<JSArray> array,
2866 CodeStubArguments* args,
2867 TVariable<IntPtrT>* arg_index,
2868 Label* bailout) {
2869 Comment("BuildAppendJSArray: ", ElementsKindToString(kind));
2870 Label pre_bailout(this);
2871 Label success(this);
2872 TVARIABLE(Smi, var_tagged_length);
以上是CSA中的代码,可以在gdb中输入'n'然后从2869行单步到2870行吗?
澄清一下,我可以得到以下用于调试 CSA 代码的格式吗?
[───────────────────────────────────────────────────────────────────────────────────────DISASM───────────────────────────────────────────────────────────────────────────────────────]
0x7f9fc9bcaca5 mov rax, qword ptr [rbp - 0x60]
0x7f9fc9bcaca9 mov rcx, qword ptr fs:[0x28]
0x7f9fc9bcacb2 mov rdx, qword ptr [rbp - 8]
0x7f9fc9bcacb6 cmp rcx, rdx
0x7f9fc9bcacb9 mov qword ptr [rbp - 0xb0], rax
► 0x7f9fc9bcacc0 jne 0x7f9fc9bcacd6
0x7f9fc9bcacc6 mov rax, qword ptr [rbp - 0xb0]
0x7f9fc9bcaccd add rsp, 0xb0
0x7f9fc9bcacd4 pop rbp
0x7f9fc9bcacd5 ret
0x7f9fc9bcacd6 call __stack_chk_fail@plt <0x7f9fcb191dc0>
[───────────────────────────────────────────────────────────────────────────────────────SOURCE───────────────────────────────────────────────────────────────────────────────────────]
457 // static
458 MaybeHandle<Object> Execution::Call(Isolate* isolate, Handle<Object> callable,
459 Handle<Object> receiver, int argc,
460 Handle<Object> argv[]) {
461 return Invoke(isolate, InvokeParams::SetUpForCall(isolate, callable, receiver,
462 argc, argv));
463 }
464
465 MaybeHandle<Object> Execution::CallBuiltin(Isolate* isolate,
466 Handle<JSFunction> builtin,
[───────────────────────────────────────────────────────────────────────────────────────STACK
是的,您可以这样做,就像任何其他 C++ 代码一样。
当然,此代码 运行s 作为 mksnapshot
的一部分,它的作用是创建(部分)“内置”代码对象,该对象可以处理向 JavaScript 数组。 2869行会在代码对象的注释部分加入注释(如果你是运行的--code-comments
标志),2870行会定义一个标签,后面会用到条件跳转
所以要明确一点,当您实际将元素附加到数组时,这段代码 而不是 运行。届时,此代码生成的内置函数将 运行,调试需要不同的技术(参见其他答案)。
编辑以解决评论中的问题:
If i enter p kind
in line 2870,can i get the value of kind
? if i enter p ElementsKindToString
in this function,can i get the address of function ElementsKindToString
?
是的,当然,这是纯 C++。 (还有,你为什么这么问?试试吧!)
how could i break in gdb before the Turbofan backend translate this function to machine code and get the debugging format i posted above.
运行 mksnapshot
在 GDB 中并在您想要的行上设置断点,然后根据需要切换视图模式。 (同样,这是 GDB 的常规用法;如果您需要 GDB 教程,请搜索一个,网上有很多。)
虽然您没有直接要求,但我怀疑您真正想做的是逐条执行 generated 内置指令并查看负责生成它们的 CSA 来源。不幸的是,这是不可能的,因为内置函数和它们的生成器 运行 在不同的时间(甚至在不同的二进制文件中!)。
我从
2864 TNode<Smi> CodeStubAssembler::BuildAppendJSArray(ElementsKind kind,
2865 TNode<JSArray> array,
2866 CodeStubArguments* args,
2867 TVariable<IntPtrT>* arg_index,
2868 Label* bailout) {
2869 Comment("BuildAppendJSArray: ", ElementsKindToString(kind));
2870 Label pre_bailout(this);
2871 Label success(this);
2872 TVARIABLE(Smi, var_tagged_length);
以上是CSA中的代码,可以在gdb中输入'n'然后从2869行单步到2870行吗?
澄清一下,我可以得到以下用于调试 CSA 代码的格式吗?
[───────────────────────────────────────────────────────────────────────────────────────DISASM───────────────────────────────────────────────────────────────────────────────────────]
0x7f9fc9bcaca5 mov rax, qword ptr [rbp - 0x60]
0x7f9fc9bcaca9 mov rcx, qword ptr fs:[0x28]
0x7f9fc9bcacb2 mov rdx, qword ptr [rbp - 8]
0x7f9fc9bcacb6 cmp rcx, rdx
0x7f9fc9bcacb9 mov qword ptr [rbp - 0xb0], rax
► 0x7f9fc9bcacc0 jne 0x7f9fc9bcacd6
0x7f9fc9bcacc6 mov rax, qword ptr [rbp - 0xb0]
0x7f9fc9bcaccd add rsp, 0xb0
0x7f9fc9bcacd4 pop rbp
0x7f9fc9bcacd5 ret
0x7f9fc9bcacd6 call __stack_chk_fail@plt <0x7f9fcb191dc0>
[───────────────────────────────────────────────────────────────────────────────────────SOURCE───────────────────────────────────────────────────────────────────────────────────────]
457 // static
458 MaybeHandle<Object> Execution::Call(Isolate* isolate, Handle<Object> callable,
459 Handle<Object> receiver, int argc,
460 Handle<Object> argv[]) {
461 return Invoke(isolate, InvokeParams::SetUpForCall(isolate, callable, receiver,
462 argc, argv));
463 }
464
465 MaybeHandle<Object> Execution::CallBuiltin(Isolate* isolate,
466 Handle<JSFunction> builtin,
[───────────────────────────────────────────────────────────────────────────────────────STACK
是的,您可以这样做,就像任何其他 C++ 代码一样。
当然,此代码 运行s 作为 mksnapshot
的一部分,它的作用是创建(部分)“内置”代码对象,该对象可以处理向 JavaScript 数组。 2869行会在代码对象的注释部分加入注释(如果你是运行的--code-comments
标志),2870行会定义一个标签,后面会用到条件跳转
所以要明确一点,当您实际将元素附加到数组时,这段代码 而不是 运行。届时,此代码生成的内置函数将 运行,调试需要不同的技术(参见其他答案)。
编辑以解决评论中的问题:
If i enter
p kind
in line 2870,can i get the value ofkind
? if i enterp ElementsKindToString
in this function,can i get the address of functionElementsKindToString
?
是的,当然,这是纯 C++。 (还有,你为什么这么问?试试吧!)
how could i break in gdb before the Turbofan backend translate this function to machine code and get the debugging format i posted above.
运行 mksnapshot
在 GDB 中并在您想要的行上设置断点,然后根据需要切换视图模式。 (同样,这是 GDB 的常规用法;如果您需要 GDB 教程,请搜索一个,网上有很多。)
虽然您没有直接要求,但我怀疑您真正想做的是逐条执行 generated 内置指令并查看负责生成它们的 CSA 来源。不幸的是,这是不可能的,因为内置函数和它们的生成器 运行 在不同的时间(甚至在不同的二进制文件中!)。