[fpc-pascal] FpDebug hands-on: AnsiStrings

Martin Frb lazarus at mfriebe.de
Thu May 21 18:25:42 CEST 2020

On 21/05/2020 17:29, Joost van der Sluis wrote:
> I've added codepage-support for ansistrings, compiled with -gw3. This 
> is done in the TFpValueDwarfV3FreePascalString class, which does the 
> heavy work regarding the formatting of strings. Although there is also 
> some code in TFpDebugDebugger.EvaluateExpression and probably other 
> places that change the formatting of string-values.
> So I've made my change in TFpValueDwarfV3FreePascalString, but I don't 
> know if this is the right place. After all, it is about formatting, 
> and this class is related to the Dwarf-debug info. On the other hand. 
> I do understand why this logic in implemented here. This is *the* 
> place where all the relevant information is present.
> But that the design is problematic can be seen in a comment in the file:
>   // TODO: XXXXX Dynamic max limit
This is not really about formatting. A corrupt debug target, could 
return a string length of 2^31, not something that the debugger should 
attempt to read. (newer gdb have similar options, if the data is to 
large they return nothing / for strings we can do better and get the start)
That can happen when reading locals before the stackframe is set up.

Part 2 is formatting related....  In most cases the user does not need a 
10kb string, the user may want offset 1500 len 500. Ideally then the 
debugger only reads that part. That part may move to the formatter. But 
also may need an extension to target reading the correct subset of the data.

Currently config for FpDebug does not exist. It needs to be integrated 
with the config for LazDebuggerFp (i.e. use TDebuggerProperties so it 
can be streamed). Yet separated from config that is only for LazDebuggerFp.
That is why the value is hardcoded.
I want to avoid having to copy all the values in from LazDebuggers 
config to FpDebug config (which happens now for the 2 configs avail)

max memory limits can be passed via TFpDbgMemReader = class(TDbgMemReader)
TDbgMemReader could have a property that can be read by the dwarf classes.

> This seems an easy task, but it is not. 
> TFpValueDwarfV3FreePascalString is not bound to the GUI or does not 
> have formatting-settings. But it is the place where the formatting 
> takes place! But adding a formatting-setting (like a max-length for 
> strings) at this location would be really strange.
Well the current code (your commit) does not do formatting.
It adds the info to the string.

The formatter, getting the longstring, can read the codepage from it. 
The formatter can also read the string byte by byte.

  SetCodePage(RResult, Codepage, False);
Does not change the raw data in the string (only the meaning it has).
As long as it does not accidentally get converted while being passed around.

> I see two solutions: Besides the AsString property we could add a 
> GetAsString procedure with some parameters on how to format the 
> string. Maybe the easiest at this moment, and this morning I though it 
> was a good idea. (Note that I want to add more stuff, like function to 
> retrieve the code-page, and the raw-data)
If needed I would rather add the 2 new functions. Though it seems the 
data is actually returned as part of the longstring?

If you need individual calls to retrieve that info, it could be done by 
something like GetMember.
GetMember has to much overhead. as it returns a big object.

But something like
    GetDataProperty(AnPropId: Integer): Pointer;
would be generic enough to return any additional data.
(yes ID is integer. quicker to much than doing string compare)

Or you add dedicated properties to TFpValueDwarfV3FreePascalString and 
use type casting.  *** For starters, I would go with that, and later 

I am not sure about adding to many methods to for up the hierarchy, and 
needing meaningless defaults for them.

More information about the fpc-pascal mailing list