Skip to content

Commit 71f43ce

Browse files
committed
Add stack tracing and make a big mess of WeakComSafe - need to be refactored
1 parent 20d8a4e commit 71f43ce

File tree

1 file changed

+40
-4
lines changed

1 file changed

+40
-4
lines changed

Rubberduck.VBEEditor/ComManagement/WeakComSafe.cs

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
using System;
22
using System.Collections.Concurrent;
3+
using System.Collections.Generic;
34
using System.Runtime.CompilerServices;
45
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
56

67
#if DEBUG
8+
using System.Diagnostics;
79
using System.Linq;
810
using System.Runtime.InteropServices;
911
#endif
@@ -15,14 +17,27 @@ public class WeakComSafe : IComSafe
1517
//We use weak references to allow the GC to reclaim RCWs earlier if possible.
1618
private readonly ConcurrentDictionary<int, (DateTime insertTime, WeakReference<ISafeComWrapper> weakRef)> _comWrapperCache = new ConcurrentDictionary<int, (DateTime, WeakReference<ISafeComWrapper>)>();
1719

20+
#if DEBUG
21+
private IEnumerable<string> trace = null;
22+
#endif
23+
1824
public void Add(ISafeComWrapper comWrapper)
1925
{
2026
if (comWrapper != null)
2127
{
28+
#if DEBUG
29+
trace = GetStackTrace(3, 3);
30+
#endif
2231
_comWrapperCache.AddOrUpdate(
2332
GetComWrapperObjectHashCode(comWrapper),
2433
key => (DateTime.UtcNow, new WeakReference<ISafeComWrapper>(comWrapper)),
25-
(key, value) => (value.insertTime, new WeakReference<ISafeComWrapper>(comWrapper)));
34+
(key, value) =>
35+
{
36+
#if DEBUG
37+
Debug.Assert(false);
38+
#endif
39+
return (value.insertTime, new WeakReference<ISafeComWrapper>(comWrapper));
40+
});
2641
}
2742

2843
}
@@ -71,18 +86,39 @@ public void Serialize()
7186
{
7287
using (var stream = System.IO.File.AppendText($"comSafeOutput {DateTime.UtcNow:yyyyMMddhhmmss}.csv"))
7388
{
74-
stream.WriteLine("Ordinal\tKey\tCOM Wrapper Type\tWrapping Null?\tIUnknown Pointer Address");
89+
stream.WriteLine("Ordinal\tKey\tCOM Wrapper Type\tWrapping Null?\tIUnknown Pointer Address\tLevel 1\tLevel 2\tLevel 3");
7590
var i = 0;
7691
foreach (var kvp in _comWrapperCache.OrderBy(kvp => kvp.Value.insertTime))
7792
{
7893
var line = kvp.Value.weakRef.TryGetTarget(out var target)
79-
? $"{i++}\t{kvp.Key}\t\"{target.GetType().FullName}\"\t\"{target.IsWrappingNullReference}\"\t\"{(target.IsWrappingNullReference ? "null" : GetPtrAddress(target.Target))}\""
80-
: $"{i++}\t{kvp.Key}\t\"null\"\t\"null\"\t\"null\"";
94+
? $"{i++}\t{kvp.Key}\t\"{target.GetType().FullName}\"\t\"{target.IsWrappingNullReference}\"\t\"{(target.IsWrappingNullReference ? "null" : GetPtrAddress(target.Target))}\"\t\"{string.Join("\"\t\"", trace)}\""
95+
: $"{i++}\t{kvp.Key}\t\"null\"\t\"null\"\t\"null\"\t\"{string.Join("\"\t\"", trace)}\"";
8196
stream.WriteLine(line);
8297
}
8398
}
8499
}
85100

101+
private static IEnumerable<string> GetStackTrace(int frames, int offset)
102+
{
103+
var list = new List<string>();
104+
var trace = new StackTrace();
105+
if ((trace.FrameCount - offset) < frames)
106+
{
107+
frames = (trace.FrameCount - offset);
108+
}
109+
110+
for (var i = 1; i <= frames; i++)
111+
{
112+
var frame = trace.GetFrame(i + offset);
113+
var typeName = frame.GetMethod().DeclaringType?.FullName ?? string.Empty;
114+
var methodName = frame.GetMethod().Name;
115+
116+
var qualifiedName = $"{typeName}{(typeName.Length > 0 ? "::" : string.Empty)}{methodName}";
117+
list.Add(qualifiedName);
118+
}
119+
return list;
120+
}
121+
86122
private static string GetPtrAddress(object target)
87123
{
88124
if (target == null)

0 commit comments

Comments
 (0)