Delphi debugger showing ???? for Currency variables - delphi

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.

Related

How to find the file paths of all namespace loaded in an application using tcl/TK under Unix?

For existing flow, there would be a whole bunch of namespaces loaded when running some script job.
However, if I want to check & trace the usage of some command in some namespace, I need to find the script path of the certain namespace.
Is there some way to get that? Particularly, I'm talking about Primetime scripts.
Technically, namespaces don't have script paths. But we can do something close enough:
proc report_current_file {call code result op} {
if {$code == 0} {
# If the [proc] call was successful...
set cmd [lindex $call 1]
set qualified_cmd [uplevel 1 [list namespace which $cmd]]
set file [file normalize [info script]]
puts "Defined $qualified_cmd in $file"
}
}
trace add execution proc leave report_current_file
It's not perfect if you've got procedures creating procedures dynamically — the current file might be wrong — but that's fortunately not what most code does.
Another option that might work for you is to use tcl::unsupported::getbytecode, which produces a lot of information in machine-readable format (a dictionary). One of the pieces of information is the sourcefile key. Here's an example running interactively on my machine:
% parray tcl_platform
tcl_platform(byteOrder) = littleEndian
tcl_platform(engine) = Tcl
tcl_platform(machine) = x86_64
tcl_platform(os) = Darwin
tcl_platform(osVersion) = 20.2.0
tcl_platform(pathSeparator) = :
tcl_platform(platform) = unix
tcl_platform(pointerSize) = 8
tcl_platform(threaded) = 1
tcl_platform(user) = dkf
tcl_platform(wordSize) = 8
% dict get [tcl::unsupported::getbytecode proc parray] sourcefile
/opt/local/lib/tcl8.6/parray.tcl
Note that the procedure has to be already defined for this to work. And if Tcl's become confused about what file the code was in (because of dynamic programming trickery) then that key is absent.

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.

memory trace of all variables in program with DBI tool

I am using intel pin as my primary DBI tool.
I am interested to know how can I trace all variables allocated in a program .
suppose, we have the following snippet in C:
int *ptr_one, *ptr_two, g;
ptr_one = (int *)malloc(sizeof(int));
ptr_two = (int *)malloc(sizeof(int));
*ptr_one = 25;
*ptr_two = 24;
g = 130;
free(ptr_two);
g = 210;
*ptr_two = 50;
I want to know how can I trace specific variables / memory references in my program . for example on the above code, I like to trace the variable "g" in my program with Intel Pin, how it can be done?
for dynamically allocated variables, I'm monitoring malloc/free calls & follow their addresses, but for static ones I do not have any idea .
Another matter is, for dynamically allocated variables, I like to trace them across the whole program, suppose in the above code, I want to monitor (ptr_two) variable changes and modification during my program from start to finish .
If anyone have some idea about that, it can be nice to share it here, sample codes appreciated in Intel Pin .
thank you all .
Simply stated, you can't associate a name from your source code (be it variable or function name) with a memory location on the compiled binary: this information is (probably) lost on the final binary.
This is not true in two cases:
1) If your binary is exporting functions: in this case other binaries must have a means to call the function by name (minus some subtleties), in which case the information must be available somewhere; for example on Windows, binaries that export functions, variables or classes have an export table.
2) You have symbolic information: in your example, either for the global variable or other local variable, you have to use the symbolic information provided by the compiler.
On Linux you will need an external tool / library / program (e.g. libelf.so or libdwarf.so) to parse the symbolic information from the symbol tables (usually dynsym / symtab) if the binary is not stripped.
On windows you have to rely on the program database (*.pdb files); the format is mostly undocumented (although MS is trying to document it) and you have to use either the DbgHelp API or the DIA SDK.
As stated by the PIN user guide (emphasis is mine):
Pin provides access to function names using the symbol object (SYM).
Symbol objects only provide information about the function symbols in
the application. Information about other types of symbols (e.g. data
symbols), must be obtained independently by the tool.
If you have symbolic information you can then associate a variable name - obtained from an external tool - with an address (relative to the module base for global vars or a stack location for local ones). At runtime it is then just a matter of converting the relative address to a virtual one.

FAKE Fsc task is writing build products to wrong directory

I'm just learning F#, and setting up a FAKE build harness for a hello-world-like application. (Though the phrase "Hell world" does occasionally come to mind... :-) I'm using a Mac and emacs (generally trying to avoid GUI IDEs by preference).
After a bit of fiddling about with documentation, here's how I'm invoking the F# compiler via FAKE:
let buildDir = #"./build-app/" // Where application build products go
Target "CompileApp" (fun _ -> // Compile application source code
!! #"src/app/**/*.fs" // Look for F# source files
|> Seq.toList // Convert FileIncludes to string list
|> Fsc (fun p -> // which is what the Fsc task wants
{p with //
FscTarget = Exe //
Platform = AnyCpu //
Output = (buildDir + "hello-fsharp.exe") }) // *** Writing to . instead of buildDir?
) //
That uses !! to make a FileIncludes of all the sources in the usual way, then uses Seq.toList to change that to a string list of filenames, which is then handed off to the Fsc task. Simple enough, and it even seems to work:
...
Starting Target: CompileApp (==> SetVersions)
FSC with args:[|"-o"; "./build-app/hello-fsharp.exe"; "--target:exe"; "--platform:anycpu";
"/Users/sgr/Documents/laboratory/hello-fsharp/src/app/hello-fsharp.fs"|]
Finished Target: CompileApp
...
However, despite what the console output above says, the actual build products go to the top-level directory, not the build directory. The message above looks like the -o argument is being passed to the compiler with an appropriate filename, but the executable gets put in . instead of ./build-app/.
So, 2 questions:
Is this a reasonable way to be invoking the F# compiler in a FAKE build harness?
What am I misunderstanding that is causing the build products to go to the wrong place?
This, or a very similar problem, was reported in FAKE issue #521 and seems to have been fixed in FAKE pull request #601, which see.
Explanation of the Problem
As is apparently well-known to everyone but me, the F# compiler as implemented in FSharp.Compiler.Service has a practice of skipping its first argument. See FSharp.Compiler.Service/tests/service/FscTests.fs around line 127, where we see the following nicely informative comment:
// fsc parser skips the first argument by default;
// perhaps this shouldn't happen in library code.
Whether it should or should not happen, it's what does happen. Since the -o came first in the arguments generated by FscHelper, it was dutifully ignored (along with its argument, apparently). Thus the assembly went to the default place, not the place specified.
Solutions
The temporary workaround was to specify --out:destinationFile in the OtherParams field of the FscParams setter in addition to the Output field; the latter is the sacrificial lamb to be ignored while the former gets the job done.
The longer term solution is to fix the arguments generated by FscHelper to have an extra throwaway argument at the front; then these 2 problems will annihilate in a puff of greasy black smoke. (It's kind of balletic in its beauty, when you think about it.) This is exactly what was just merged into the master by #forki23:
// Always prepend "fsc.exe" since fsc compiler skips the first argument
let optsArr = Array.append [|"fsc.exe"|] optsArr
So that solution should be in the newest version of FAKE (3.11.0).
The answers to my 2 questions are thus:
Yes, this appears to be a reasonable way to invoke the F# compiler.
I didn't misunderstand anything; it was just a bug and a fix is in the pipeline.
More to the point: the actual misunderstanding was that I should have checked the FAKE issues and pull requests to see if anybody else had reported this sort of thing, and that's what I'll do next time.

Strange "inaccessible value" in debugger

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'.

Resources