mcpField
M
matlab-debug-code

matlab-debug-code

github.com/matlab开发1.2k58 次安装1 天前更新
代码仓库

关于 matlab-debug-code

这是一项 MATLAB 调试技能,通过实时 MATLAB 会话调查错误、意外结果和变量状态。它结合源码检查、静态分析与运行时诊断,并根据 MATLAB 是否处于桌面模式调整断点流程。

主要功能

  1. 01实时 MATLAB 诊断与变量检查
  2. 02静态检查和源码调查
  3. 03适配桌面模式的断点流程
  4. 04错误、调用栈与数据形状分析
  5. 05工具箱可用性检查

适用场景

  1. 01追查 MATLAB 运行时错误的原因
  2. 02调查意外输出或 NaN 值
  3. 03检查故障代码路径中的变量
  4. 04确认未定义函数是否需要工具箱

MCP 相关

该技能通过 MATLAB MCP 工具使用实时 MATLAB 会话,执行代码、诊断、静态分析、测试和工具箱检测。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/matlab/matlab-agentic-toolkit --skill matlab-debug-code

安装后在 Claude Code 中输入/matlab-debug-code确认已加载。

附带文件manifest.yaml

详细介绍

使用 MCP 工具调查和调试 MATLAB 代码

你可以通过 MCP 工具访问实时 MATLAB 会话。使用这些工具主动调查代码,无论是调试错误、了解行为,还是解答 MATLAB 代码的工作原理。不要只根据代码猜测。

适用场景

  • 用户遇到 MATLAB 错误消息或意外结果
  • 用户想设置断点或检查变量状态
  • 跟踪函数产生错误输出的原因
  • 意外出现 NaN/Inf 值
  • MATLAB MCP 工具返回错误或异常,包括运行时错误、语法错误、未定义函数/变量错误或测试失败结果
  • 用户询问“为什么我的 MATLAB 代码无法运行”“帮我调试”,或分享 MATLAB 堆栈跟踪

不适用场景

  • 没有运行时问题的代码质量审查——改用 matlab-review-code
  • 性能分析——使用性能优化工作流
  • 编写正确性测试——改用 matlab-write-tests
  • 在没有具体 bug 的情况下了解 MATLAB API 或语言特性

静态分析与运行时调试

并非所有问题都需要实时 MATLAB 会话。选择合适的方法:

  • 静态分析足够时:语法错误、未使用的变量、明显的逻辑错误,或仅通过阅读源代码就能发现的问题。使用 Read 工具和 check_matlab_code。
  • 需要运行时调试时:
    • 错误取决于实际数据值、类型或维度
    • 输出错误,但代码看起来正确
    • 用户说“无法运行”,但代码看起来没问题——检查实际数据
    • 需要了解执行过程中特定位置的变量内容

拿不准时,先进行静态分析。如果仅凭源代码无法确定根本原因,再升级为运行时调试。

MATLAB 错误时自动触发

当 MATLAB MCP 工具返回错误时(运行时错误、语法错误、未定义函数/变量、维度不匹配、断言失败等),不要默默继续或猜测修复方法。而应:

  1. 识别错误——留意 MCP 工具输出中的 Error using ...、Undefined function or variable、Index exceeds ...、Error in ... 等模式、MATLAB 堆栈跟踪或测试失败结果。
  2. 征求用户许可——开始调查前,先询问:

    “我注意到出现了 MATLAB 错误:<brief error summary>。我可以使用 matlab-debug-code 技能深入调查——检查变量、跟踪调用栈并找出根本原因。要我调查吗?”

  3. 仅在用户确认后继续——用户同意后,按照以下调查工作流进行。

无论错误是用户运行代码时出现的,还是你代用户运行代码时出现的(例如验证修复或运行测试),都适用此规则。

可用工具

工具用途
mcp__matlab__run_matlab_file运行 .m 脚本——执行用户脚本和验证修复时优先使用
mcp__matlab__evaluate_matlab_code快速诊断:检查变量、计算表达式、测试小型代码片段
mcp__matlab__check_matlab_code对 .m 文件进行静态分析(警告、未使用变量、潜在问题)
mcp__matlab__run_matlab_test_file运行 MATLAB 测试文件
mcp__matlab__detect_matlab_toolboxes列出已安装的工具箱——当“未定义函数”可能是由缺少工具箱导致时使用

运行脚本时,优先使用 run_matlab_file,而不是 evaluate_matlab_code。 仅将 evaluate_matlab_code 用于简短的诊断命令(检查变量、测试表达式等),不要用它在行内重新运行整个脚本。

工作流

1. 了解目标

确定用户的需求:

  • 调试 — 运行时错误、输出不正确、行为异常
  • 理解 — 这段代码如何工作、这个函数的作用是什么
  • 调查 — 为什么这个变量的值是这样、这些数据来自哪里
  • 探索 — 有哪些函数可用、此代码库的结构如何
