Exemple #1
0
        public EventThreadView()
        {
            InitializeComponent();

            ThreadToolsPanel.Visibility = Visibility.Collapsed;

            foreach (CallStackReason reason in Enum.GetValues(typeof(CallStackReason)))
            {
                CallstackFilter.Add(new CallstackFilterItem()
                {
                    IsChecked = true, Reason = reason
                });
            }
            CallstackFilterPopup.DataContext = CallstackFilter;

            ThreadViewControl.OnShowPopup += OnShowPopup;
        }
    static void Main(string[] args)
    {
        List <Callstack>    stacks;
        List <CallTreeNode> callTreeRoots;

        CallstackFilter filter = delegate(CallstackKey key)
        {
            // This function can be used to remove functions that you think are unrelated to the leak.
            // Example:
            //  if (key.Contains("FunctionWithBalancedAddRefsAndReleases"))
            //      return false;

            return(true);
        };

        TracepointAnalysis.MaxCallstackDepth = 50;

        TracepointAnalysis.ReadFile(@"C:\Users\greggm\Desktop\leakdiag.txt", filter, out stacks, out callTreeRoots);

        TracepointAnalysis.ComputeAddRefReleaseDeltas(callTreeRoots);

        int       totalDelta    = callTreeRoots[0].Function.DeltaValue + callTreeRoots[1].Function.DeltaValue;
        const int expectedDelta = 2;

        if (totalDelta != expectedDelta)
        {
            if (totalDelta <= 0)
            {
                Console.WriteLine("AddRef/Release problem went away");
            }
            else
            {
                Console.WriteLine("AddRef/Release problem is bigger than expected");
            }

            return;
        }

        CallstackFunction.DumpFunctionsWithDelta(2);
        DumpStacks(stacks);
        //DumpCallTree(callTreeRoots);
    }
Exemple #3
0
    /// <summary>
    /// Reads in a file that contains the text from the debugger's output window and analyises the tracepoint callstacks
    /// </summary>
    /// <param name="path">Path to a file containing the saved output window text</param>
    /// <param name="filter">Optional delegate to filter out callstacks that are uninteresting</param>
    /// <param name="stacks">Returns a list of all the callstacks in the output with their hit count</param>
    /// <param name="callTreeRoots">Returns the roots of the tracepoint call trees</param>
    static public void ReadFile(string path, CallstackFilter filter, out List <Callstack> stacks, out List <CallTreeNode> callTreeRoots)
    {
        int currentLine     = 0;
        int currentRefCount = 0;

        Dictionary <CallstackFunction, CallTreeNode> callTreeRootMap = new Dictionary <CallstackFunction, CallTreeNode>();
        Dictionary <CallstackKey, Callstack>         callstackMap    = new Dictionary <CallstackKey, Callstack>();

        stacks = new List <Callstack>();

        StreamReader inputFile = File.OpenText(path);

        List <string> currentCallstack         = null;
        Regex         callstackStartLineFormat = new Regex(@"[0-9]+\:\ ?\t.+(\.dll|\.exe)\!.+");

        while (!inputFile.EndOfStream)
        {
            currentLine++;
            string line = inputFile.ReadLine();

            if (currentCallstack == null)
            {
                Match match = callstackStartLineFormat.Match(line);

                if (match.Success && match.Index == 0)
                {
                    string s = line.Substring(line.IndexOf('\t') + 1).Trim();

                    //Additional code to validate the debug output. Useful when figuring out why a
                    //call stack may have gotten dropped.
                    string refcountStr = line.Substring(0, line.IndexOf(':'));
                    int    newRefCount = int.Parse(refcountStr);

                    // mscordbi - ignore the 'InterlockedCompareExchange frame'
                    if (inputFile.EndOfStream)
                    {
                        Debugger.Break();
                    }
                    currentLine++;
                    line = inputFile.ReadLine();
                    s    = line.Substring(line.IndexOf('\t') + 1).Trim();

                    // Is an AddRef frame?
                    if (s.EndsWith("::AddRef") || s.Contains("InterlockedIncrement"))
                    {
                        if (newRefCount != currentRefCount + 1)
                        {
                            //Debugger.Break();
                        }
                        currentRefCount++;
                    }
                    // Is a release frame?
                    else if (s.EndsWith("::Release") || s.Contains("InterlockedDecrement"))
                    {
                        if (newRefCount != currentRefCount - 1)
                        {
                            //Debugger.Break();
                        }
                        currentRefCount--;
                    }
                    else
                    {
                        Debugger.Break();
                    }

                    // Create a new call stack
                    currentCallstack = new List <string>();
                    currentCallstack.Add(s);
                    currentRefCount = newRefCount;
                }
            }
            else
            {
                if (IsOnlyWhiteSpace(line))
                {
                    CallstackFunction[] frames = CallstackFunction.GetObjects(currentCallstack);
                    CallstackKey        key    = new CallstackKey(frames);

                    if (filter == null || filter(key))
                    {
                        Callstack.AddCallstack(stacks, callstackMap, key);
                        CallTreeNode.AddCallstack(callTreeRootMap, key);
                    }

                    currentCallstack = null;
                }
                else if (line.Length > 1 && line[0] == '\t')
                {
                    string s = line.Substring(1);

                    currentCallstack.Add(s);
                }
            }
        }

        callTreeRoots = new List <CallTreeNode>(callTreeRootMap.Values);
    }