Is it possible to automate the insertion of breakpoints? For example, I need to insert a specific (the same) conditional breakpoint at the beginning and exit of every procedure inside a specific unit. To do this manually would be tedious and time-consuming, so I am looking for an automated way to do this.
-
5I've been working in Delphi since v1 was released, and currently have several projects with >1MM LOC. I have never once had the need to have this functionality (and I'm suspecting you won't find anyone else who has either). What exactly is making you think you need this? – Ken White Sep 04 '13 at 13:26
-
To answer the question at the end of your comment "What exactly is making you think you need this?": I want to quickly find out where a specific public variable becomes a specific value. This could easily be achieved by inserting a conditional breakpoint at the beginning and end of every procedure, with this condition ´MyVariable = AValue´. – user1580348 Sep 04 '13 at 13:42
-
2Or you could set a Data Breakpoint, which is tripped when the variable is changed, and then view the callstack to see what code was executing last. See help index; search on 'Breakpoints, setting data breakpoints' – Ken White Sep 04 '13 at 13:47
-
1So your real question is "How can I find out where/when a variable changes"? The answer is in Ken's comment – Gerry Coll Sep 04 '13 at 13:48
-
2@GerryColl No, this was just an example. – user1580348 Sep 04 '13 at 14:01
-
1@GerryColl Data break point is what you need here. Of course, if you'd made your public field a property then you could simply break inside the setter. – David Heffernan Sep 04 '13 at 14:03
-
Upvoted question. Just yesterday I was wishing for this capability. In my case, I want to see what component event handlers are being called as I exercise my UI. – RobertFrank Sep 04 '13 at 16:04
-
@RobertFrank, have a look at CodeSite - especially the Method Tracer (via Tools - CodeSite). – Uwe Raabe Sep 04 '13 at 16:10
-
@DavidHeffernan - which I quite often do – Gerry Coll Sep 04 '13 at 21:18
3 Answers
No. There's no functionality in the IDE to do so.
Based on your comment to the original question, what you're actually trying to do is detect where a global ("public") variable is being changed. The way to do that is to set a Data Breakpoint, which is tripped when the variable is changed, and then view the callstack to see what code was executing last. (You can find this in the help file by searching on "Breakpoints, setting data breakpoints" in the help index for Delphi 2007, or "Breakpoint Properties, Data Breakpoint" in XE4's help (linked above).
Note that both ask for an address to watch, but work with @VariableName
as well. (Using a stack (local) variable triggers a dialog that tells you that doing so can make your app unstable and asking you to confirm you want to do so.)
As @DavidHeffernan points out in a comment, a better solution is to make the public field a property with a setter, and then set a normal breakpoint inside that setter.

- 123,280
- 14
- 225
- 444
-
@DavidHeffernan: I added your setter suggestion as an alternative in the last paragraph. If you also post an answer to this question, please edit to remove that addition (or let me know and I will). – Ken White Sep 04 '13 at 14:12
-
Breakpoints are stored in the similar named section of the projects DSK file. Set one breakpoint manually in the IDE to find out the correct settings. Then copy and adjust this breakpoint in the DSK file to your needs.
This doesn't solve the problem to find out the correct line numbers though.

- 45,288
- 3
- 82
- 130
-
DSK files still exists ? I can't remember to see them since Delphi 2009. – TLama Sep 04 '13 at 15:59
-
-
2@TLama: Only if you check the box to save the project desktop in your project options, IIRC. – Ken White Sep 04 '13 at 23:51
-
-
The line numbers are a one time only problem. Once the breakpoints are set the IDE keeps track of the positions. – Uwe Raabe Sep 05 '13 at 06:14
-
'IDE keeps track...' if only... I can no longer keep track of the number of times (a day) that the IDE's breakpoint tracking gets it wrong and the breakpoint ends up on a blank line or somewhere else altogether (XE2). – Marjan Venema Sep 05 '13 at 06:41
-
Or until you remove them all and then decide you need them all again, when you realize that now the line numbers are no longer a "one time problem". This is not an automated solution; it's a manual one with a little support when you're done. :-) – Ken White Sep 06 '13 at 10:58
Yes *)
A breakpoint can be inserted with assembler code (see How to simulate a Delphi breakpoint in code?):
asm int 3 end;
Automated insertion (and removal) of this code in the places where you need the breakpoint is a trivial task, as tools which perform source code instrumentation (e.g. profilers for Delphi and other languages) show.
I do not say that it is easy, but possible.
*) if you are a programmer ;-)
-
1You didn't say it was easy; you said it's trivial. What's the distinction between those terms? I wouldn't exactly say it's trivial to write a source-code instrumenter. The first step is writing a parser, and that can be hard even *with* a published formal grammar. – Rob Kennedy Sep 04 '13 at 14:45
-
@RobKennedy instead of "it is trivial" I could say "this problem is of [Complexity P](http://en.wikipedia.org/wiki/P_%28complexity%29)" - here in an expert forum ;) – mjn Sep 04 '13 at 14:48
-
1Which source code instrumentation tools can insert (and of course then remove) *CUSTOM* code into the source code? For example: 1. At the beginning/exit of any procedure, 2. before/after every single statement which contains a custom identifier, etc. – user1580348 Sep 04 '13 at 15:37
-
@user1580348 this is a new question: I can not answer it, but some profilers for Delphi are available with full source code, for example asm (http://code.google.com/p/asmprofiler/) – mjn Sep 04 '13 at 16:25
-
Only when "ignore non-user breakpoints" is not selected in debugger options. – Sertac Akyuz Sep 04 '13 at 18:35
-
1This can cause an exception if one doesn't get removed (and doesn't typically get reached) and you release your code. The user gets an error message about 'External Exception 0x80000003', which is an unhandled debugger instruction (but the error doesn't mention that, of course). It has a tendency to tick them off, especially when they lose unsaved work. I speak from experience. :-) I did it to isolate an issue in the middle of a 100MB data file with an `if Copy(CurrLine, 12, 20) = 'SomeVal`` trying to isolate the problem, fixed it, and forgot to remove it. Weeks later, a file had the value. :) – Ken White Sep 04 '13 at 23:55