在独立的matlab中调试代码

时间:2011-02-16 14:20:29

标签: debugging matlab matlab-compiler

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

现在的问题是,在独立编译中assignin是不可能的,如果代码中有mccassignin会抱怨错误。我想做的是仅在代码以交互方式运行时包含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无法在独立模式下编译。

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

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

2 个答案:

答案 0 :(得分: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。

答案 1 :(得分:1)

使用功能isdeployed。 isdeployed在MCR中运行时为true,在MATLAB中运行时为false。

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