I am trying to run a debug on my code, but somehow it stopped working. Here is a snippet and the green lines it is showing:
I have tried to right click on my project and clean it.
Tried
to delete temporary files, like .stat and .dcu.
Switching back and forth to Release and Debug modes, rebuilding, recompiling them.
The Debugging options under Project -> Options -> Delphi compilingare all set to true.
Checked if there are no duplicate files in the search paths.
Other projects are working correctly.
Also tried swearing.
What am I doing wrong?
It is a kind of normal compiler behaviour. It ever happens when the procedure (code line) is never called from anywhere inside your program. Compiler skips such procedures and functions (all the code lines within them).
See the picture.
You just need to check if the procedure (line) is really at least once called from anywhere inside your application.
Appended
This also takes place when the code line can never be called and this (the logic statement) can be evaluated at compilation (the result is known in advance and can not be affected at runtime). The compiler optimizes the code skipping such lines. That is why it does not accept breaks at them.
Here is a diassembly of the latter procedure. The if false then ... statement at lines 37 and 38 is omitted:
Adding to the answer from asd-tm, I include the following line in all my units:
unit SomeRandomUnit;
{$I ProjOptions.inc}
In the ProjOptions.inc file, I include the following code:
// Compiler switches:
// Debug Info Optimisation
// DEBUG On Off
// RELEASE Off On
{$IFDEF DBG}
{$D+}
{$O-}
{$ELSE}
{$D-}
{$O+}
{$ENDIF}
In this way, optimisation is off and debug information switched on when I am debugging without me worrying about accidentally toggling something in Project > Options. Manually deleting DCU files from the PROJECT\objects folder (combined with the above .inc file) should guarantee breakpoints working again (at least in DEBUG builds).
Related
Wait! - this is not as silly a question as it sounds. The title is simply succinct.
I have some debugging code to verify the correctness of a data structure and some assertions checking this correctness, which I only want enabled in the Debug build:
{$ifdef DEBUG}
function Sorted : Boolean;
function LinearSearchByValue(const T : TType) : NativeInt;
{$endif}
and later in a method:
assert(Sorted);
for example.
In my debug build with assertions enabled, all is fine. However, in my Release build with assertions disabled, the line assert(Sorted); causes a compiler error E2003 Undeclared identifier: 'Sorted'. It's quite right, the identifier isn't declared, but assertions are also turned off and should not be being evaluated or have any code generated. (Trying to trick assert by declaring the method but having no implementation causes the normal error 'Unsatisfied forward or external declaration'. It is clearly looking for the method body as well.)
This is leading to some messy code where methods that should not exist in a Release build at all have to be declared and have a body, in order to compile asserts, which are turned off.
How do I declare methods that exist only in a debug build, and use those in assertions which should also only exist in the debug build, in Delphi 2010?
Further info:
I tried wrapping the method declarations with {$ifopt C+}, which checks if assertions are switched on. The calls to assert still failed with 'undeclared identifier'.
Compiler options are definitely that assertions are turned off. (I checked :))
I have tried wrapping calls to assert that use these methods with {$ifdef DEBUG}. However, this is messy and should not be required. At one point it made me worried that assertions are being compiled even in Release builds, and for performance reasons I don't want them at all. (This is not happening - assert code is not generated.)
My current strategy is to declare these methods all the time, but in a Release build ifdef the method body out and fill it with a dummy Result. The aim here is to all assertions to compile, but have as little overhead for the methods as possible, and their return value (should they have turned out to be actually called in a release build) to be clearly wrong.
Is there any equivalent to C/C++-style macros in Delphi, where an ASSERT(x) macro would simply be defined as nothing in a release build, causing the compiler to neither see nor care about the statement inside the assertion? This is one of the few clean ways (IMO) to use macros in C++.
So while asserts are not being generated, they are compiled. This loops back to my question: How do I best mix debug-only methods and assertions, and release builds?
Don't exclude the code from your release build. Keep the code there, and have it compiled unconditionally.
Your argument against having the code exist in a release build is that it's "messy." But you've already written the code, so it's going to be messy whether it's compiled or not. You may as well let the compiler compile it; it doesn't take appreciably longer to compile the extra code, after all.
Trying to exclude the assertion-related code only makes your code messier by requiring conditional-compilation directives.
Assertions and debug information are orthogonal settings. Assertions can be enabled when debugging is not, and vice versa.
An alternative is to move your assertion-related code into your unit tests. Then they're automatically excluded from all versions of your application, but they're still available for testing.
Assertions are usually "elided" or not included in the output executable code at the link step in the compile process. The source code symbols and expressions passed into the assert function must be defined in the compile step so the the compiler can parse and generate code for the assertion and its expression parameter.
Whether the assert is included in the output exe is determined by the linker when copying code to the output file. Depending on the compiler, the expression passed to the assert might still be included in the executable code even if the call to the assert function isn't included.
As noted in other answers and many comments, asserts are not exclusive to debugging. Asserts are also valuable in release code, to verify that must-never-happen conditions don't.
One solution to allow you to leave assertions in your release code while making the functions used in the assertion expression exist only in debug builds is to define do-nothing stubs of the debug functions for the release build. Like this:
// Declaration:
private function Sorted: Boolean;
// Implementation
{$ifdef DEBUG}
function Sorted : Boolean;
begin
// work work work
end;
{$else}
function Sorted: Boolean;
begin
end;
{$endif}
// used in an assertion:
assert(Sorted);
This allows you to use the assertions in debug code and in release code without polluting your source code with ifdef wrappers around the assertions, and guarantees that the debug implementations do not exist in your release code.
As we know Build compiles all used units and Compile compiles only changed used units. But when you are working with ifdefs and need to change it a lot of times you must Build the project a lot of times.
If you have to much libraries that you know that this IFDEF will not change the behavior, there is no reason to build this library again.
What I want to do discovery is a way to say to the IDE that some files was changed and call the Compile and not the Build.
How to get the units and every else I know, but some know how to set the unit as modified?
Tks
Couldn't find a why to solve my problem yet. I found a way to set it as modified the problem is that it doesn't force the IDE to build it as I thought it'll.
Some one know what checks is made to an archive be sent to compile ?
Solved in a simpler way. I just deleted the DCU of the file and ok, it'll compile it again. :D
http://paste.ideaslabs.com/show/KCB9cq2Z8c
Let us assume that what you want is to mark editor buffers modified. That assumes there is an editor buffer to modify, which in most cases, there isn't, for most items in your Project. Let's suppose that you ALWAYS have every file in your project open at all times, then perhaps you can tweak those open units, this way.
My thinking is that you would actually need not only to mark editor buffers modified, but also TOUCH all the files on disk that would need to be rebuilt because of the #define change.
To know which files are affected, you would need to read all the files. I think, that the odds of you doing this reliably, over and over again, and faster than just doing a BUILD are pretty slim.
But if you did decide to go for it, you need not only to modify buffer Modified flags, but also, for any other file in the current project group, or which is in a folder included in the search or library path, find any file which might be affected.
You can see perhaps that this is more complex than you first thought.
And, as far as OTA goes, here is IOTAEditor property, Modified, it is read only.
The OTA doesn't want you changing it:
IOTAEditor = interface(IUnknown)
['{F17A7BD0-E07D-11D1-AB0B-00C04FB16FB3}']
...
function GetModified: Boolean;
..
property Modified: Boolean read GetModified;
..
end;
But you could actually modify the buffer CONTENT itself, and that would set the flag.
Use IOTAEditorContent, get the content (IStream), modify it (add a space), then modify it again (take away the space). You have now set the dirty bit (call GetModified just for luck).
I found some sample code from JCL JclStackTraceViewerStackCodeUtils.pas that shows you how to read editor content using IOTAEditorContent:
function GetFileEditorContent(const AFileName: string): IStream;
var
I: Integer;
Module: IOTAModule;
EditorContent: IOTAEditorContent;
begin
Result := nil;
Module := (BorlandIDEServices as IOTAModuleServices).FindModule(AFileName);
if Assigned(Module) then
begin
for I := 0 to Module.ModuleFileCount - 1 do
if Supports(Module.ModuleFileEditors[I], IOTAEditorContent, EditorContent) then
begin
Result := EditorContent.Content;
Break;
end;
end;
end;
After re-reading your question, it seems to me you only want to mark open editor buffers as all changed, and then do a compile, for speed. So you might want to do this: Take the code above, get the IOTAEditorContent using Supports(), and tweak each one.
Update: Short and sweet version: Modifying the buffer isn't sufficient. Plus, you won't have buffers for the files you need to change, plus Touching the file on the disk doesn't do what you want. So no, you can't do exactly what you wanted to do. And even if you could somehow modify the compiler's ability to do Make-style dependency and modification checks, you would probably cause a lot of problems inside the IDE.
On IOTAModule70 = interface(IOTAModule50) I'll find MarkModified:
Description:
{ MarkModifed will mark this module as "modified" without actually indicating
why is it modified (which will cause internal file dates to remain constant).
This will force the IDE to ask to save this module when the user attempts
to close it. It will also clear the "discardability" of a new unnamed
module such as when File|New|Application is selected. }
I was able to build one application up to this morning, then I don't know what happened as I try to build I have
[DCC Error] myunit.pas(1710): E2056 String literals may have at most 255 element`
Why this if this was working? (1710) was not edited in last month. I checked with a colleague project options and environement options one by one and they are the same. (the only difference is that i installed all Delphi updates, while he didn't anyway I didn't install them today).
moreover if I fix the above "erroor" by splitting the string in 2, doing something like
S := 'firstpart' + 'secondpart';
instead of
S := 'firstpartsecondpart';
// this is an example of course firstpartsecondpart
//is a string of more than 255 chars
I have another problem:
[DCC Error] myunit.pas(1797): E2283 Too many local constants. Use shorter procedures
Why this? I didn't change this procedure today. It is a long procedure indeed, but it used to compile up to this morning. I tried to split tjhe procedure in 2 and I was able to compile...
And Finally...
Breakpoints doesn't work anymore. If I try to set a breakpoint, after compiling and linking the RED cirlce of breaxpoint becomes green with an X, like when you try to debug a line of code that cannot be debugged.
I tried all, including rebooting and setting Debug Info to True in project options.
FINAL NOTE: It seems that for some reason some strange settings have been applied. I can't recall having done something strange. Recently I installed CnPack, but I could use it effectively for days. This problem started today.
Can anyone give me an hand? I am in real trouble, I lost half day and I still don't see a way out.
It seems you've changed the "Huge strings" project option. Did you add a {$H} to your code? Or did you fiddle with the project options? ("Compiler options/Huge strings" need to be checked to default to strings longer than 255 characters.)
The green breakpoint thingie means that this specific code is not compiled, thus it will not be called. Check if your code is calling this code, or perhaps it's looking at some other (pre-compiled?) unit.
My comments from below to complete the answer:If all breakpoints are green, it appears you have a problem setting the project options. If you remove the YourProject.dproj and YourProject.dproj.local files (Move somewhere else, don't delete) and then open the YourProject.dpr, your project should have the default options. Check if it works in that case. If not, move the old files back.The E2056 error is because strings inside Delphi code cannot be longer than 255 characters. Splitting it by including '+' in your string can fix this. See qc.embarcadero.com/wc/qcmain.aspx?d=71575 for why your collegue doesn't get this warning.
I am using Delphi 2007 with all patches and updates.
I have a file which is used by two different projects. In that file is a procedure, which I will simplify as follows:
procedure MyProcedure;
const
UniqueValue: integer = 0;
begin
//some code
Inc(UniqueValue);
//some more code
end;
The Inc() command should fail, because you cannot assign to a constant. In one project, I get an error to that effect (I'll call that project "Accurate"). In the other project, I don't get any errors (I'll call it "Bogus"). I also don't get any warnings. I can't figure out why the compiler lets this incorrect code through.
Here's what I've tried in project Bogus:
1 - Introduce an obvious error, like typing "slkdjflskdjf" in the middle of a line
Result: I get an error,which proves that it is really trying to compile this file.
2 - Delete the .DCU, and rebuild the project
Result: The .DCU is re-generated, again proving that the project is truly compiling this erroneous code.
Does anyone have thoughts on why this behavior would occur? And more specifically, why it would occur in one project but not another? Is there some obscure compiler option to permit assigning to constants?
One final note: Both projects are converted from Delphi 5. Under Delphi 5 with similar code, they both compile fine.
Edit: Thanks for all your help. After changing the assignable typed constants directive, I can get consistent behavior across both projects. I learned something new today...
There is an option for this called "Assignable typed constants" in Compiler Options. It can also be enabled with "{$J+}" in your code.
Could it be that those projects differ in the setting of the $J compiler directive?
I'd suggest to check the Project Options, section Compiler and see if you can spot any differences. Maybe you have option Assignable typed constants enabled in the Bogus project.
As others have said it's almost certainly the {$J+} directive.
If you have a diff tool you can compare the project files to see how they differ - they're just text files - to solve similar problems in the future.
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