【AI 使用案例】如何使用 AI 进行代码调试

背景说明

在编译器中端构图开发中,需要处理字节码之间的控制流关系。当遇到 fall through(顺序执行到下一个字节码)或跳转时,需要正确设置当前基本块(CurrentBlock)。

如果 CurrentBlock 未被正确设置,后续 fall through 进行 merge 的时候,会出现崩溃。(错误进行 BB 块的相连)


案例一:else 分支缺失导致变量未设置

案例背景

测试代码(switch 表达式)

typescript 复制代码
function switch_expr_test(x) {
    let result = 0;
    switch (true) {
        case x > 0 && x < 3:
            result += 100;
            break;
        case x >= 3 && x < 5:
            result += 200;
            break;
        default:
            result += 0;
            break;
    }
    return result;
}

崩溃信息

复制代码
ASSERTION FAILED: index < GetInputCount()
IN ../../arkcompiler/ets_runtime/ecmascript/arksteed/arksteed_vertex.h:736: SetInput

崩溃栈:
#14 BuildBody at arksteed_graph_builder.cpp:191
  -> mergeStates_[index]->Merge(*currentFrameState_, prevBlock);

含义:在设置 Vertex 输入时,index 超出了该 Vertex 的输入数量

问题代码

arksteed_graph_builder.cpp:167-177

cpp 复制代码
// ========== 第一部分:设置 CurrentBlock ==========
// already fall through and new block
if (blockForBytecode_[index] != nullptr &&
    !IsBlockFinished(blockForBytecode_[index])) {
    SetCurrentBlock(blockForBytecode_[index]);
} else if (index > 0) { // fall through, but not new block
    uint32_t predIndex = iterator_.PredIndex();
    if (blockForBytecode_[predIndex] != nullptr &&
        !IsBlockFinished(blockForBytecode_[predIndex])) {
        SetCurrentBlock(blockForBytecode_[predIndex]);
    }
    // ❌ 如果上面条件不满足,CurrentBlock() 仍然是 nullptr!
}

// ========== 第二部分:使用 CurrentBlock ==========
MergePointInterpreterFrameState* mergeState = mergeStates_[index];
if (mergeState != nullptr) {
    if (CurrentBlock() != nullptr) {
        // Previous bytecode was NOT finished (fallthrough), need to end the block first
        auto *prevBlock = FinishBlock<JumpVertex>({}, &jumpTargets_[index]);
        // Then merges interpreter states to the current
        mergeStates_[index]->Merge(*currentFrameState_, prevBlock);
        // ← 崩溃点:prevBlock 参数与 mergeStates_[index] 期望不匹配
    }
    StartNewBlock(nullptr, index);
} else {
    ASSERT(CurrentBlock() != nullptr);  // ← 潜在崩溃点
    blockForBytecode_[index] = CurrentBlock();
}

问题根因深度分析

问题 1:else 分支缺失
cpp 复制代码
} else if (index > 0) {
    uint32_t predIndex = iterator_.PredIndex();
    if (blockForBytecode_[predIndex] != nullptr &&
        !IsBlockFinished(blockForBytecode_[predIndex])) {
        SetCurrentBlock(blockForBytecode_[predIndex]);
    }
    // ❌ 缺失 else:当上述条件不满足时,CurrentBlock() 未被设置
}
场景 条件 结果
前驱块未创建 blockForBytecode_[predIndex] == nullptr CurrentBlock() 未设置
前驱块已完成 IsBlockFinished(blockForBytecode_[predIndex]) == true CurrentBlock() 未设置

CurrentBlock 设置错了,会导致错误判断了 fall-through 块,导致用例崩溃。

崩溃影响链路

复制代码
┌──────────────────────────────┐
│ 内层 if 条件不满足      │
│ (前驱块 nullptr 或已finished)│
└──────────────────────────────┘
              ↓
    SetCurrentBlock() 未被调用
              ↓
    CurrentBlock() == nullptr
              ↓
    ┌────────────────────────────────┐
    │     mergeState != nullptr?    │
    └────────────────────────────────┘
              ↓           ↓
         YES           NO
          ↓             ↓
    ┌─────────────┐   else {
    │ CurrentBlock()│   ASSERT(CurrentBlock()
    │ != nullptr?  │   != nullptr);
    │ 为 false      │   blockForBytecode_[index] = CurrentBlock();
    ↓             ↓           ↓
跳过 Merge      崩溃!       (潜在)
    →             ↓
StartNewBlock()   (路径 B)

路径 A(实际发生)

  • CurrentBlock() != nullptr(使用的是错误的 Block[0])
  • Merge 时参数不匹配 → 崩溃

路径 B(潜在)

  • mergeState == nullptr
  • ASSERT 失败 → 崩溃

AI 辅助调试过程

第一步:准备上下文信息

需要提供给 AI 的信息:

  1. 崩溃信息

    ASSERTION FAILED: index < GetInputCount()
    位置:arksteed_graph_builder.cpp:191
    函数:mergeStates_[index]->Merge(*currentFrameState_, prevBlock)

  2. 关键代码片段

cpp 复制代码
// 问题代码:else if 分支缺少 else 处理
} else if (index > 0) {
    uint32_t predIndex = iterator_.PredIndex();
    if (blockForBytecode_[predIndex] != nullptr &&
        !IsBlockFinished(blockForBytecode_[predIndex])) {
        SetCurrentBlock(blockForBytecode_[predIndex]);
    }
    // 缺少 else:当上述条件不满足时,CurrentBlock() 未被设置
}

