I have an array of structs stores as pointer + length and would like to print a deep field of each.
I can do it using .for
and temporary registers:
.for (r $t0 = 0; @$t0 < @@c++(length); r $t0 = @$t0 + 1) { dx pointer[@$t0].a.b.c }
Is there some nicer way to do it using dx
expressions? I know they have some LINQ capabilities, because they are described at MSDN and I can for example run:
dx Debugger.Utility.FileSystem.CurrentDirectory.Files.Select(x => x.Extension)
I am looking for an equivalent code for C/C++ objects, something like:
dx array(pointer, length).Select(x => x.a.b.c)
Having to write a small JS extension which works genetically and can be invoked with arbitrary pointer, size and lambda would also be an acceptable answer.
The LINQ methods are projected onto anything which is iterable (either naturally like an array or via an attached data model (e.g.: NatVis, JS, etc...) which supports the iterable concept). The dx evaluator supports casting to array types. You can easily do something like:
dx ((TYPE[SIZE])pointer).Select(...)
For instance:
0:000> dx ((int[5])@rip).Select(x => x < 0)
((int[5])@rip).Select(x => x < 0)
[0] : false
[1] : true
[2] : true
[3] : false
[4] : false
If you need to programmatically control the size (e.g.: it's not constant), you can write a short JavaScript function which does this. For example:
"use strict";
class __CollectionsExtension
{
PointerToArray(ptr, size)
{
if (ptr.targetType === undefined || ptr.targetType.typeKind != "pointer")
{
throw new Error("Invalid argument: must provide a pointer");
}
var baseType = ptr.targetType.baseType;
return host.createTypedObject(ptr.address, baseType.createArrayOf([new host.typeSystem.arrayDimension(0, size, baseType.size)]));
}
}
function initializeScript()
{
return [new host.apiVersionSupport(1, 9),
new host.namedModelParent(__CollectionsExtension, "Debugger.Models.Utility.Collections")];
}
The above script will add a method called PointerToArray onto Debugger.Utility.Collections. You could then do something like:
0:000> dx Debugger.Utility.Collections.PointerToArray((int *)@rip, @rax + 2)
Debugger.Utility.Collections.PointerToArray((int *)@rip, @rax + 2) [Type: int [2]]
[0] : 1208019916 [Type: int]
[1] : -1019689853 [Type: int]
Hope that helps...