Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

debugger not stepping through code step by step

Status
Not open for further replies.

AlastairP

Technical User
Feb 8, 2011
286
AU
I have just recently started getting an issue where the debugger does not step through the code line by line, but instead only stops where "SET STEP ON" occurs.
I set "SET STEP ON" at the point I want to check, then press F8 to step the code. However, the code runs without stopping/stepping at each line, just like what happens when the resume button was clicked.


Anyone seen this before?
 
I don't know what caused the issue, but is ok now.

Alastair
 
Ok an update:
I am still having the issue.
It seems to be occurring in timers, but I am having other issues as well

The another issue is with pemstatus anywhere on a form
In the console the command works as expected:

Code:
x = pemstatus(_screen,'oLoadingForm',5)
? x
x will show as .t.


But the following always triggers false

Code:
IF pemstatus(_screen,'oLoadingForm',5)
[indent]&& Do somthing[/indent]
ENDIF

My programs have pemstatus used extensively just like the second code example with no issues. But now it does not return a .t. value when clearly the value is .t.

I changed one instance to the following:

Code:
IF pemstatus(_screen,'oLoadingForm',5) = .t.
[indent]&& Do something[/indent]
ENDIF

And this time it registered the .t. and the code in the IF statement executed





 
I can't suggest anything regarding your PEMSTATUS() code. But you also mentioned timers. Using the debugger on code in Timer events nearly always causes problems. It's something I have always avoided.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Not sure if you're just lucky. I don't know enough about the whole situation, but doing some guesswork

oLoadingform - is that a form object existing while a form loads, removed from _screen afterwards? It could also be an object loading a form, but is it temporary only?

Are you checking pemstatus(_screen,'oLoadingForm',5) within a timer?

Well, then the timer events might occur before and after a form loaded, as simple as that. Loading of a form can be quite fast, also the timers aren't very precise and any code execution might queue timer events until after the code execution finishes and VFP becomes idle again, going into READ EVENTS mode and then timer events never fire during form load.

As said, there's very much guessing in this, but you might want to use BINDEVENTS here instead of a timer.

Without guessing, I can assure you it never is a problem to let the IF branch execute on a TRUE condition IF bExpression and it never needs IF bExpression=.T. to get there. Or shorter bExpression=.T. would never differ from bExpression itself, even if you would consider bExpression could be NULL. PEMSTATUS(...,5) can never be NULL, but even if it could, NULL=.T. is NULL just like NULL alone is. So bExpression=.T. always is the same as bExpression. Unless bExpression isn't logical/boolean, but then that would throw type errors every time.

To prove this in short just actually use a variable bExpression and set it to the three possible values .NULL., .T., and .F. and then check whether bExpression=.T. and bExpression itself can ever differ, or specifically whether bExpression = .T. can ever be .T. while bExpression itself is not .T., but .NULL. or .F. - you'll see it can't.

Code:
bExpression = .F.
? bExpression=.T., bExpression
bExpression = .T.
? bExpression=.T., bExpression
bExpression = .NULL.
? bExpression=.T., bExpression
This outputs three lines, each displaying the same boolean value twice.

Now the only remaining thing to know is what happens if an IF statements condition is NULL.
Code:
If .null.
   ? 'ifbranch'
Else
   ? 'elsebranch'
Endif
The answer is in case of a NULL value of the IF condition, the else branch becomes executed. This could be relevant if your overall IF condition involves more things that could also become .NULL. and would therefore explain that the if branch doesn't execute.


But in itself adding =.T. to an already evaluated expression with no further terms ANDded or ORed into the overall condition makes no difference whatsoever. So the only reason you had success with adding .T. is luck to catch one instance where the condition became .T., which you'd also have seen not adding =.T.

Well, and as a quintessence of it all - describe what you're doing more precisely to get better analysis and advice. But, really, you've made no difference from what I can see, the condition must be more complex and then it may become explainable.

Chriss
 
Breakpoints within timer events are hard o do, one thing I said recently is that you do yourself a favor with debugging timer events with breakpoints, if the first line of code of a timer is This.Enabled=.F.

Then never forget to set Enabled back to .T. at the end, including to do so when you Return anywhere in a branch of conditionally executed code. But when that is established this timer can't happen within the debugging of it. You also have to consider parallel timers, though. And therefore the debugger has a setting to ignore all timer events in the trace window. That means other timers happen and run without that code execution being shown in the debugging process in the trace window.

But if further timers influence what you're debugging, that can become impossible to debug, as the factor of you slowly stepping through code could differ from the actual runtime execution. So multiple timers are problematic to debug even with that precaution and using the debugger setting about timer events. Then it becomes more valuable to do coverage logging of what happens.

Chriss
 
I wonder what you did.

Have you put something like that into your base form class?

Code:
AddProperty(_screen,"oloadingform",THIS) && start of Load event
...
RemoveProperty(_screen,"oloadingform") && end of Init event.

And are you trying to catch all forms starting with a timer observing the existence of oloadingform?
Then it would be simpler to add to the base code of forms, wouldn't it?

What is really your goal, in plain English?

Chriss
 
I've had this happen before, usually when I'm debugging timer code.

The only reliable way I've found as a workaround is to set a breakpoint on every line you want to stop on. Then, when you single-step, it breaks at those lines.

Several years ago I had some code I couldn't debug for that very reason. Was driving me nuts. I finally just out of desperation set a breakpoint on every line to see what happened, and it worked. I've used it a few times since then.

--
Rick C. Hodgin
 
Chriss said:
Breakpoints within timer events are hard to do, one thing I said recently is that you do yourself a favor with debugging timer events with breakpoints, if the first line of code of a timer is This.Enabled=.F.

Another thing to do is create a property off _vfp that is a global timer activity state, which can be tested by every timer to see if all timers should be suspended.

It would be nice if VFP had a feature like SET TIMERS ON|OFF|SUSPENDED|AUTO so that you could debug them, and it could automatically enter the SUSPENDED state when you have a breakpoint in a timer if it were in AUTO mode, and when resuming it would go back to normal.

--
Rick C. Hodgin
 
One option when dealing with timer stuff is to lace your code with DEBUGOUT commands and, if necessary, turn on event tracking, so you can see what's happening without relying on breakpoints.

Tamar
 
Thanks
I have modified my code so the timer only calls the next event and the validation is done in the next event, not the timer.
This enables stepping through the code in the next event as per normal.

With thanks
Alastair
 
It seems you don't understood this option:
debugger_jnvqzr.jpg


If you have this off, the debugger will ignore displaying timer events in the trace window of the debugger. Furthermore, even if you set a breakpoint that's ignored. But you can in principle debug timers within the timer event, if you check this option. No need to use a workaround.

Chriss
 
My usual practice is to execute the following commands at the point where I want to begin debugging.

SET ASSERT ON
ASSERT .F.

Regards
Gary
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top