Field values using API

Use this forum for questions on how to use .NET Memory Profiler and how to analyse memory usage.

Moderator: SciTech Software

Field values using API

Postby 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

Postby 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.
momono
 
Posts: 2
Joined: Thu Jun 23, 2016 2:55 pm

Re: Field values using API

Postby 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
Andreas Suurkuusk
 
Posts: 963
Joined: Wed Mar 02, 2005 7:53 pm
Location: Sweden


Return to Using .NET Memory Profiler

Who is online

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

SciTech Software logo

© Copyright 2001-2016. SciTech Software AB
All rights reserved.


SciTech Software AB
Kartvägen 21
SE-175 46 Järfälla
Sweden


E-mail: mail@scitech.se

Telephone: +46-706868081

cron