nodejs / nodejs/node

Low cost stacktrace walking

未关闭
#64,337 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

feature request v8 module
主要语言
JavaScript
星标
122k
派生
37.3k
平均合并
4 天 2 小时
30 天内合并 PR
283

描述

What is the problem this feature will solve?

Public APIs that allow for stack collection/walking are quite heavy, doing memory allocation and symbol resolution in the background.
All the necessary features are already available - but exported as local symbols, making theme very hard to use even from native code.

What is the feature you are proposing to solve the problem?

Below is example code, that used to work fine in node 20 and 22, but will not work on 24+ because the necessary symbols are not global anymore (so in a way it is regression) . I do not mind that the private API are not stable and require recompilation specific for v8. I do not need new public API - it would be nice of course, but I can easily maintain multiple version of my code. Having symbols local though, makes the project extremely complex:

struct FrameId {
    uint32_t script_id;
    uint32_t start_position;
    uint32_t end_position;
    uint32_t filler;
    v8::internal::Tagged<v8::internal::SharedFunctionInfo> sfi;
};

size_t get_stack_frame_ids(v8::Isolate* isolate, FrameId* buffer, size_t max_len) {
    v8::internal::JavaScriptStackFrameIterator it(reinterpret_cast<v8::internal::Isolate*>(isolate));
    size_t count = 0;
    while (!it.done() && count < max_len) {
        v8::internal::JavaScriptFrame* frame = it.frame();
        v8::internal::Tagged<v8::internal::JSFunction> function = frame->function();
        v8::internal::Tagged<v8::internal::SharedFunctionInfo> sfi = function->shared();
        v8::internal::Tagged<v8::internal::Script> script = v8::internal::Cast<v8::internal::Script>(sfi->script());

        buffer[count].script_id = script->id();
        buffer[count].start_position = sfi->StartPosition();
        buffer[count].end_position = sfi->EndPosition();
        buffer[count].sfi = sfi;

        count++;
        it.Advance();
    }
    return count;
}

size_t describe_frame(v8::Isolate* isolate, FrameId* frame_id, char* buffer, size_t buffer_size) {
    // Fetch function name and script name
    std::unique_ptr<char[]> name = frame_id->sfi->DebugNameCStr();
    size_t offset = 0;
    size_t i=0;
    while(offset < buffer_size - 3 && name[i] != '\0') {
        buffer[offset++] = name[i++];
    }
    buffer[offset++] = '(';
    v8::internal::Tagged<v8::internal::Script> script = v8::internal::Cast<v8::internal::Script>(frame_id->sfi->script());
    v8::internal::Tagged<v8::internal::Object> raw_name = script->GetNameOrSourceURL();
    if (IsString(raw_name)) {
        name = v8::internal::Cast<v8::internal::String>(raw_name)->ToCString();
        i=0;
        while(offset < buffer_size - 2 && name[i] != '\0') {
            buffer[offset++] = name[i++];
        }
    } else {
        if(offset < buffer_size - 11) {
            memcpy(buffer+offset, "<unknown>", 9);
            offset += 9;
        }
    }
    buffer[offset++] = ':';

    // Format the final description into the buffer
    offset += snprintf(buffer+offset, buffer_size - offset, "%d:%d)", frame_id->start_position, frame_id->end_position);

    // If buffer was too small, null-terminate it safely
    if (offset >= buffer_size) {
        buffer[buffer_size - 1] = '\0'; // Null-terminate the buffer
        offset = buffer_size - 1; // Set offset to the last position
    }

    return offset;
}
What alternatives have you considered?

There do not seem to be alternative for "allocation free" stack walking.

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

首先跟踪示例中显示的 V8 内部入口点,尤其是 JavaScriptStackFrameIterator、JavaScriptFrame 和 SharedFunctionInfo,并比较它们在 Node 22 与 Node 24 之间的符号可见性。然后确定控制这些符号的构建或导出配置。当无需新的公共 API 仍可使用无分配的原生堆栈遍历时,即表示完成。

由索引模型根据 Issue 内容生成。

评估

技术栈
cpp, nodejs
领域
backend
Issue 类型
功能
难度
5/5
预计耗时
一周以上
活跃度
冷清
描述清晰度
基本清楚
新手友好度
38/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。