コード例 #1
0
 private void RegisterDeallocation(UIntPtr address)
 {
     lock (this)
     {
         if (tmpEvents == null)
         {
             return;
         }
         var ev = new DeallocateEvent(address);
         tmpEvents.Add(ev);
     }
 }
コード例 #2
0
ファイル: HeapAgent.cs プロジェクト: SayHalou/ospy
 private void RegisterDeallocation(UIntPtr address)
 {
     lock (this)
     {
         if (tmpEvents == null)
             return;
         var ev = new DeallocateEvent(address);
         tmpEvents.Add(ev);
     }
 }
コード例 #3
0
        private void ProcessAllocations()
        {
            List <HeapEvent> events = null;

            lock (this)
            {
                if (lastFrameEvents == null)
                {
                    return;
                }
                events          = lastFrameEvents;
                lastFrameEvents = null;
            }

            int allocCount   = 0;
            int allocSize    = 0;
            int deallocCount = 0;

            Dictionary <int, int> countForSize = new Dictionary <int, int>();

            foreach (HeapEvent ev in events)
            {
                // for now
                if (ev is DeallocateEvent)
                {
                    deallocCount++;
                    continue;
                }

                int size = 0;
                if (ev is AllocateEvent)
                {
                    AllocateEvent allocEv = ev as AllocateEvent;
                    size = allocEv.Size;
                }
                else if (ev is ReallocateEvent)
                {
                    ReallocateEvent reallocEv = ev as ReallocateEvent;
                    size = reallocEv.Size;
                }
                else
                {
                    throw new NotImplementedException();
                }

                int oldCount = 0;
                countForSize.TryGetValue(size, out oldCount);
                countForSize[size] = oldCount + 1;

                allocCount++;
                allocSize += size;
            }

            StringBuilder sb = new StringBuilder();

            sb.AppendLine();
            sb.AppendFormat("{0} allocations ({1} bytes), {2} deallocations\r\n",
                            allocCount, allocSize, deallocCount);
            sb.AppendLine();

            sb.AppendLine("  Size  |  Count");
            sb.AppendLine("------------------");
            int[] sizes = countForSize.Keys.ToArray();
            Array.Sort(sizes);
            Array.Reverse(sizes);
            foreach (int size in sizes)
            {
                sb.AppendFormat("{0,7} | {1}\r\n", size, countForSize[size]);
            }

            sb.AppendLine();

            sb.AppendLine("Events:");
            sb.AppendLine("-------");
            int count = 0;

            foreach (HeapEvent ev in events)
            {
                sb.AppendLine(ev.ToString());

                count++;

                if (enableEntryLimit && count >= 100)
                {
                    break;
                }
            }

            if (enableEntryLimit)
            {
                int remaining = events.Count - count;
                if (remaining > 0)
                {
                    sb.AppendFormat("...and {0} more...\r\n", remaining);
                }
            }

            List <HeapEvent> leakedEvents = new List <HeapEvent>();

            foreach (HeapEvent ev in events)
            {
                UIntPtr removePtr = UIntPtr.Zero;

                if (ev is AllocateEvent)
                {
                    AllocateEvent allocEv = ev as AllocateEvent;
                    if (allocEv.Address != UIntPtr.Zero)
                    {
                        leakedEvents.Add(allocEv);
                    }
                }
                else if (ev is ReallocateEvent)
                {
                    ReallocateEvent reallocEv = ev as ReallocateEvent;
                    if (reallocEv.NewAddress != UIntPtr.Zero)
                    {
                        if (reallocEv.OldAddress != UIntPtr.Zero)
                        {
                            if (reallocEv.NewAddress == reallocEv.OldAddress)
                            {
                                // no change
                                // FIXME: in case we missed the original malloc we could get it here...
                            }
                            else
                            {
                                // relocated
                                leakedEvents.Add(reallocEv);
                                removePtr = reallocEv.OldAddress;
                            }
                        }
                        else
                        {
                            // new event
                            leakedEvents.Add(reallocEv);
                        }
                    }
                    else if (reallocEv.OldAddress != UIntPtr.Zero && reallocEv.Size == 0)
                    {
                        // free
                        removePtr = reallocEv.OldAddress;
                    }
                }
                else if (ev is DeallocateEvent)
                {
                    DeallocateEvent deallocEv = ev as DeallocateEvent;
                    removePtr = deallocEv.Address;
                }
                else
                {
                    throw new NotImplementedException();
                }

                if (removePtr != UIntPtr.Zero)
                {
                    bool again = false;

                    do
                    {
                        again = false;

                        foreach (HeapEvent leakEv in leakedEvents)
                        {
                            UIntPtr address;

                            if (leakEv is AllocateEvent)
                            {
                                address = (leakEv as AllocateEvent).Address;
                            }
                            else if (leakEv is ReallocateEvent)
                            {
                                address = (leakEv as ReallocateEvent).NewAddress;
                            }
                            else
                            {
                                throw new NotImplementedException("Should not get here");
                            }

                            if (address == removePtr)
                            {
                                leakedEvents.Remove(leakEv);
                                again = true;
                                break;
                            }
                        }
                    }while (again);
                }
            }

            if (leakedEvents.Count > 0)
            {
                sb.AppendLine();
                sb.AppendLine("Possible leaks:");
                sb.AppendLine("---------------");
                foreach (HeapEvent ev in leakedEvents)
                {
                    sb.AppendLine(ev.ToString());
                }
            }

            Event.InvocationOrigin origin = new Event.InvocationOrigin("HeapAgent", null, 42);
            PacketEvent            pktEv  = new PacketEvent(eventCoordinator, origin);

            pktEv.Data = Encoding.UTF8.GetBytes(sb.ToString());
            manager.Submit(new Event[] { pktEv });
        }