Field values using API

Use this forum for questions on how to use .NET Memory Profiler and how to analyse memory usage.
Post Reply
momono
Posts: 2
Joined: Thu Jun 23, 2016 2:55 pm

Field values using API

Post by momono » Thu Jun 23, 2016 3:09 pm

Hi,

I'm trying to get values for objects from API. My intend is to rebuild the object from data that are availble in dump.
I've retrieved TypeInstance using comparison.GetTypeInstance(instanceId) but it returns only reference fields on GetReferencesAndFields(ReferencesOption.Default) call. I require to get all fields and their values (even for value types). But I can't find any method to retrieve value types fields and their values.
I'm using version 5.0.142

Thanks for help.

Edit:
For me it would be also sufficient to get all instances of type in FE and export them to file like string values. I need to confirm that some instance of type with certain value was in memory.

momono
Posts: 2
Joined: Thu Jun 23, 2016 2:55 pm

Re: Field values using API

Post by momono » Fri Jun 24, 2016 1:43 pm

I was able to identify correct instance by traversing all instance of type and checking for id. Id is type of YourType. You have to know its size and position so it make some time to find.In my case its struct holding long.
First four bytes in GetInstanceData seems to contain instanceId or whatever which is not related to actual data.

Code: Select all

TypeInstance instance = comparison.GetTypeInstance(instanceId);
var arrBytes = instance.GetInstanceData();
var eightBytesPtr = Marshal.AllocHGlobal(8);
Marshal.Copy(arrBytes, 4, eightBytesPtr, 8);
YourType id = (YourType)Marshal.PtrToStructure(eightBytesPtr, typeof(YourType));
Marshal.FreeHGlobal(eightBytesPtr);
So this showed me right instance and now I can work in profiler normally by filtering instance id.

Andreas Suurkuusk
Posts: 1000
Joined: Wed Mar 02, 2005 7:53 pm

Re: Field values using API

Post by Andreas Suurkuusk » Mon Jun 27, 2016 4:21 pm

There is a helper class named SciTech.Profiler.InstanceDataRetriever that can be used to parse the instance data of an instance in a profiler snapshot. The example code below shows how field information can be retrieved.

Code: Select all

var retriever = new InstanceDataRetriever(comparison);

int maxFields = 1000;
RetrievedFieldDataCollection fields = retriever.RetrieveFields(instanceId, maxFields);

if( fields.HasMissingFields )
{
    // Fields may be missing under some circumstances, e.g. uninitialized nested value types.
    Console.WriteLine("One or more fields are missing in the collection.");
}

if( fields.IsTruncated)
{
    // Arrays and strings may be truncated if the number of items exceeds maxFields
    Console.WriteLine("Fields collection is truncated.");
}

foreach( var field in fields )
{
    Console.WriteLine($"{field.Field.Name}: {field.Value}");
    if( field.Value is TypeInstanceId )
    {
        Console.WriteLine("  Field is a reference field.");
    }

    if( field.SubFields.Count > 0 )
    {
        Console.WriteLine("  Instance has nested value type fields.");
    }
}
Using PtrToStructure to retrieve instance data is not safe, since the instance data layout is often different from the .NET marshalling layout. However, the fields information retrieved by InstanceDataRetriever is more suitable for presentation than programmatic analysis. I will try to write an sample that uses the InstanceDataRetriever to unmarshal the instance data to an actual instance of the type, similar to the PtrToStructure method.
Best regards,

Andreas Suurkuusk
SciTech Software AB

Post Reply

Who is online

Users browsing this forum: Google [Bot] and 3 guests