首页 文章

在独立的matlab中调试代码

提问于
浏览
3

假设我有一个在独立应用程序中使用的函数 foo (即编译成带有 mcc -m 的可执行文件),它具有重要的中间结果 bar . 通常我在完成函数后不需要这个中间结果,因此它不是返回值 . 但是,出于开发和调试的目的,能够使这个中间结果可访问是很有用的,我可以通过使用 assignin 将中间结果放入某个调试工作区来完成 .

现在的问题是 assignin 在独立编译中是不可能的,如果代码中有 assigninmcc 将会报错 . 我想要做的只是当代码以交互方式运行而不是在编译为独立应用程序时才包含 assignin . 另外,这会加速,因为我不需要在独立应用程序中的中间结果,因此可以通过不在独立应用程序中执行assignin来获得相同的时间和/或内存 . 在任何其他编程环境中,可以在调试和释放模式下调用此编译 .

在伪matlab中:

function res = foo()
  bar = some complicated formula
  if ~standalone
    assignin('debug', 'foo_bar', bar)
  end
  res = some complicated formula involving bar

问题是我知道无法表达 if ~standalone ,首先我不知道如何测试是否处于独立模式,但更重要的是,这需要一些代码构造实际上导致mcc完全忽略保护代码块而不是尝试编译它,因为assignin无法在独立模式下编译 .

顺便说一句,这不仅对中间结果有 Value ,而且对于额外的数据收集也是有 Value 的,其中额外的数据将在受保护的块中计算并通过 assignin 导出 . 显然,这些额外的数据不应该在独立版本中计算,因为它不会用于任何目的 .

在matlab中是否有任何这样的代码构造可以实现这一点,还是有更好的选择?到目前为止,我一直在处理评论代码,取消注释并重新调试调试代码,就像我在开发过程中一样 .

2 回答

  • 1

    使用函数isdeployed . 在MCR中运行时isdeployed为true,在MATLAB中运行时为false .

    编辑:当然,这并没有解决编译问题 . 您可能必须找到assignin的替代品..

  • 2

    您可以使用全局调试结构并将变量存储在同名字段中,而不是使用assignin来填充调试工作区 . 所有有效的变量名称也是有效的struct字段名称 . 您可以使用全局变量实现此功能,但在函数内使用持久变量可能会更好 . 这将在编译或非编译代码中工作 .

    首先,有一个定义调试模式的函数 .

    function out = isdebugging(value)
    %ISDEBUGGING Get or set the global debugging state
    
    persistent state
    if isempty(state)
        state = false;
    end
    
    switch nargin
        case 0 % Getter
            out = state;
        case 1 % Setter
            state = value;
    end
    

    然后是一个用于存储调试值的函数,该函数仅在启用调试模式时保留值 .

    function out = debugval(action, name, value)
    %DEBUGVAL Stash values for debugging
    
    persistent stash
    if isempty(stash)
        stash = struct;
    end
    
    % Short-circuit when not in debugging mode to save space
    if ~isdebugging()
        return;
    end
    
    switch action
        case 'get'
            out = stash.(name);
        case 'getall'
            out = stash;
        case 'set'
            stash.(name) = value;
        case 'list'
            out = fieldnames(stash);
        case 'remove'
            stash = rmfield(stash, name);
        case 'clear'
            stash = struct;
    end
    

    默认情况下禁用调试,因此它将在编译版本中短路而不会累积值 . 使用isdebugging(true)在交互式Matlab会话中手动启用它 . 这绕过了检测您是否正在部署的问题 . 它还意味着您可以在已编译的应用程序中启用和使用它,如果您想测试已编译的代码以查看它在该上下文中的工作方式 . 您可以使用GUI按钮或环境变量来告知已编译的应用程序以启用调试 .

    isdebugging()调用可以保护其他代码 . 但是,除了日志输出或值累积之外,使用isdebugging()来保护任何东西都不会让我感到沮丧 . 您不希望调试机制对代码的正确性产生副作用 .

    另请参阅Java的log4j,作为如何在应用程序中合并运行时可配置调试输出的模型 . 您可以将其原则应用于Matlab .

相关问题