Enter debug mode if a variable changes value

조회 수: 36 (최근 30일)
Leo Simon
Leo Simon 2018년 3월 22일
편집: Jan 2021년 4월 22일
I'm trying to debug somebody else's impenetrable matlab code; at the beginning of each iteration of a loop, I'm displaying the value of a variable x. Somewhere inside this loop the value of the variable has changed, and I can't figure out where this has happened. So I'd like matlab to "watch" this variable for me and enter debug mode at the point where it changes value. There have been a couple of posts related to this issue. @WalterRoberson appears to have provided one answer and @BrettShoelson appears to have provided another. Brett suggests using the
timer
command, which seems like an appealing solution. But I'm afraid both answers are too terse for me to understand how to implement them. Would somebody be willing to provide an example, e.g., using timer, that would pause my program when the value of some element of a vector x has changed? Thanks!

채택된 답변

Jan
Jan 2018년 3월 24일
편집: Jan 2021년 4월 22일
I'm still convinced that the conditional breakpoints solve your problem. Set the breakpoints automatically:
function dbTest
x = 0;
bruteDBOnCondition(which(mfilename), 'x~=0');
for k = 1:1e6
q = rand;
if q < 0.01
x = rand;
end
end
disp(x)
end
And the function to set the breakpoints:
function bruteDBOnCondition(mFile, Condition)
[~, mName] = fileparts(mFile);
CStr = strsplit(fileread(mFile), '\n');
for k = 1:numel(CStr)
if ~isempty(CStr{k})
dbstop('in', mName, 'at', sprintf('%d', k), 'if', Condition)
end
end
end
You do not have to call bruteDBOnCondition() from inside the function to be supervised, but here it avoids to check the value of x before it is defined. Maybe this is smarter:
bruteDBOnCondition(which('dbTest'), 'exist(''x'', ''var'') && ~isequal(x, 0)');
You can do this for all subfunctions also.
You could reduce the number of breakpoints also, by selecting only lines, in which the symbol 'x' or 'x(' occurs left from a '=' character.
  댓글 수: 1
Leo Simon
Leo Simon 2018년 3월 26일
Ingenious. Worked spectacularly, I found the spot I was looking for, thanks very much. Everybody should have this tool!

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Jan
Jan 2018년 3월 22일
dbstop in myprogram at 4 if X>=3.1415
Or you can insert some code:
x = 0;
X0 = x; % <-- inserted
for k = 1:1e6
if rand < 0.01
x = rand;
if x ~= X0 % <-- inserted
disp('Changed'); % <-- inserted, set a breakpoint here
end % <-- inserted
end
end
  댓글 수: 4
Leo Simon
Leo Simon 2018년 3월 24일
>> Is the variable involved a global variable?
no
>> Is it a shared variable?
It's passed as an input and output variable between lots of child programs, grand-child and great-grand child programs, which it's why it's so hard to debug
>> Is it possible that something is using evalin('caller') or assignin('caller')?
no
>> Or is it a variable in the base workspace? If it is in the base workspace, then do you have a GUI involved?
no
Walter Roberson
Walter Roberson 2018년 3월 24일
As a first approximation:
At the point you want to start tracking changes, take a copy of the value and assign it to a variable in the base workspace. Then execute some utility code that finds all of the routines that use the variable on i/o and calls dbstop on the function name using a conditional of "if VariableName ~= evalin('base', 'ReferenceCopyofVariable')"
With breakpoints automatically created, proceed to execute.
This will not catch the change in value of the variable when it happens. What it would do is catch the first function call using the variable after it has been changed. You would then know that either the previous function call with the variable changed it or else that code between the two calls had changed it. It helps to narrow down the search a fair bit.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Entering Commands에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by