我如何逐行调试 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 来源。不幸的是,这是不可能的,因为内置函数和它们的生成器 运行 在不同的时间(甚至在不同的二进制文件中!)。