// 后续依赖 CurrentBlock() 的代码
if (mergeState != nullptr) {
    if (CurrentBlock() != nullptr) {
        // 使用 CurrentBlock() 进行操作
    }
}
第二步:向 AI 提问

提问模板:

复制代码
我在调试一个崩溃代码

问题代码:
[粘贴代码]

修改的逻辑:
if (blockForBytecode_[index] != nullptr &&
    !IsBlockFinished(blockForBytecode_[index])) {
    SetCurrentBlock(blockForBytecode_[index]);
} else if (index > 0) { // fall through, but not new block
    uint32_t predIndex = iterator_.PredIndex();
    if (blockForBytecode_[predIndex] != nullptr &&
        !IsBlockFinished(blockForBytecode_[predIndex])) {
        SetCurrentBlock(blockForBytecode_[predIndex]);
    }
    // ❌ 如果上面条件不满足,CurrentBlock() 仍然是 nullptr!
}

请帮我分析:
1. 为什么会有崩溃?
2. 帮我重新编译,并且加入调试日志进行分析。
第三步:AI 可能的分析方向

AI 可能会给出以下分析:

逻辑完整性问题

  • if-else 链只处理了成功情况
  • 失败情况没有对应的处理
  • 变量在所有路径下未被正确设置
第四步:问题定位与修复

问题模式:

问题 现象 解决方案
缺失 else 分支 条件不满足时变量未设置 添加 else 分支处理所有未覆盖情况
变量未初始化 后续使用时崩溃/行为异常 在 else 中明确设置变量或创建新对象
逻辑不完整 只考虑了正常流程 添加异常处理和边界条件

修复建议:

cpp 复制代码
// 添加 else 分支
} else if (index > 0) {
    uint32_t predIndex = iterator_.PredIndex();
    if (blockForBytecode_[predIndex] != nullptr &&
        !IsBlockFinished(blockForBytecode_[predIndex])) {
        SetCurrentBlock(blockForBytecode_[predIndex]);
    } else {
        // ✅ 添加此分支:前驱块不可用时
        // 保持 nullptr 让后续代码创建新 block
        SetCurrentBlock(nullptr);
    }
}

效率对比

调试方式 传统调试 AI 辅助调试
理解问题 需要手动分析每个分支 AI 快速识别逻辑缺陷
分析原因 逐步排查代码路径 AI 指出缺失的分支
解决方案 自己考虑边界情况 AI 提供多种方案对比
验证思路 需要经验积累 AI 给出验证方法建议

时间节省估算:

  • 问题理解:从 2 小时 → 30 分钟
  • 原因分析:从 4 小时 → 1 小时
  • 方案验证:从 3 小时 → 1.5 小时

思考

AI 辅助调试,分5个步骤:

  1. 先给 AI 编译命令和调试命令
    • python ark.py x64.debug
    • ./debug_jit.sh test.ts
  2. AI 添加调试日志
  3. 找到问题,修改代码
  4. AI 帮忙检查修改的代码
  5. 删除调试日志
相关推荐
IT_陈寒1 天前
别再死记硬背Python语法了!这5个思维模式让你代码量减半
前端·人工智能·后端
Ray Liang1 天前
彻底治愈AI“失忆”和胡说八道的真正办法
人工智能·rag·智能体·ai助手·mindx
阿星AI工作室1 天前
飞书OpenClaw插件太香了!自动写文+整理表格+按评论修改保姆级教程
人工智能
生如夏呱1 天前
【教程】230 行代码实现一个极简的 OpenClaw
人工智能
yuhaiqiang1 天前
为什么我建议你不要只问一个AI?🤫偷偷学会“群发”,答案准到离谱!
人工智能·后端·ai编程
踩着两条虫1 天前
AI 智能体如何重构开发工作流
前端·人工智能·低代码
大模型真好玩1 天前
大模型训练全流程实战指南工具篇(八)——EasyDataset问答数据集生成流程
人工智能·langchain·deepseek
Johny_Zhao1 天前
OpenClaw中级到高级教程
linux·人工智能·信息安全·kubernetes·云计算·yum源·系统运维·openclaw
比尔盖茨的大脑1 天前
AI Agent 架构设计:从 ReAct 到 Multi-Agent 系统
前端·人工智能·全栈
后端小肥肠1 天前
OpenClaw 实战|多 Agent 打通小红书:数据收集 + 笔记编写 + 自动发布一步到位
人工智能·aigc·agent