Reading IntelliTrace files (.iTrace)

by ingvar 2. november 2010 12:07

IntelliTrace is a really cool new feature in Visual Studio 2010. This feature gives you a lot of information that was not available before, like file I/O. But if you enable IntelliTrace and the file event, then you pretty quickly end up with a huge amount of events to look through in the IDE. But there is a pretty nice API for reading .iTrace files, so data mining these huge files is pretty easy.

Here is a rather simple method that reads the .iTrace file and goes through all diagnostic events, prints its category id and the stack trace including module name.

IntelliTraceFile file = new IntelliTraceFile("Sample.iTrace");

foreach (IntelliTraceProcess process in file.Processes)
{
    DiagnosticStreamChain chain = process.CreateProcessChain<DiagnosticStreamChain>();

    EventToken eventToken = chain.FirstValidToken;
    while (eventToken != chain.AfterLastToken)
    {
        IntelliTraceEvent intelliTraceEvent = chain.GetEvent(eventToken);

        DiagnosticEvent traceEvent = intelliTraceEvent as DiagnosticEvent;
        if (traceEvent != null)
        {
            ResolvedDiagnosticEvent diagnosticEvent =
                new ResolvedDiagnosticEvent(process, traceEvent);                       

            Console.WriteLine("Event: " + diagnosticEvent.CategoryId);

            var stackFrames = diagnosticEvent.DiagnosticEvent.StackFrames.Reverse();
            foreach (IntelliTraceStackFrame traceStackFrame in stackFrames)
            {
                ResolvedStackFrame stackFrame =
                    new ResolvedStackFrame(process, traceStackFrame);

                IntelliTraceModule module =
                    process.Modules.
                    Where(f => f.Mvid == stackFrame.Module.Mvid).
                    SingleOrDefault();

                string parameterNames = "";
                foreach (string parameterName in stackFrame.Method.ParameterNames)
                {
                    if (parameterNames.Length > 0)
                    {
                        parameterNames += ", ";
                    }

                    parameterNames += parameterName;
                }

                string stackFramePrint =
                    stackFrame.Method.ContainingTypeName + "." +
                    stackFrame.Method.MethodName + "(" + parameterNames + ")";

                if (module != null)
                {
                    stackFramePrint += " @ " + Path.GetFileName(module.FileName);
                }

                Console.WriteLine(stackFramePrint);
            }                        
        }

        eventToken = chain.GetNextToken(eventToken);
    }
}

I have not looked through all different data related to a diagnostic event (DiagnosticEvent.DataBytes). But here is an example of how to get the file name of the file that has been touched in a “file.access” diagnostic event.

if (diagnosticEvent.CategoryId == "file.access")
{
    UnicodeEncoding enc = new UnicodeEncoding();
    string filename = enc.GetString(diagnosticEvent.DiagnosticEvent.DataBytes.Skip(5).ToArray());
}

Tags:

.NET | C#

About the author

Martin Ingvar Kofoed Jensen

Architect and Senior Developer at Composite on the open source project Composite C1 - C#/4.0, LINQ, Azure, Parallel and much more!

Follow me on Twitter

Read more about me here.

Read press and buzz about my work and me here.

Stack Overflow

Month List