Strange "inaccessible value" in debugger - delphi

Could anyone explain this screen:
As you can see I have simple array - debugger shows values of its elements when I use A[0], A1...
but I cannot get elements with local variable A[i] (but value of "i" is shown correctly).
Project settings:
Debug info: ON
Local Symbols: ON
Optimization: OFF.
Project (one PAS file) is BUILD so DCU is fresh. You can see on that screen almost full code of this test project so there is no chance that array A or "i" is declared in some other unit etc...
Now I checked - the same code in Delphi XE3 works perfectly - debugger shows all values.
It seems that XE4 has a serious bug in basic feature :-((

i is a var and this var need an amount for instance change i to 1 and check it;
A[1].val;

It doesn't work because 'val' is a function and not a variable. Double click on the watched item and check the property 'allow function calls'.

Related

Delphi : Field 'False' not found. occurred only on my computer

I have a TCustomClientDataSet (in memory) which is used to do some filtering in a Delphi program.
My filtering code look like :
CDSFilteredGroup.Filter := 'ACP_type = 1 AND ACP_by_default <> False';
CDSFilteredGroup.Filtered := True;
When I compile and run it, I got the following error only with Delphi (XE4) installed on my computer :
CDSFilteredGroup: Champ 'False' non trouvé.
Translation: Field 'False' not found. The same code compile and run perfectly fine on my colleagues computers, but not on mine. There must be an option somewhere that I miss, any idea ?
Remember, the code is ok and working...
The TExprParser instance used for handling the filter string relies on the resourcestrings given as STextTrue and STextFalse. You probably have another language than English configured for your IDE library. Try switching to English and see if the error disappears.
To workaround that problem in general replace the text "False" with the content of the resourcestring STextFalse.
BTW, this was corrected in later Delphi versions that also accept the literal "False" even in non English environments.

Delphi code compilation error

when i compile my code i can see that some lines are not compiled. Due to this issue some codes does not execute according to the way i want.
i have attached a screenshot of the delphi IDE in the debug mode. Blue dots on the left shows the lines which are compiled and those lines without the blue dots does not function properly or not complied
As can see on the watch window that variable dPcnt value is 0 taxP, srvP, serv_charge does not have a proper value but in the code window can see that the variables have been initialized to 0
Can someone help me out to correct the issue.
It is the optimizer that has removed useless lines like
srvP := 0;
because you don't use that value before you assign a new value on line 770.
I can not see how and where the other variables are used, but I bet the reason is similar.
You can turn optimization on and off with the compiler directive {$O+} or {$O-} {$OPTIMIZATION ON} or {$OPTIMIZATION OFF}. But, please note what help says about it:
Other than for certain debugging situations, you should never have a
need to turn optimizations off. All optimizations performed by the
Delphi compiler are guaranteed not to alter the meaning of a program.
In other words, the compiler performs no "unsafe" optimizations that
require special awareness by the programmer.
If you have compiler hints turned on ({$HINTS ON}) you will see hints in the form H2077 Value assigned to '%s' never used for lines that are 'useless'.
Further info here:
H2077 Value assigned to '%s' never used #Delphi#

Unit source code does not match code execution path when breakpoint hit

I am debugging a DirectShow filter I created with the DSPACK code library using Delphi 6 Pro. When a breakpoint I set is hit in one particular unit named BaseClass.pas, and I begin tracing, the Execution Point jumps to strange places in the source code. This usually indicates that the source code being traced does not match the source code that was compiled into one of the packages being used by the Delphi application. Oddly enough it is only the BaseClass unit since I have traced other units belonging to the DSPACK code library and they do not exhibit this problem. I am not using run-time packages.
I scanned my disk and found only one copy of BaseClass.dcu with a modification date equal to the last time I built the program. I have not modified the source for that unit or any other belonging to DSPACK. Since my Filter is part of the main application this indicates that BaseClass.pas would be subject to a dual use situation since it is used to build the DSPACK component package (dpk), and is also referenced by my main application directly via the TBCSource object my Filter descends from. Note, I did try adding the unit PAS file directly to my Project but that didn't fix anything.
I also went back and re-opened each of the DSPACK package files and did a full re-build. None of this helped. Is there something else I can try to get the source synchronized with the compiled image of the BaseClass unit? Or is a different problem altogether and if so, what is it and how can I fix it?
Sometimes this happens when code is copied/pasted from web pages or other sources, and the lines don't end with CR/LF pairs (#13#10 or 0x0D0A, standard for Windows) but end in only LF (#10 or 0x0A, typically the line ending in *nix systems) or CR (#13 or 0x0D, typical with Mac OSX/iOS). The incorrect line terminators confuse the debugger - this has been an issue for the past several Delphi versions.
You can sometimes fix this by opening the source file using a text editor like Notepad, making a small meaningless change (insert and then delete a blank line, for instance), and then save the file.
I had same problem and made a similar utility. Fixed it.
Basically, just this:
procedure adjustCRLF(filename : String);
var
strList : TStringList;
begin
strList := TStringList.Create;
try
strList.LoadFromFile(filename);
strList.Text := AdjustLineBreaks(strList.Text);
strList.SaveToFile(filename);
finally
strList.Free;
end;
end;
There is another way this can happen: if the IDE erroneously opens another source file with the same name (but different, such as an earlier version) then all the debug points will be incorrect, and the debugger will even allow you to step through the incorrect file.
I've seen Delphi 7 do this once.
Make sure that when you rebuild it, that in the compiler options for your project that you have "Debug Information" turned on. In fact, most of the options under Debugging should be set in your project's Compiler options.
Also, if you haven't already, restart Delphi.

Debugging code in Delphi XE

I am a long time Delphi dev and in the past I use a third party tool for logging and debugging while developing (called Smart Inspect) however now that I've upgraded to Delphi XE I want to try and use the IDE for debugging.
My question is, given a function like
procedure MyFunction;
var
str : string;
begin
str := 'Foo';
//Debug, show value of str?
str := AnotherFunction(str);
//Debug, show value of str?
end;
how can I debug and get the value of str, without doing stupid things like
showmessage(str);
if there is a video somewhere (or article) then I am more than happy to read.
Is there a way to watch/output the value of variables.
If you want to use the IDE Debugger only, then do the following:
put a breakpoint somewhere
right click on the breakpointr circle and choose "Breakpoint Properties ..."
press "Advanced" button to show more options
uncheck "Break" checkbox
then use "Log message" and "Eval expression" edit boxes to enter trace values
Such messages will be send to "Event Log" debugger pane. Right click on the pane and choose "Properties". There you can filter ("Messages") / hilight ("Colors") the trace messages as you whish.
Well, Delphi XE comes with CodeSite logging, but I get the feeling you're talking about the debugger itself.
If you place a breakpoint in a routine, it will break to the debugger when it hits it. From there, you've got a Local Variables pane and a Watches pane along the left side of the IDE. Local Variables will show the value of all locals, and Watches lets you set up expressions whose value it will keep track of.
You can also get something similar to a watch, but with more detailed information (especially for structured types such as objects) by using Inspect (Alt-F5). Also, the Evaluate/Modify (Ctrl-F7) will allow you to type in expressions and evaluate them. It's not quite as detailed as Inspect, but it gives you a lot more flexibility.
If you familiarize yourself with these tools, you'll find debugging much easier.
1) You can use OutputDebugString Function to output string to debug window
2) You can use CodeSite Express. I recommend video from CodeRage 5 as a starting point for using CodeSite
Other answers are all correct.
My personal favorite technique (same as the answer by da-soft) is to create a breakpoint, that logs a message to the event log, containing a value that I want logged, and does not actually "break" (that is, execution continues without you hitting the Run icon). Then every time that line of code is reached, I get my message, and my values in the log. Since I can go back and read the history, as well as see the current values, I find this more useful than merely using the debugger watch window.
But since Delphi XE includes CodeSite, you can go far beyond what expression evaluation in breakpoints does for you. Code Site however requires that you modify your code to add some logging. But it's much better than a message box.
You can also use OutputDebugString(PChar(s)) to output any string to the debugger. Since this can contain whatever you want, it's a very nice way to debug but not show stuff to the end user.
In many of my applications, I have a special trace buffer, which is circular (that is, it keeps only the last 500 or so lines). When ever I see a problem, not only do I get a stack traceback, I also save that in-memory trace log, so I have some history on what was going on just before my problem.
You can also check out the Log 4 Delphi project.
I prefer debugger hints. After breaking to the debugger move your mouse to the "str" anywhere in your code and you will see its current value. Also you can highlight some statement by a mouse and evaluate it. For example highlight "AnotherFunction(str)" and place your mouse over it.
Nothing wrong with any of the other answers but I just wanted to add these useful functions.
procedure DebugString ( const s : string ) ; overload ;
begin
{$IFDEF DEBUG}
OutputDebugString ( PChar ( s ) ) ;
{$ENDIF}
end ;
procedure DebugString ( const s : string ; args : array of const ) ; overload ;
begin
{$IFDEF DEBUG}
OutputDebugString ( PChar ( Format ( s , args ) ) ) ;
{$ENDIF}
end ;

