How do I stop F7 from going into Embarcadero code? - delphi

I am trying to debug a dense piece of code with multiple function calls in single lines. I want to single step through all the code that I have written, but in doing that I keep finding myself in the supplied source code, including the assembler code.
This is happening at a client's site on his machine running XE5. It doesn't happen on my own code, running XE2 and XE4.
What is the magic setting that makes this work they way I want?

The best you can do is make sure that Debug DCUs is disabled in the project options. But even doing that sometimes is not sufficient to stop yourself landing in RTL code, in modern Delphi versions. I suspect that you have Debug DCUs disabled and are being caught out by this behaviour change.
The only thing you can do is get used to knowing when to use step out (F8) rather than step in (F7), and being able to escape from a function as quickly as possible. Usually that involves putting the cursor on the last line, running to cursor (F4), and stepping in again.

You might also be interested in the Selective Debugging tool by Uwe Raabe which allows you a fine grained selection for which DCUs are used with or without debug information.

Related

How to maintain "Ignore/handle subsequent exceptions" breakpoints between developers?

Sometimes there are pieces of code where exceptions occur that you don't want to stop execution in the IDE (e.g. OLE exceptions when setting up a connection).
The trick is to place 2 breakpoints around this, with the 1st set to "Ignore subsequent exceptions" and the 2nd to "Handle subsequent exceptions".
This works fine when you are the only one working on the code, the breakpoint moves with the code.
However, when several developers update the same file and you import/export from/to version control (SVN in my case) the breakpoints can end up on the wrong lines and you have to reset them.
This is because these breakpoint settings are maintained locally in the IDE configuration.
Has anyone ever found a way to maintain these breakpoints among developers? How?
Using Delphi XE2 for W32 apps.
These breakpoints are stored in a DSK file - either that of the project or that of the project group, depending on what was open in the IDE. You may consider adding those files to the version control. However, this might have other significant drawbacks.

REPL for Delphi IDE?

http://en.wikipedia.org/wiki/REPL Read–eval–print_loop
Is there such a thing for Delphi ?
It would be rather useful to explore DLLs such as Windows APi and sketch their usage, when dealing with border cases scarcely documented.
I tried pascal scripts, such as one in Cnwizards, but it is much less comfortable.
For example it cannot use units like Windows.pas and you had to make some strange stubs of your own for it.
And anyway, those scripts are less easy to use for "try this try that" scenario than Repl.
For Delphi objects most clsoe thing it to pause on breakpoint and use Evaluate/Modify window, but it only works with Delphi objects, not DLLs; it cannot make temporary vars to cache values and such.
It's not really what you're looking for, because Delphi is a statically typed, compiled language, but if you really insist on being able to type some pascal in and see if it does anything, you can try the TJvInterpreter component that comes in the Jedi VCL.
Note that the experience is nothing like using python. You can't just type "uses module" and hit enter, because pascal units must be complete before they can even be interpreted by JvInterpreter, and the JvInterpreter needs you to write a wrapper for every single other unit you want to import. You would go crazy. I'm not seriously advising anybody to try to build a REPL around TJvInterpreter.
The "interactive magic" element of Delphi is called the "designtime environment" and the way we build using "components". We don't even do that bit by writing code much, we do it all visually with our mouse and keyboard. It's called RAD (rapid application development) and is powered by the VCL (visual component library) in Delphi, and (like REPL) is one of the many ways of doing very-rapid development.
The other thing we have that is a lot like a REPL is this button in Delphi:
You click it, after creating a new empty project, and whatever code you added to your new empty project is built and running in less than a second. Close enough to a REPL for me. It's kind of like binary executable instant bliss.
Write one line. Build and run (1 second). Instant.

How to skip assembly code when debugging in Delphi?

Sometimes when debugging, specifically when catching an exception and following through destructors called, Delphi steps through a lot of assembly code. Hit Shift+F8 appears to cause mayhem.
Can I tell the debugger to skip assembly code automatically?
In my experience, the vast majority of such assembly code is in VCL or RTL units.
If you compile with "Debug .dcu's" disabled then the debugger will not step through this code. However, it will also not step through any other VCL/RTL code either - assembler or Pascal. It will still step through any code that is not part of the VCL/RTL, assuming you have the Debug information option enabled for the project.
Whether turning off VCL/RTL debug units makes debugging any particular issue you may have easier or harder will of course depend on your particular circumstances, but usually what is going on inside the VCL/RTL code is of little consequence unless and until you have eliminated the possibility of some error in your own code and then need to investigate a potential bug in the VCL/RTL itself.
For myself, I have "Debug .dcus" turned OFF unless I need them ON.
Your mileage may vary.
If you see assembler code, you probably are in the Alt-F2 CPU view. Just close the CPU view (escape key on old Delphi, or close its tabs), and you'll continue stepping within pascal source code (e.g. press F7 or F8).
If you see assembler code in the middle of a .pas file (in an asm ... end block), then you can try going to the end of it (at end level) and press F4 (shift F8 is buggy). But be aware that it may quit not at the end but in an internal ret assembler op code. So my personal advice is, if you do not know about assembler, to display the Call Stack (this window displays the function calls that brought you to your current program location and the arguments passed to each function call) and double-click on the parent caller. This will be always safe.
For additional info about debugging, this e.g. this article.
You can use the {$D-} directive to switch off debugging for a block of code. I think this will allow you to achieve what you want.
Also - dont use shift F8 in assembly code, I believe it causes all sorts of trouble - better to place your cursor after the block and F4 down to that.