2. 通过 MATLAB 收集信息

使用 mcp__matlab__evaluate_matlab_code 运行诊断命令。

阅读源代码: 使用 Read 工具读取磁盘上的 .m 文件,而不是 MATLAB 的 type 或 dbtype。只有在尚未找到文件时才使用 MATLAB 的 which 定位文件,并使用 which -all 检查是否存在同名文件遮蔽。

预览大型数据: 使用 varName(1:min(5,end),:) 或 head(T) 预览 部分数据,而不是倾倒整个变量。

运行时调试 — 先检查桌面模式:

使用断点前,先检查 MATLAB 是否有桌面环境:

desktop('-inuse')  % true = desktop mode, false = no-desktop

桌面模式(desktop('-inuse') 返回 true):

使用完整的断点工作流:

  1. 运行前设置断点:
    dbstop if error          % Pause on any error
    dbstop if caught error   % Pause on error inside try-catch (silent failures)
    dbstop if warning        % Pause when a warning is issued
    dbstop if naninf         % Pause on NaN or Inf
    dbstop in file at line   % Pause at a specific line
    
  2. 通过 run_matlab_file 运行代码 — MATLAB 会在断点处暂停。
  3. 检查调用堆栈:
    dbstack                  % See full call stack with file names and line numbers
    
  4. 使用 whos 查看当前作用域中的内容 — 检查变量名称、大小和类型 后再查看具体值。对于大型数组/表格,预览部分数据 (varName(1:5,:)、head(T)),不要显示整个变量。
  5. 切换栈帧并检查各个作用域中的变量:
    dbup                     % Move up one frame (toward caller)
    dbdown                   % Move back down (toward callee)
    
    执行 dbup/dbdown 后,变量检查命令会在该栈帧的局部作用域中运行 — 可借此检查每一层的输入/输出。
  6. 继续运行或退出:
    dbcont                   % Continue execution to next breakpoint or end
    dbquit                   % Exit debug mode entirely
    dbclear all              % Remove all breakpoints when done
    

注意: 通过 MCP 进行交互式单步调试(dbstep)并不可靠 — 每次 evaluate_matlab_code 调用都是一条独立命令,因此单步状态可能无法保留。

无桌面模式(desktop('-inuse') 返回 false):

不要使用 dbstop if error、dbstop if naninf、dbstop if warning,也不要使用 任何会暂停执行的断点。 在无桌面模式下,暂停型断点 会导致 MCP eval 无限期挂起。

请改用以下策略:

  1. try-catch 包装器 — 包装可疑代码,以捕获错误并在失败后检查状态:

    try
        result = suspectFunction(data);
    catch ME
        fprintf('Error: %s\n', ME.message);
        fprintf('In: %s line %d\n', ME.stack(1).name, ME.stack(1).line);
        whos  % Show variables in scope at failure
    end
    
  2. Tracer 条件断点 — 使用带有始终返回 false 的条件的 dbstop,这样 MATLAB 就不会实际暂停,而是通过副作用打印值。定义一个 tracer 函数:

    function out = tracer(val)
        disp(val);
        out = false;
    end
    

    然后设置一个会调用它的条件断点:

    dbstop in myScript at 42 if tracer(myVar)
    

    第 42 行执行时,MATLAB 会计算 tracer(myVar),打印该值并返回 false — 执行会继续,不会暂停。 这样无需修改源文件,即可探查特定行上的变量。 完成后移除 tracer 断点:dbclear all

  3. 运行后检查 — 对于脚本,使用 run_matlab_file 运行,然后使用 evaluate_matlab_code 检查执行后的工作区变量。 同一会话中的 MCP 调用之间会保留基础工作区。

3. 迭代调查

这是调试的核心 — 请自行判断:

  • 阅读相关源代码,了解代码意图
  • 检查出现在故障行上或附近的变量
  • 计算子表达式,确定故障发生在哪一部分
  • 测试假设,在 MATLAB 中运行小段代码
  • 有选择地检查 — 不要倾倒整个工作区。只检查与问题相关的内容。 如果作用域中有 7 个变量,但故障行只用到其中 2 个,就检查这 2 个。

如果错误发生在 MathWorks 内置函数中,问题几乎总是出在 调用该函数的用户代码中。沿调用堆栈向上查找用户代码。

4. 质疑诊断结果