Delphi debugger showing ???? for Currency variables

I'm trying to see the value of a variable, but the debugger shows me a value of "????". This seems to happen to Currency variables, but not other types (Double and enumerated types are ok).
I'm debugging on Windows XP SP 3 using Delphi 10 Update 2.
The process I'm using is:
Build the project in the BDS IDE.
Copy the exe to the directory where the service is expected to live.
Start the service. It's running locally, I'm not trying to remote debug.
Attach to the service process (Run | Attach to Process).
The process stops at my breakpoint(s), so the attaching seems to be ok.
Evaluate the value of a variable.
To evaluate the variable I've tried:
Hovering the mouse over the variable name. Usually this displays the value, but in this case it doesn't show anything (i.e. no pop-up).
Right-click the variable name, Debug, Evaluate/Modify shows a value of ????.
Right-click the variable name, Debug, Add Watch at Cursor shows a value of ????.
The Local Variables window shows a value of {.
It seems to be related to Currency, so I tried changing the variable type from Currency to Double, and when I re-ran the test the debugger showed the correct value.
The variables I'm trying to evaluate is a local variable with nothing tricky being done, e.g.:
function FooBar: Boolean;
var
foo: Currency;
bar: Double;
begin
foo := 0; // Breakpoint next line, evaluate foo shows "????"
bar := 0; // Breakpoint next line, evaluate bar shows "0"
...
end;
The Project Options I think might be relevant are:
Compiler
Code Generation
Optimization = Off
Stack frames = Off
Pentium-safe FDIV = Off
Syntax options
Strict var-strings = On
Complete boolean eval = Off
Extended syntax = On
Typed # operator = Off
Open parameters = On
Huge strings = On
Assignable typed constants = Off
Runtime Errors
Range Checking = On
I/O Checking = On
Overflow Checking = On
Debugging
Debug Information = On
Local Symbols = On
Debug Info = On
Definitions Only = On
Assertions = On
Use Debug DCUs = Off
Linker
Map file = Detailed
Linker output = Generate DCUs
Exe and DLL options
Include TD32 debug info = On
Include remote debug symbols = On
Can anyone suggest what's causing this and how I can make it work?
Edit:
I tried a test program consisting of a form with a button that formats a Currency variable onto a label. Debugging as described above (attach to process etc), the debugger showed the correct value. Now wondering if the problem is specific to debugging a service ...
Hm - it works for me in Delphy 2006. I did only create a small console app though. A suggestion for a workaround - cast the variable into an int64 inside the debugger. It should show the value multiplied by 10000.
The problem seems to be due to not having program.rsm file in the same directory as program.exe (step 2 of my process copied the exe to somewhere else).
Program.rsm is generated when Include remote debug symbols is enabled. I had it checked, but didn't think it was relevant because I was debugging locally. I'd only ever used program.rsm when debugging remotely, and it didn't occur to me that debugging locally but in a different directory is kind of "remote".
So there appear to be three possible solutions:
Set the path to program.rsm in:
Project | Options | Debugger | Symbol Tables | Debug symbols search path.
Set the output directory in:
Project | Options | Directories/Conditionals | Output directory.
Copy program.rsm to the same directory as program.exe before debugging.
It's still a mystery why the Currency variables were the only ones affected.

Resources