Why do conditional breakpoints slow my program down so much? - delphi

When I'm debugging something that goes wrong inside a loop, say on the 600th iteration, it can be a pain to have to break for every one. So I tried setting a conditional breakpoint, to only break if I = 600. That works, but now it takes almost a full minute to reach that point, where before it was almost instantaneous. What's going on, and is there any way to fix it?

When you hit a breakpoint, Windows stops the process and notifies the debugger. It has to switch contexts, evaluate the condition, decide that no, you don't want to be notified about it, restart the process and switch back. That can take a lot of processor cycles. If you're doing it in a tight loop, it'll take a couple orders of magnitude more processor cycles than one iteration of the loop takes.
If you're willing to mess with your code a little, there's a way to do conditional breakpoints without incurring all this overhead.
if <condition here> then
asm int 3 end;
This is a simple assembly instruction that manually sends a breakpoint notification to the OS. Now you can evaluate your condition inside the program, without switching contexts. Just make sure to take it out again when you're done with it. If an int 3 goes off inside a program that's not connected to a debugger, it'll raise an exception.

It slows it down because every time you reach that point, it has to check your condition.
What I tend to do is to temporarily create another variable like this (in C but should be doable in Delphi).
int xyzzynum = 600;
while (true) {
doSomething();
if (--xyzzynum == 0)
xyzzynum = xyzzynum;
}
then I put a non-conditional breakpoint on the "xyzzynum = xyzzynum;" line.
The program runs at full speed until it's been through the loop 600 times, because the debugger is just doing a normal breakpoint interrupt rather than checking conditions every time.
You can make the condition as complicated as you want.

Further to Mason's answer, you could make the int 3 assember only be compiled in if the program is built with the debug conditional defined:
{$ifdef debug}
{$message warn 'debug breakpoint present in code'}
if <condition here> then
asm int 3 end;
{$endif}
So, when you are debugging in the ide, you have the debug conditional in the project options. When you build the final product for your customers (with your build script?), you wouldn't include that symbol, so it wont get compiled in.
I also included the $message compiler directive, so you will see a warning when you compile letting you know that the code is still there. If you do that everywhere you use int 3, you will then have a nice list of places which you can double click on to take you straight to the offending code.
N#

Mason's explanations are quite good.
His code could be made a bit more secure by testing that you run under the debugger:
if (DebugHook <> 0) and <your specific condition here> then
asm int 3 end;
This will not do anything when the application is running normally and will stop if it's running under the debugger (whether launched from the IDE or attached to the debugger).
And with boolean shortcut <your specific condition here> won't even be evaluated if you're not under the debugger.