Find all compilation errors in a Delphi project

I am doing some refactoring of my Delphi project. I want to be able to make a change, then see all the places in the project that break due to that change. Similar to how Eclipse lists all the compile errors for a project (in Java).
In Delphi, I can make a change, then recompile my project, but the compiler stops when it finds the first Unit that does not compile. I have to fix that Unit, compile again, which will then show me the next error, etc etc.
I want to be able to see all the compile errors in the project at once. Then I can decide if the change is worth doing or not. For example, if the change will require hand fixing of 50 separate source files, it's not worth doing. But if it only breaks 2 files then that's an easy change to make.
Is there any way to do this in Delphi? Can I tell the compiler to keep going even after finding a Unit that does not compile?
I am using Delphi 2010
Delphi units, as a modularity feature, are conceptually at a similar level to Java jars or .NET assemblies; they compile to individual files. In neither Java nor .NET can you compile dependent modules when you have compile errors in a referenced module.
The reason they are more granular than .NET assemblies etc. owes to their history. They were designed in part around the segmented x86 architecture; the data associated with any one unit could not be any larger than 64KB. Similarly, units served as a natural division between near code and far code. If you're familiar with 16-bit x86, you'll know that pointers to far data required a value for the segment as well as the offset, while near data only needed an offset. Calling near code was also faster than calling far code. Programs were also smaller and less complex back then; the unit was a reasonable granularity of module for an entire subsystem's worth of behaviour. This is much less the case today.
There's no way to do that with the Delphi compiler, but if you're considering making a breaking change to some part of a unit's public interface, you can use the refactoring tools that come with the IDE to find all references to whatever it is you're about to change before you change it, which will give you the information you're looking for.
The Delphi compiler already tries to compile as much as it can.
Unfortunately, very often, an error is critical enough to prevent the compiler to move past the error as it cannot make an assumption as to what the code should be it if were compilable.
Moreover, very often, the errors a compiler can give after the 1st error has been encountered are not reliable and may even disappear after the 1st error has been fixed. (witnessed by all the red squiggly lines appearing and disappearing when you type)
What the compiler does however is to provide all the hints and warnings (which are called errors for some other compilers).
You can use Ctrl-Shift-Enter to see all occurances of the variable, property, method or wahtever is currently under the cursor. With that information you can decide to do your changes or not.
Alas, with the current version this feature doesn't work as reliable as it should.

Debug Breakpoint doesn´t work only in DataModule unit - Delphi

Debug breakpoint's works fine in all other 38 units of my system. But, in my DataModule, that have +- 10.000 lines, delphi disables then after I launch by F9/F8/F7. In any part of source that unit, even on obrigatory steps like OnCreate, SQLConnection.Active:=true, etc.
Detail: works fine until +- 20 days ago.
I'm using D7 and have all sources of components also.
Thanks
Felipe
Try doing a full build (Shift+F9). If that does not work, then what happens if you simulate a breakpoint in code with the below?
asm int 3 end;
Check for multiple copies of your source file for the datamodule. Sometimes the code you think you're running isn't the code the compiler and debugger are seeing.
Next, make sure you haven't accidentally turned off debugging in your code with {$D-} or {$DEBUGINFO OFF}. This can turn off debugging info for a single unit.
Also, make sure you've turned on Integrated Debugging in Tools|Options|Debugger Options. I know you said you could debug other places, but it can't hurt to make sure that integrated debugging didn't get accidentally turned off somehow.
I discovered this problem. It's a weird behavior in Delphi7 that limits the number of fields in interface class section, between: type TDM=class(TDataModule) and private section. I deleted some fields (DataSet Fields (+-40 fields)) and degub runs again. I add these fields again, and debug not runs. I'm sure that's a limit, because doesn't mather which component fields I deleted. I tried with several fields, from different tables too, adding, testing and deleting. It's a shame, but is true...
Thanks for your help.
I have a vague memory that debugging very large files was buggy in old D7.
Try to break you big unit in several classes and se if you can debug outside your unit.
Another option could be to turn off debuginfo in your big file except the section you want to debug. It is worth a try.
There's a blog post from Steve Trefethen, a while back, explaining some possible reasons, although if you say you can debug other units, I doubt they'll apply.
We had the same issue with a large DataModule in Delphi 5 that wouldn't let us debug it, and kind of put it down to it being too large a file to debug and Delphi not liking it. When we moved to Delphi 2007, we could debug it again. Not sure why, nothing had changed (code wise).
Felipe, is the unit that will not allow you to debug in a dll that is being moved into or out of memory? I've found when debugging dll's that if I do something in the executable that executes code in another dll or unloads the dll that the problem unit is in - Delphi will disable all breakpoints. Usually a restart of Delphi and being sure to keep a single instance of the problem unit's dll in memory is the only solution for this problem.
I doubt size is the issue, as I have a 17k line unit that I debug regularly.

Resources