In the picture below I'm on a breakpoint looping through the (196) elements of a TStrings. The current index is 193.
The Visualizer only shows 17 elements.
Can anything be done about that (other than specifically inspecting element 'x')?
In the picture below I'm on a breakpoint looping through the (196) elements of a TStrings. The current index is 193.
The Visualizer only shows 17 elements.
Can anything be done about that (other than specifically inspecting element 'x')?
As far as I can tell, there's not much that you can do about this, short of submitting a feature request (and upgrading if it succeeds). My guess it that's what's being truncated, like WarrenP implied, is the size of the data being fed to the visualizer, rather than the particular number of lines in the TStrings object. This is why I think that:
Assuming XE2 comes with the same sample debugger visualizers as later XE versions, you could try this:
Uninstall the Embarcadero Sample Visualizers package if you have it installed in the IDE.
Copy the StringListVisualizer.Pas unit to somewhere convenient.
Create a new .Dpk project and add the copied StringListVisualizer.Pas to its Contains list; its Requires list should include Rtl and DesignIDE.
Open the copied StringListVisualizer.Pas and locate the routine
function TStringListViewerFrame.Evaluate(Expression: string): string;
You'll see that its local vars include
ResultStr: array[0..4095] of Char;
Change the 4095 to 32767. The point of doing this is to make sure that the the Strings Visualizer display isn't truncated because of the size of this buffer, in light of WarrenP's comment. In fact the truncation that's causing your problem is seemingly elsewhere.
In StringListVisualizer.Pas, put debugger breakpoints on the lines
case EvalRes of
and
if not FDeferredError then
in function TStringListViewerFrame.Evaluate(Expression: string): string
.
You need 2 breakpoints because there are two ways Evaluate
can complete,
depending on the value of EvalRes. It always returns erDeferred for me.
Compile and run your Dpk project. It will invoke a second instance of the IDE.
In the second instance, load and run your problem project. When your breakpoint in that trips, right-click in the Watches window and go to Visualizers | Show Strings.
Shortly one or other of your breakpoints in StringListVisualizer.Pas will trip evaluating the strings property that's giving you trouble (it may trip on several other expressions to evaluate first. When it does, single step to where the result of function TStringListViewerFrame.Evaluate is assigned, then evaluate
Length(Result)
and
Copy(Result, Length(Result) - 100, Length(Result))
Using my test data, I get a value for Length(Result) which is 4101, and the Copy evaluates to the last part of the strings .text, just before its display in the visualizer gets truncated.
It seems fairly clear from those results (in my case at least, ymmv) that the data truncation occurs somewhere in the debugger machinery that feeds the visualizer rather than in the visualizer itself. Somebody who knows more about the debugger internals than me may be able to suggest another way of getting untruncated data to be fed to the visualizer.
Update: A couple of thoughts:
A work-around for the apparent "4k" truncation of what's available to a visualizer might be to link into the app being debugged a function, let's call it TStringsPagedWindow(Input : TStsrings; Page : Integer) : String
which returns a section of a TStrings object hopefully working around the "4k" limitation, at the expense of needing to watch it, rather than the TStrings object per se, in the Watch Window, and specify the Page value. Obviously this would not be wildly convenient, and would require the TStringsPagedWindow
function to be linked into the executable being debugged.
Following on from 1., seeing as a debugger visualizer can apparently evaluate any valid expression, one could envisage constructing (in the visualizer) an expression based on the name of the TStrings variable being watched and invoking TStringsPagedWindow
automatically to populate a GUI object that could display its contents. This is the closest I can think of at the moment to WarrenP's suggestion "Since you can write your own visualizers, it is possible you could add such arrows, and use a different control to show the contents. " Maybe quite a lot of work, but my idea of fun; perhaps I'll have a go if there's any interest.