Conditional breakpoints in any debugger (I'm just surmising here) require the process to flip back and forth every time between your program and the debugger every time the breakpoint is hit. This process is time consuming but I do not think there is anything you can do.

Normally condition breakpoints work by inserting the appropriate break instruction into the code and then checking for the conditions you have specified. It'll check at every iteration and it might well be that the way in which the check is implemented is responsible for the delay as it's unlikely that the debugger compiles and inserts the complete check and breakpoint code into the existing code.
A way that you might be able to accelerate this is if you put the condition followed by an op with no side effect into the code directly and break on that op. Just remember to remove the condition and the op when you're done.

Related

Is there any purpose for an empty Try/Finally block?

I have inherited a large code base that is full of constructs like this:
try
DoWhatever;
finally
end;
Sometimes "DoWhatever" involves some fiddling with controls, and very often it's a post to a database, and there are many cases in the code where there IS something in the finally block.
But my understanding is, if there's nothing in the finally block, then the whole try...finally thing is pointless. The code is pretty noisy overall so I'm assuming it was just a placeholder for future code or a holdover from previous code. (There are many placeholders in the code.)
Is my understanding correct or is there some secret double-bluff reverso in Delphi try...finally blocks I've overlooked? (This is Delphi 2010.)
There is no functional purpose to it — it has no effect on the run-time behavior of the program. When control leaves the try section, the program will jump to the finally section, do nothing, and then continue to whatever the next instruction should be (according to how control reached the finally statement), the same as if the try-finally block hadn't been there at all. The only difference will be that the program spends an extra moment before and after the try-finally block as it sets up and clears the control structure form the stack.
It might be that the author had a template that included a try-finally block, but that some instances of that template ended up not needing any cleanup code. Having the code fit a consistent pattern might have made certain automated tasks easier.
The try-finally block might also provide a convenient place to put a breakpoint that triggers after the protected code runs, even in the event of an exception or other premature termination.
To find out why the code has such apparently useless constructs, ask the previous author, or check the commit history.

iOS: LLDB multiline breakpoint commands don't work as expected

I'm trying to do something a little fancy here, but the docs suggest it should be possible. Maybe LLDB is still too new, but I'm getting a lot of debugger crashes / deadlocks and even when that doesn't happen it does't seem to work like I expected.
I'm trying to put together a debug wrapper around all selector calls, to extract the message call graph inside a certain chunk of code. (I could explain why if you really want to know, but it isn't really relevant to the debugger issue.)
I start out with an Xcode breakpoint on the line where I want to start tracking things (for bonus points, this is happening on a secondary thread, but before you ask, no, nothing on any other thread is doing any accesses to this object or anything in its property subgraph):
[myObject startProcessing];
The breakpoint triggers, and I run "bt", just to extract:
* thread #5: tid = 0x2203, 0x000277d2 .........
I then do something mildly evil: I put a breakpoint in objc_msgSend, right at the instruction where it calls out to the real object selector. objc_msgSend looks like:
libobjc.A.dylib`objc_msgSend:
...(instructions)...
0x37babfa4: bx r12
...(more instructions)...
(Actually there are two bx calls but let's keep things simple.) I run:
breakpoint set -a 0x37babfa4 -t 0x2203
(TID included because I'm having enough trouble tracking this one thread and I don't need irrelevant stuff interfering.)
Here's where the scripting comes in. The setup described above works exactly as I'd like it to. If I resume execution until the breakpoint triggers, I can run:
frame select 0
thread step-inst -m this-thread 5
frame info
continue
and the effect will be that the debugger:
moves to the objc_msgSend frame
steps by one instruction, advancing it into the object selector frame it was pointing at
displays relevant details (object type, selector called)
resumes execution
at which point I can keep pasting in those four commands over and over and copying the output until I hate myself.
If, on the other hand, I run:
breakpoint command add -s command
and paste in those exact same commands, everything breaks. It does not advance to the object selector frame. It doesn't show the frame details, or at least not the correct ones -- depending on various tweaks (see below), it may or may not show "objc_msgSend" as being the current function. It doesn't resume execution.
In this case, if I could get that example working, I'd be mostly happy. But for even more bonus points, I've also tried this with python, which I would prefer because it would allow for much more sophisticated logging:
breakpoint command add -s python
> thread = frame.GetThread()
> thread.StepInstruction(1)
> newFrame = thread.GetFrameAtIndex(0)
> print " " * thread.GetNumFrames() + newFrame.GetFunctionName()
> process = thread.GetProcess()
> process.Continue()
> DONE
Again no good. Again depending on tiny details, this may or may not print something (usually objc_msgSend), but it never prints the correct thing. It never steps the instruction forward. It never resumes execution afterwards.
And again, the python version works fine if I do it by hand: if I wait till the breakpoint fires, then run "script" and enter those exact same lines, it works as expected. Some parts will even work in isolation, e.g. if I remove everything except the parts that get the process and call process.Continue() and trigger those automatically, that "works" (meaning I see the lldb prompt flashing rapidly as it suspends and resumes execution. Usually I regret this because it becomes unresponsive and crashes shortly after.)
So: Any ideas? Is the technology Not Ready Yet, or am I just missing some clever piece of the puzzle that will fix everything? Or should I give up entirely and just live with the fact that there are some parts of object internals that I will never understand?...
Breakpoint commands cannot resume execution and then get control back again, at least today. There are a lot of unresolved questions about what would happen if breakpoint 1 is running the process and then breakpoint 2 is hit. Besides the whole question of whether the code base can really handle nested breakpoints correctly (it was designed to...), what does it mean if breakpoint 2 decides execution should stop? Is breakpoint 1's state thrown away?
It seems a little esoteric to worry about a breakpoint hitting another breakpoint while stepping the inferior process but unless all the details have been worked out, it's easy for the user to shoot themselves in the foot. So for today, breakpoint commands can either stop when the breakpoint is hit or continue to run - but there isn't any ability to run a little bit and do more processing. I know this would be a really useful capability for certain tasks but there are a lot of gotchas that need to be thought out before it could be done.
For some cases, it is possible to handle it the other way around ... if you want to stop in function parser() only when it has been called by function lexer(), it is easy to put a breakpoint on lexer() with some a few python commands to go one stack frame up the stack and see what the calling function is. If it's not lexer(), continue. I don't think this will apply to what you're trying to do, though.

Add code before initialization of units in Delphi

Is there a place where I can add code that will be executed before unit initialization?
The reason I want to do this is I need to change the DecimalSeparator, this has to be done before the initialization of some units. I have put it in the project source, before Application.Initialize but it is too late by then.
As I see it the only choice I have is to put it in the initialization of the unit that needs the DecimalSeparator to be changed, is this the case?
Thanks in advance for any advice.
Initialization order in Delphi is deterministic: units get initialized in the same order as the compiler compiled them, and finalized in the reverse order. The compiler starts at the top of the DPR's uses clause and works its way down, and for each unit it finds, it does the same thing recursively: start at the start of the uses clause, try to compile each used unit that isn't already compiled, then compile the current unit. So if you can get your unit in before any of the other ones get compiled, then it will get initialized first.
If you want to make sure it gets executed first, make a new unit, put your changes in that unit's initialization block, and then make sure it ends up in the DPR before any of the units that will depend on the changes. You might even want to make it the first unit, unless you have other "must be first" units there already, such as replacement memory managers.
Put it into the initialization section of the first unit in your project uses list, that way it will be executed prior to any other initialization code.
A word of warning here.
I've got an application running on the desktop of a logged in user and IN THE MIDDLE of testing the app the DecimalSeparator changed for me, without me restarting the application.
I used to set the
DecimalSeparator := '.';
once in the FormCreate() code, but that seems not the be enough. So now I set it once every time before I use my FormatFloat() function (used only in one place in my application).
I do not know WHY this happens, but probably there are some system-wide parameter changes happening, that reset the char to ',' on my system.
The best way to avoid this is probably to set the decimal separator in windows configuration to '.' to avoid strange problems...

Easiest way to find previous instance of an application

I have rewritten a VB6 application in Delphi. It should have only one instance running. How can I do this with minimum of code?
In VB6 we just have to use one single line of code
>
If App.PrevInstance Then
'Take some action
End If
On goggling I did find a solution but it is very length and we have to mess with .drp file.
I do not want to do that.
I want something simpler.
I have some code along the lines of:
var
AppMutex: THandle;
{ .... }
initialization
// Create the mutex
AppMutex := CreateMutex(nil, True, 'MY-APPLICATION-NAME');
if (AppMutex = 0) or (GetLastError = ERROR_ALREADY_EXISTS) then
begin
MessageDlg('My application is already running on this computer.'#13#10+
'You should close the other instance before starting a new one.',mtError,
[mbOK],0);
Halt;
end;
finalization
// Close the mutex
CloseHandle(AppMutex);
but I'm sure the answers in the thread that #mghie linked to are more helpful/richer features!
Edit: Note you can make this into a small unit in it's own right, then just use that unit in your project(s).
Note that in many cases, the user's expecation will be that launching the second instance results in the first instance being restored and brought to the foreground. Don't expect users to understand the difference between restoring a minimized/hidden app and launching from a shortcut or start menu.
In my experience one cannot decide in general wether an application my be started twice or not. It may be for instance perfectly valid to start the same application if it is started in another folder or under another user account or whatever. On the other hand it might be the case that two different applications may not run together if they are started in the same folder or so.
So besides the different approaches with mutexes and semaphores and handling race conditions, it is the wise selection of the mutex's or semaphore's name that handles the above combinations appropriately.
If an application may not run twice at all, take a GUID like name. You can even use the exe's filename if you can ignore that someone might rename it.
Restricting the one-time-start on a specific folder, you can take the exe path into account, but be aware that due to mappings different pathes may end up at the same exe.

In Delphi: How to skip sections of code while debugging?

I often accidently step into code that I'm not interested in while debugging in Delphi.
Let's start by saying that I know that you can step over with F8, and that you can run to a certain line with f4.
Example:
function TMyClass.DoStuff():Integer;
begin
// do some stuff
bla();
end;
procedure TMyClass.Foo()
begin
if DoStuff()=0 then // press F7 when entering this line
beep;
end;
Example: I want to step into method DoStuff() by pressing F7, but instead of going there, I first end up in FastMM4.FastGetMem(), which is a massive blob of assembly code that obviously I'm not interested in at the moment.
There are several ways to go about this, and I don't like any of them:
Add a breakpoint on "bla" (almost useless if you only want to step into DoStuff on special occasions, like iteration 23498938);
Instead of pressing F7, manually move the cursor to "bla", and press F4 (Works for this simple example. In practice, it doesn't);
In case of FastMM: temporarily disable fastmm;
Is there any way to hint the IDE that I'm never interested into stepping into a certain block of code, or do I always have to set extra breakpoints or use F4 to try to avoid this?
I'm hoping for some magic compiler directive like {$NODEBUG BEGIN/END} or something like that.
In most cases being able to exclude entire units would be fine-grained enough for me, but being able to avoid certain methods or even lines of code would be even better.
Update: Maybe codegear should introduce something like skip-points (as opposed to break-points) :-)
There is a "magic nodebug switch". {$D-} will disable the generation of debug code. Place that at the top of your FastMM unit and you won't end up tracing into it. And if you do end up in a function you don't want to be in, SHIFT-F8 will get you out very quickly. (WARNING: Don't use SHIFT-F8 from inside an assembly-code routine that plays around with the stack. Unpredictable behavior can result. F4 to the bottom of it instead.)
If you're jumping into FastMM code, then there are memory operations occurring. The code you've shown doesn't have any memory operations, so your question is incomplete. I'll try to guess at what you meant.
When a subroutine has local variables of compiler-managed types (such as strings, interfaces, or dynamic arrays), the function prologue has non-trivial work to do. The prologue is also where reference counts of input parameters are adjusted. The debugger represents the prologue in the begin line of the function. If the current execution point is that line, and you "step into" it, you'll be taken to the RTL code for managing the special types. (I wouldn't expect FastMM to be involved there, either, but maybe things have changed from what I'm used to.) One easy thing to do in that situation is to "step over" the begin line instead of into it; use F8.
If you're really pressing F7 when entering your highlighted line, then you're doing it wrong. That's stepping into the begin line, not the line where DoStuff is called. So whether you get taken to the FastMM code has nothing to do with the implementation of DoStuff. To debug the call to DoStuff, the current execution point should already be the line with the call on it.
If you only want to debug DoStuff on iteration 23498938, then you can set a conditional breakpoint in that function. Click in the gutter to make a normal breakpoint, and then right-click it to display its properties. There you can define a condition that will be evaluated every time execution reaches that point. The debugger will only stop there when the condition is true. Press F8 to "step over" the DoStuff call, and if the condition is true, the debugger will stop there as though you'd pressed F7 instead.
You can toggle the "use debug DCUs" option to avoid stepping into most RTL and VCL units. I don't know whether FastMM is included in that set. The key difference is whether the DCUs you've linked to were compiled with debug information. The setting alters the library path to include or exclude the subdirectory where the debug DCUs are. I think you can configure the set of included or excluded debug directories so that a custom set of directories is added or removed based on the "debug DCUs" setting.
Back to breakpoints. You can set up breakpoint groups by assigning names to your breakpoints. You can use an advanced breakpoint to enable or disable a named group of breakpoints when you pass it. (Breakpoint groups can have just one breakpoint, if you want.) So, for example, if you only want to break at location X if you've also passed some other location Y in your program, you could set a disabled breakpoint at X and a non-breaking breakpoint at Y. Set the "enable groups" setting at Y to enable group X.
You can also take advantage of disabled breakpoints without automatic enabling and disabling. Your breakpoints appear in the "breakpoints" debugger window. If you're stepping through DoStuff and you decide you want to inspect bla this time, go to the breakpoint window and enable the breakpoint at bla. No need to navigate to bla's implementation to set the breakpoint there.
For more about advanced breakpoints, see Using Non-Breaking Breakpoints in Delphi, and article by Cary Jensen from a few years ago.
I may have missed something with your post, but with FastMM4 you can edit the FastMM4Options.Inc include file and remove the '.' from the following define:
From FastMM4Options.inc ****
{Enable this option to suppress the generation of debug info for the
FastMM4.pas unit. This will prevent the integrated debugger from stepping into
the memory manager code.}
{$.define NoDebugInfo}
When recompiling (might need building) the debugger will (should) no longer debug the FastMM code.
Use a precompiled non-debug DCU of FasmMM
In the project dpr file, I use
uses
{$IFNDEF DEBUG} FastMM4, {$ENDIF}
... // other units
to exclude FastMM4 during debug mode. Requires no change in FastMM4 so I don't have to remember to add {$D-} in FastMM when I change to a different version.
AFAIK, the debugger is only aware of the files in Browsing Path that you can modify in Options. So if you exclude the paths of modules you're not interested in debugging that will give the effect of what you want to do.
One caveat: code completion also relies on Browsing Path so you might run into occasions that code completion falls short when needed.
Although it isn't a direct answer to your question, you could modify your first suggested solution by putting breakpoint at bla that is only enabled when a breakpoint at Foo is passed (or some other condition of your choose, such as iteration count). Then it will only break when you want it to.
As an aside, I am finding more and more that I am not halting execution at break points, but rather dumping variable values or stack dumps to the message log. This allows more careful analysis than on-the-fly inspection of variables, etc. FWIW.
No. I don't believe there is a way to tell the debugger to never stop in a certain section of code. There is no magic directive.
The best you can do when you get into a routine you don't want to be in is to use Shift+F8 which will Run until the Return. Then do a F7 or F8 to exit the procedure.
Hmmm. Now I see Mason's answer. Learned something. Thanks, Mason. +1

Resources