开发者

debug code in standalone matlab

Say I have some function foo that is used in a standalone application, (ie. compiled into an executable with mcc -m,) which has an important intermediate result bar. Normally I don't need this intermediate result after completion of the function and thus it is not a return value. However for development and debugging purposes it is useful to be able to make this intermediate result accessible, which I may do by using assignin to put the intermediate result in some debug workspace.

Now the problem is that the assignin isn't possible in a standalone compilation and mcc will complain with an error if there is an assignin in the code. What I'd like to do is include the assignin only when the code is run interactively and not when being compiled as a standalone application. Additionally, this would speed things up as I would not need the intermediate result anyway in the standalone application and thus can same time and/or memory by not doing the assignin in the standalone application. In any other programming environm开发者_开发技巧ent one would call this compiling in debug and release mode.

In pseudo-matlab:

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

The problem is that I know of no way of expressing the if ~standalone, firstly I don't know how to test for being in standalone mode or not, but more crucially, this needs to be some code construct that actually causes mcc to completely disregard the guarded code block and not try to compile it, because the assignin can not be compiled in standalone mode.

As an aside, this would not just be valuable for intermediate results, but also for extra data gathering, where extra data would be calculated in the guarded block and exported by way of an assignin. Obviously such extra data should not be calculated in the standalone version as it would not serve any purpose.

Is there any such code construct in matlab that would allow for this to be done, or is there a better alternative? Up to now I've just been juggling commented code, uncommenting and recommenting the debug code as I went along in the development process.


Instead of using assignin to populate a debug workspace, you could use a global debugging struct and stash the variables in fields of the same name. All valid variable names are also valid struct field names. You could implement this with a global variable, but would probably be better done with a persistent variable inside a function. This will work in compiled or non-compiled code.

First, have a function that defines your debugging mode.

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

Then a function for stashing the debugging values, that only holds on to values when debug mode is on.

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

The debugging is disabled by default so it will short-circuit in the compiled version and not accumulate values. Enable it manually in your interactive Matlab session with isdebugging(true). This bypasses the issue of detecting whether you're running deployed. It also means you can enable and use it in your compiled app, if you want to test the compiled code to see how it's working in that context. You can use a GUI button or environment variable to tell the compiled app to enable debugging.

The isdebugging() call can guard other code. But I wouldn't get too carried away with using isdebugging() to guard anything besides log output or value accumulation. You don't want your debugging mechanism to have side effects on the correctness of your code.

Also have a look at Java's log4j as a model of how to incorporate run-time configurable debugging output in an application. You could apply its principles to Matlab.


Use the function isdeployed. isdeployed is true when run in the MCR, and false when run in MATLAB.

EDIT: Of course, this doesn't solve the problem of compiling. You might have to find a substitute for assignin..

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