用户对问题的描述可能与实际问题不符。在修复他们所说的故障之前,请先自行验证:

  • 直接测试声称的故障 — 如果用户说 ismember 或 strcmp 无法正常工作,请用他们的实际数据自行运行。通常操作本身没有问题,真正的问题在于相关逻辑。
  • 先检查数据,再归咎于代码 — 如果对数据执行的操作“无法正常工作”, 请检查数据:类型(class)、实际值(抽取几个样本)、空白字符(strtrim)、隐藏字符(double(str))和维度(size)。
  • 核实代码的实际行为与用户描述是否一致 — 阅读代码, 确认实际使用了哪些变量和列。用户描述的可能是他们的意图,但代码的实际行为可能有所不同。
  • 考虑方法本身是否有误 — 有时代码本身并没有 bug,但采用的方法不必要地复杂或脆弱。建议使用符合 MATLAB 惯例的替代方案:用表连接代替手动循环,用向量化运算代替逐元素比较,用内置函数代替手写逻辑。

常见错误 — 优先检查事项

错误模式诊断步骤
Undefined function or variable 'X'which X、exist('X','file')、exist('X','var'),检查 path,使用 detect_matlab_toolboxes 确认工具箱已安装
Index exceeds array dimensions / Index exceeds the number of array elements执行 size(arr) 并检查索引表达式 — 通常是索引偏移一位或数组为空
Not enough input arguments检查调用位置的函数调用方式、函数内部的 nargin,并与函数签名进行比较
Too many input arguments同上 — 调用方传入了多余参数,或将脚本当作函数调用
Matrix dimensions must agree / Dimension mismatch对两个操作数分别执行 size(A)、size(B) — 通常一个是行向量,另一个是列向量
Subscript indices must either be real positive integers or logicals检查索引变量:class(idx)、min(idx),查找 0 或负值、NaN,或浮点索引
Dot indexing is not supported for variables of this type执行 class(var) — 通常是在非结构体(元胞、数组、表)上访问结构体字段
Unable to perform assignment检查赋值两侧的 class 和 size
Out of memory使用 whos 查找大型变量,检查循环中是否意外扩展数组
Maximum recursion limit检查是否缺少基例或存在无限相互递归 — 在错误点执行 dbstack
NaN 传播 / 执行了错误分支在桌面模式下,使用 dbstop if naninf 捕获 NaN 首次产生的位置。在无桌面模式下,使用 dbstop in file at line if tracer(suspect) 探查值而不暂停。NaN 比较(>、<、==)始终为 false,因此 if 会悄无声息地执行错误分支。追溯上游:检查是否存在 0/0、Inf-Inf,或输入数据中的 NaN。使用 any(isnan(var)) 进行检查。

注意事项

  • 暂停型断点在无桌面模式下会卡住。 当 desktop('-inuse') 返回 false 时,dbstop if error、dbstop if naninf、dbstop if warning 和无条件行断点会导致 MCP eval 无限期卡住。请务必先检查桌面模式。在无桌面模式下,请改用 tracer 条件断点或 try-catch 包装器(参见上文的无桌面策略)。
  • 通过 MCP 使用 dbstep 不可靠。 每次 evaluate_matlab_code 调用都是独立命令,因此步进状态可能无法在调用之间保留。请使用断点(dbstop in file at line)在特定位置暂停,而不要尝试逐步执行代码。要跟踪执行流程,可插入临时的 fprintf() 语句或使用 try-catch 块。
  • 不要使用 type 或 dbtype 阅读源代码。 请改用 Read 工具——速度更快,也不会占用 MATLAB 会话输出带宽。只有在尚未找到文件时,才使用 which 定位文件。
  • 调试完成后务必运行 dbclear all。 之前会话遗留的断点会导致后续运行意外暂停。
  • dbup/dbdown 的作用域仅限单次调用。 每次 evaluate_matlab_code 调用都会重置到当前栈帧。请在同一次 evaluate_matlab_code 调用中,将 dbup 与变量检查串联起来:
    dbup; whos; myVar(1:min(5,end),:)
    
    在 dbup 之后单独调用 evaluate_matlab_code,将返回原始栈帧。
  • 切勿运行 restoredefaultpath。 它会从 MATLAB 路径中移除 MCP 服务自身的包,导致 eval 通道失效(找不到 mcpEval)。如果发生这种情况,唯一的恢复方法是完全重启 MATLAB。
  • 无需工具箱。 此技能仅使用 MATLAB 基本调试命令。

核心原则

  • 使用工具——你可以使用正在运行的 MATLAB 会话。运行命令、检查状态、验证假设。不要只靠阅读代码来调试。
  • 有所取舍——只请求相关内容。不要转储所有变量,也不要读取调用栈中的每个文件。
  • 获取数据前先检查大小——显示变量前,务必先了解其维度。切勿盲目对未知变量运行 disp。
  • 聚焦用户代码——在内置函数中出现的错误几乎总是由用户代码传入了错误输入所致。
  • 先阅读再修复——提出修改建议前,务必阅读实际源代码。不要猜测代码内容。
  • 验证修复——条件允许时,在 MATLAB 中运行修正后的代码以确认结果。

Copyright 2026 The MathWorks, Inc.


评论

支持 Markdown