[KOE-130] Added wrapper tracing feature

This commit is contained in:
Patrick Simpson 2017-07-05 12:12:43 +02:00
parent 879a10bef8
commit 59ad301b03
10 changed files with 947 additions and 97 deletions

View File

@ -388,6 +388,9 @@
<Compile Include="UI\Outlook\MenuItem.cs" />
<Compile Include="UI\Outlook\Types.cs" />
<Compile Include="Utils\CompletionTracker.cs" />
<Compile Include="Utils\DisposableTracer.cs" />
<Compile Include="Utils\DisposableTracerDummy.cs" />
<Compile Include="Utils\DisposableTracerFull.cs" />
<Compile Include="Utils\DisposableWrapper.cs" />
<Compile Include="Utils\ImageUtils.cs" />
<Compile Include="Utils\RegistryUtil.cs" />

View File

@ -28,23 +28,58 @@
/// </summary>
private void InitializeComponent()
{
System.Windows.Forms.ColumnHeader columnMethod;
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DebugDialog));
System.Windows.Forms.ColumnHeader columnFile;
System.Windows.Forms.ColumnHeader columnLine;
this.tableMain = new System.Windows.Forms.TableLayoutPanel();
this.flowButtons = new System.Windows.Forms.FlowLayoutPanel();
this.buttonGC = new System.Windows.Forms.Button();
this.buttonRefresh = new System.Windows.Forms.Button();
this.buttonClose = new System.Windows.Forms.Button();
this.buttonLog = new System.Windows.Forms.Button();
this._tabs = new System.Windows.Forms.TabControl();
this._tabProperties = new System.Windows.Forms.TabPage();
this.Properties = new System.Windows.Forms.PropertyGrid();
this._tabWrapperTypes = new System.Windows.Forms.TabPage();
this.listWrapperTypes = new System.Windows.Forms.ListView();
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this._tabWrapperLocations = new System.Windows.Forms.TabPage();
this._layoutLocations = new System.Windows.Forms.TableLayoutPanel();
this.listStackTrace = new System.Windows.Forms.ListView();
this.listWrapperLocations = new System.Windows.Forms.ListView();
this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
columnMethod = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
columnFile = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
columnLine = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.tableMain.SuspendLayout();
this.flowButtons.SuspendLayout();
this._tabs.SuspendLayout();
this._tabProperties.SuspendLayout();
this._tabWrapperTypes.SuspendLayout();
this._tabWrapperLocations.SuspendLayout();
this._layoutLocations.SuspendLayout();
this.SuspendLayout();
//
// columnMethod
//
resources.ApplyResources(columnMethod, "columnMethod");
//
// columnFile
//
resources.ApplyResources(columnFile, "columnFile");
//
// columnLine
//
resources.ApplyResources(columnLine, "columnLine");
//
// tableMain
//
resources.ApplyResources(this.tableMain, "tableMain");
this.tableMain.Controls.Add(this.flowButtons, 0, 1);
this.tableMain.Controls.Add(this.Properties, 0, 0);
this.tableMain.Controls.Add(this._tabs, 0, 0);
this.tableMain.Name = "tableMain";
//
// flowButtons
@ -85,14 +120,109 @@
this.buttonLog.UseVisualStyleBackColor = true;
this.buttonLog.Click += new System.EventHandler(this.buttonLog_Click);
//
// _tabs
//
this._tabs.Controls.Add(this._tabProperties);
this._tabs.Controls.Add(this._tabWrapperTypes);
this._tabs.Controls.Add(this._tabWrapperLocations);
resources.ApplyResources(this._tabs, "_tabs");
this._tabs.Name = "_tabs";
this._tabs.SelectedIndex = 0;
//
// _tabProperties
//
this._tabProperties.Controls.Add(this.Properties);
resources.ApplyResources(this._tabProperties, "_tabProperties");
this._tabProperties.Name = "_tabProperties";
this._tabProperties.UseVisualStyleBackColor = true;
//
// Properties
//
resources.ApplyResources(this.Properties, "Properties");
this.Properties.DisabledItemForeColor = System.Drawing.SystemColors.ControlText;
resources.ApplyResources(this.Properties, "Properties");
this.Properties.Name = "Properties";
this.Properties.PropertySort = System.Windows.Forms.PropertySort.Categorized;
this.Properties.ToolbarVisible = false;
//
// _tabWrapperTypes
//
this._tabWrapperTypes.Controls.Add(this.listWrapperTypes);
resources.ApplyResources(this._tabWrapperTypes, "_tabWrapperTypes");
this._tabWrapperTypes.Name = "_tabWrapperTypes";
this._tabWrapperTypes.UseVisualStyleBackColor = true;
//
// listWrapperTypes
//
this.listWrapperTypes.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader1,
this.columnHeader2});
resources.ApplyResources(this.listWrapperTypes, "listWrapperTypes");
this.listWrapperTypes.Name = "listWrapperTypes";
this.listWrapperTypes.ShowItemToolTips = true;
this.listWrapperTypes.Sorting = System.Windows.Forms.SortOrder.Descending;
this.listWrapperTypes.UseCompatibleStateImageBehavior = false;
this.listWrapperTypes.View = System.Windows.Forms.View.Details;
//
// columnHeader1
//
resources.ApplyResources(this.columnHeader1, "columnHeader1");
//
// columnHeader2
//
resources.ApplyResources(this.columnHeader2, "columnHeader2");
//
// _tabWrapperLocations
//
this._tabWrapperLocations.Controls.Add(this._layoutLocations);
resources.ApplyResources(this._tabWrapperLocations, "_tabWrapperLocations");
this._tabWrapperLocations.Name = "_tabWrapperLocations";
this._tabWrapperLocations.UseVisualStyleBackColor = true;
//
// _layoutLocations
//
resources.ApplyResources(this._layoutLocations, "_layoutLocations");
this._layoutLocations.Controls.Add(this.listStackTrace, 0, 1);
this._layoutLocations.Controls.Add(this.listWrapperLocations, 0, 0);
this._layoutLocations.Name = "_layoutLocations";
//
// listStackTrace
//
this.listStackTrace.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
columnMethod,
columnLine,
columnFile});
resources.ApplyResources(this.listStackTrace, "listStackTrace");
this.listStackTrace.FullRowSelect = true;
this.listStackTrace.MultiSelect = false;
this.listStackTrace.Name = "listStackTrace";
this.listStackTrace.ShowItemToolTips = true;
this.listStackTrace.UseCompatibleStateImageBehavior = false;
this.listStackTrace.View = System.Windows.Forms.View.Details;
//
// listWrapperLocations
//
this.listWrapperLocations.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader3,
this.columnHeader4});
resources.ApplyResources(this.listWrapperLocations, "listWrapperLocations");
this.listWrapperLocations.FullRowSelect = true;
this.listWrapperLocations.HideSelection = false;
this.listWrapperLocations.MultiSelect = false;
this.listWrapperLocations.Name = "listWrapperLocations";
this.listWrapperLocations.ShowItemToolTips = true;
this.listWrapperLocations.Sorting = System.Windows.Forms.SortOrder.Descending;
this.listWrapperLocations.UseCompatibleStateImageBehavior = false;
this.listWrapperLocations.View = System.Windows.Forms.View.Details;
this.listWrapperLocations.SelectedIndexChanged += new System.EventHandler(this.listWrapperLocations_SelectedIndexChanged);
//
// columnHeader3
//
resources.ApplyResources(this.columnHeader3, "columnHeader3");
//
// columnHeader4
//
resources.ApplyResources(this.columnHeader4, "columnHeader4");
//
// DebugDialog
//
resources.ApplyResources(this, "$this");
@ -101,13 +231,16 @@
this.Controls.Add(this.tableMain);
this.MinimizeBox = false;
this.Name = "DebugDialog";
this.ShowInTaskbar = false;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show;
this.TopMost = true;
this.tableMain.ResumeLayout(false);
this.tableMain.PerformLayout();
this.flowButtons.ResumeLayout(false);
this.flowButtons.PerformLayout();
this._tabs.ResumeLayout(false);
this._tabProperties.ResumeLayout(false);
this._tabWrapperTypes.ResumeLayout(false);
this._tabWrapperLocations.ResumeLayout(false);
this._layoutLocations.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
@ -122,5 +255,17 @@
private System.Windows.Forms.Button buttonRefresh;
private System.Windows.Forms.Button buttonClose;
private System.Windows.Forms.Button buttonLog;
private System.Windows.Forms.TabControl _tabs;
private System.Windows.Forms.TabPage _tabProperties;
private System.Windows.Forms.TabPage _tabWrapperTypes;
private System.Windows.Forms.TabPage _tabWrapperLocations;
private System.Windows.Forms.ListView listWrapperTypes;
private System.Windows.Forms.ColumnHeader columnHeader1;
private System.Windows.Forms.ColumnHeader columnHeader2;
private System.Windows.Forms.TableLayoutPanel _layoutLocations;
private System.Windows.Forms.ListView listStackTrace;
private System.Windows.Forms.ListView listWrapperLocations;
private System.Windows.Forms.ColumnHeader columnHeader3;
private System.Windows.Forms.ColumnHeader columnHeader4;
}
}

View File

@ -1,4 +1,4 @@
/// Copyright 2016 Kopano b.v.
/// Copyright 2017 Kopano b.v.
///
/// This program is free software: you can redistribute it and/or modify
/// it under the terms of the GNU Affero General Public License, version 3,
@ -35,18 +35,105 @@ namespace Acacia.Features.DebugSupport
{
public partial class DebugDialog : KopanoDialog
{
private readonly DisposableTracerFull _tracer;
public DebugDialog()
{
InitializeComponent();
Properties.SelectedObject = new DebugInfo();
_tracer = DisposableWrapper.GetTracer();
if (_tracer == null)
{
// If we don't have a wrapper tracer, hide the tabs
_tabs.SizeMode = TabSizeMode.Fixed;
_tabs.ItemSize = new Size(0, 1);
}
else
{
listWrapperTypes.ListViewItemSorter = new WrapperCountSorter();
listWrapperLocations.ListViewItemSorter = new WrapperCountSorter();
RefreshWrappers();
// Make it a bit bigger
Width = Width + 400;
Height = Height + 200;
}
}
private void UpdateFields()
{
Properties.Refresh();
RefreshWrappers();
}
#region Wrappers
private void RefreshWrappers()
{
// Wrapper types
listWrapperTypes.Items.Clear();
foreach(KeyValuePair<Type, int> type in _tracer.GetTypes())
{
string name = type.Key.Name;
if (type.Key.DeclaringType != null)
name = type.Key.DeclaringType.Name + "." + name;
ListViewItem item = new ListViewItem(name);
item.ToolTipText = type.Key.FullName;
item.SubItems.Add(type.Value.ToString());
listWrapperTypes.Items.Add(item);
}
listWrapperTypes.Columns[0].Width = -2;
listWrapperTypes.Columns[1].Width = -2;
// Wrapper locations
listWrapperLocations.Items.Clear();
foreach (KeyValuePair<DisposableTracerFull.CustomTrace, int> entry in _tracer.GetLocations())
{
ListViewItem item = new ListViewItem(entry.Key.DisplayName);
item.SubItems.Add(entry.Value.ToString());
item.Tag = entry.Key;
listWrapperLocations.Items.Add(item);
}
listWrapperLocations.Columns[0].Width = -2;
listWrapperLocations.Columns[1].Width = -2;
}
private class WrapperCountSorter : IComparer
{
public int Compare(object x, object y)
{
int ix = int.Parse(((ListViewItem)x).SubItems[1].Text);
int iy = int.Parse(((ListViewItem)y).SubItems[1].Text);
return iy - ix;
}
}
private void listWrapperLocations_SelectedIndexChanged(object sender, EventArgs e)
{
listStackTrace.Items.Clear();
if (listWrapperLocations.SelectedItems.Count > 0)
{
DisposableTracerFull.CustomTrace trace = (DisposableTracerFull.CustomTrace)listWrapperLocations.SelectedItems[0].Tag;
foreach(DisposableTracerFull.CustomFrame frame in trace.Frames)
{
ListViewItem item = new ListViewItem(frame.MethodName);
item.SubItems.Add(frame.LineNumber.ToString());
item.SubItems.Add(frame.FileName ?? "");
listStackTrace.Items.Add(item);
}
}
foreach (ColumnHeader header in listStackTrace.Columns)
header.Width = -2;
}
#endregion
#region Cycling
private class DebugCycleInfo
{
private int cycleIndex = 0;
@ -108,6 +195,12 @@ namespace Acacia.Features.DebugSupport
private DebugCycleInfo cycle;
/// <summary>
/// Runs the specific number of cycles. In each cycle the GAB is resynced. This is to test
/// memory errors, which show most frequently when using the GAB, as that touches most of
/// the code.
/// </summary>
/// <param name="count">The number of cycles to run</param>
internal void DebugCycle(int count)
{
GAB.FeatureGAB gab = ThisAddIn.Instance.GetFeature<GAB.FeatureGAB>();
@ -118,6 +211,8 @@ namespace Acacia.Features.DebugSupport
}
}
#endregion
#region Logging
private const string INDENT = "+";

View File

@ -117,11 +117,35 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="columnMethod.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<data name="columnMethod.Text" xml:space="preserve">
<value>Method</value>
</data>
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="columnMethod.Width" type="System.Int32, mscorlib">
<value>44</value>
</data>
<metadata name="columnFile.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<data name="columnFile.Text" xml:space="preserve">
<value>File</value>
</data>
<data name="columnFile.Width" type="System.Int32, mscorlib">
<value>44</value>
</data>
<metadata name="columnLine.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<data name="columnLine.Text" xml:space="preserve">
<value>Line</value>
</data>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="tableMain.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Top, Bottom, Left, Right</value>
</data>
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="tableMain.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
@ -137,18 +161,333 @@
<data name="flowButtons.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="&gt;&gt;buttonGC.Name" xml:space="preserve">
<value>buttonGC</value>
</data>
<data name="&gt;&gt;buttonGC.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;buttonGC.Parent" xml:space="preserve">
<value>flowButtons</value>
</data>
<data name="&gt;&gt;buttonGC.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;buttonRefresh.Name" xml:space="preserve">
<value>buttonRefresh</value>
</data>
<data name="&gt;&gt;buttonRefresh.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;buttonRefresh.Parent" xml:space="preserve">
<value>flowButtons</value>
</data>
<data name="&gt;&gt;buttonRefresh.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="&gt;&gt;buttonClose.Name" xml:space="preserve">
<value>buttonClose</value>
</data>
<data name="&gt;&gt;buttonClose.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;buttonClose.Parent" xml:space="preserve">
<value>flowButtons</value>
</data>
<data name="&gt;&gt;buttonClose.ZOrder" xml:space="preserve">
<value>2</value>
</data>
<data name="&gt;&gt;buttonLog.Name" xml:space="preserve">
<value>buttonLog</value>
</data>
<data name="&gt;&gt;buttonLog.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;buttonLog.Parent" xml:space="preserve">
<value>flowButtons</value>
</data>
<data name="&gt;&gt;buttonLog.ZOrder" xml:space="preserve">
<value>3</value>
</data>
<data name="flowButtons.FlowDirection" type="System.Windows.Forms.FlowDirection, System.Windows.Forms">
<value>RightToLeft</value>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="flowButtons.Location" type="System.Drawing.Point, System.Drawing">
<value>4, 703</value>
</data>
<data name="flowButtons.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>4, 3, 4, 3</value>
</data>
<data name="flowButtons.Size" type="System.Drawing.Size, System.Drawing">
<value>615, 64</value>
</data>
<data name="flowButtons.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="&gt;&gt;flowButtons.Name" xml:space="preserve">
<value>flowButtons</value>
</data>
<data name="&gt;&gt;flowButtons.Type" xml:space="preserve">
<value>System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;flowButtons.Parent" xml:space="preserve">
<value>tableMain</value>
</data>
<data name="&gt;&gt;flowButtons.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;Properties.Name" xml:space="preserve">
<value>Properties</value>
</data>
<data name="&gt;&gt;Properties.Type" xml:space="preserve">
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;Properties.Parent" xml:space="preserve">
<value>_tabProperties</value>
</data>
<data name="&gt;&gt;Properties.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="_tabProperties.Location" type="System.Drawing.Point, System.Drawing">
<value>4, 33</value>
</data>
<data name="_tabProperties.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 3, 3, 3</value>
</data>
<data name="_tabProperties.Size" type="System.Drawing.Size, System.Drawing">
<value>609, 657</value>
</data>
<data name="_tabProperties.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="_tabProperties.Text" xml:space="preserve">
<value>General</value>
</data>
<data name="&gt;&gt;_tabProperties.Name" xml:space="preserve">
<value>_tabProperties</value>
</data>
<data name="&gt;&gt;_tabProperties.Type" xml:space="preserve">
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;_tabProperties.Parent" xml:space="preserve">
<value>_tabs</value>
</data>
<data name="&gt;&gt;_tabProperties.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;listWrapperTypes.Name" xml:space="preserve">
<value>listWrapperTypes</value>
</data>
<data name="&gt;&gt;listWrapperTypes.Type" xml:space="preserve">
<value>System.Windows.Forms.ListView, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;listWrapperTypes.Parent" xml:space="preserve">
<value>_tabWrapperTypes</value>
</data>
<data name="&gt;&gt;listWrapperTypes.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="_tabWrapperTypes.Location" type="System.Drawing.Point, System.Drawing">
<value>4, 33</value>
</data>
<data name="_tabWrapperTypes.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 3, 3, 3</value>
</data>
<data name="_tabWrapperTypes.Size" type="System.Drawing.Size, System.Drawing">
<value>609, 657</value>
</data>
<data name="_tabWrapperTypes.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="_tabWrapperTypes.Text" xml:space="preserve">
<value>Wrapper types</value>
</data>
<data name="&gt;&gt;_tabWrapperTypes.Name" xml:space="preserve">
<value>_tabWrapperTypes</value>
</data>
<data name="&gt;&gt;_tabWrapperTypes.Type" xml:space="preserve">
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;_tabWrapperTypes.Parent" xml:space="preserve">
<value>_tabs</value>
</data>
<data name="&gt;&gt;_tabWrapperTypes.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="_layoutLocations.ColumnCount" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="listStackTrace.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="listStackTrace.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 328</value>
</data>
<data name="listStackTrace.Size" type="System.Drawing.Size, System.Drawing">
<value>597, 320</value>
</data>
<data name="listStackTrace.TabIndex" type="System.Int32, mscorlib">
<value>3</value>
</data>
<data name="&gt;&gt;listStackTrace.Name" xml:space="preserve">
<value>listStackTrace</value>
</data>
<data name="&gt;&gt;listStackTrace.Type" xml:space="preserve">
<value>System.Windows.Forms.ListView, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;listStackTrace.Parent" xml:space="preserve">
<value>_layoutLocations</value>
</data>
<data name="&gt;&gt;listStackTrace.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="listWrapperLocations.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="listWrapperLocations.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 3</value>
</data>
<data name="listWrapperLocations.Size" type="System.Drawing.Size, System.Drawing">
<value>597, 319</value>
</data>
<data name="listWrapperLocations.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="&gt;&gt;listWrapperLocations.Name" xml:space="preserve">
<value>listWrapperLocations</value>
</data>
<data name="&gt;&gt;listWrapperLocations.Type" xml:space="preserve">
<value>System.Windows.Forms.ListView, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;listWrapperLocations.Parent" xml:space="preserve">
<value>_layoutLocations</value>
</data>
<data name="&gt;&gt;listWrapperLocations.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="_layoutLocations.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="_layoutLocations.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 3</value>
</data>
<data name="_layoutLocations.RowCount" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="_layoutLocations.Size" type="System.Drawing.Size, System.Drawing">
<value>603, 651</value>
</data>
<data name="_layoutLocations.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="&gt;&gt;_layoutLocations.Name" xml:space="preserve">
<value>_layoutLocations</value>
</data>
<data name="&gt;&gt;_layoutLocations.Type" xml:space="preserve">
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;_layoutLocations.Parent" xml:space="preserve">
<value>_tabWrapperLocations</value>
</data>
<data name="&gt;&gt;_layoutLocations.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="_layoutLocations.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
<value>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="listStackTrace" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="listWrapperLocations" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="Percent,100,Absolute,20" /&gt;&lt;Rows Styles="Percent,50,Percent,50" /&gt;&lt;/TableLayoutSettings&gt;</value>
</data>
<data name="_tabWrapperLocations.Location" type="System.Drawing.Point, System.Drawing">
<value>4, 33</value>
</data>
<data name="_tabWrapperLocations.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 3, 3, 3</value>
</data>
<data name="_tabWrapperLocations.Size" type="System.Drawing.Size, System.Drawing">
<value>609, 657</value>
</data>
<data name="_tabWrapperLocations.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="_tabWrapperLocations.Text" xml:space="preserve">
<value>Wrapper locations</value>
</data>
<data name="&gt;&gt;_tabWrapperLocations.Name" xml:space="preserve">
<value>_tabWrapperLocations</value>
</data>
<data name="&gt;&gt;_tabWrapperLocations.Type" xml:space="preserve">
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;_tabWrapperLocations.Parent" xml:space="preserve">
<value>_tabs</value>
</data>
<data name="&gt;&gt;_tabWrapperLocations.ZOrder" xml:space="preserve">
<value>2</value>
</data>
<data name="_tabs.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="_tabs.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 3</value>
</data>
<data name="_tabs.Size" type="System.Drawing.Size, System.Drawing">
<value>617, 694</value>
</data>
<data name="_tabs.TabIndex" type="System.Int32, mscorlib">
<value>3</value>
</data>
<data name="&gt;&gt;_tabs.Name" xml:space="preserve">
<value>_tabs</value>
</data>
<data name="&gt;&gt;_tabs.Type" xml:space="preserve">
<value>System.Windows.Forms.TabControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;_tabs.Parent" xml:space="preserve">
<value>tableMain</value>
</data>
<data name="&gt;&gt;_tabs.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="tableMain.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 0</value>
</data>
<data name="tableMain.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>4, 3, 4, 3</value>
</data>
<data name="tableMain.RowCount" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="tableMain.Size" type="System.Drawing.Size, System.Drawing">
<value>623, 770</value>
</data>
<data name="tableMain.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="&gt;&gt;tableMain.Name" xml:space="preserve">
<value>tableMain</value>
</data>
<data name="&gt;&gt;tableMain.Type" xml:space="preserve">
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;tableMain.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;tableMain.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="tableMain.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
<value>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="flowButtons" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="_tabs" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="Percent,100" /&gt;&lt;Rows Styles="Percent,100,AutoSize,0,Absolute,20" /&gt;&lt;/TableLayoutSettings&gt;</value>
</data>
<data name="buttonGC.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="buttonGC.Location" type="System.Drawing.Point, System.Drawing">
<value>352, 4</value>
<value>483, 6</value>
</data>
<data name="buttonGC.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>4, 4, 4, 4</value>
<value>6, 6, 6, 6</value>
</data>
<data name="buttonGC.Size" type="System.Drawing.Size, System.Drawing">
<value>91, 33</value>
<value>126, 52</value>
</data>
<data name="buttonGC.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
@ -172,13 +511,13 @@
<value>True</value>
</data>
<data name="buttonRefresh.Location" type="System.Drawing.Point, System.Drawing">
<value>253, 4</value>
<value>346, 6</value>
</data>
<data name="buttonRefresh.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>4, 4, 4, 4</value>
<value>6, 6, 6, 6</value>
</data>
<data name="buttonRefresh.Size" type="System.Drawing.Size, System.Drawing">
<value>91, 33</value>
<value>125, 52</value>
</data>
<data name="buttonRefresh.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
@ -202,13 +541,13 @@
<value>True</value>
</data>
<data name="buttonClose.Location" type="System.Drawing.Point, System.Drawing">
<value>145, 4</value>
<value>196, 6</value>
</data>
<data name="buttonClose.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>4, 4, 4, 4</value>
<value>6, 6, 6, 6</value>
</data>
<data name="buttonClose.Size" type="System.Drawing.Size, System.Drawing">
<value>100, 33</value>
<value>138, 52</value>
</data>
<data name="buttonClose.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
@ -232,13 +571,13 @@
<value>True</value>
</data>
<data name="buttonLog.Location" type="System.Drawing.Point, System.Drawing">
<value>62, 4</value>
<value>81, 6</value>
</data>
<data name="buttonLog.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>4, 4, 4, 4</value>
<value>6, 6, 6, 6</value>
</data>
<data name="buttonLog.Size" type="System.Drawing.Size, System.Drawing">
<value>75, 33</value>
<value>103, 52</value>
</data>
<data name="buttonLog.TabIndex" type="System.Int32, mscorlib">
<value>3</value>
@ -258,47 +597,20 @@
<data name="&gt;&gt;buttonLog.ZOrder" xml:space="preserve">
<value>3</value>
</data>
<data name="flowButtons.FlowDirection" type="System.Windows.Forms.FlowDirection, System.Windows.Forms">
<value>RightToLeft</value>
</data>
<data name="flowButtons.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 470</value>
</data>
<data name="flowButtons.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 2, 3, 2</value>
</data>
<data name="flowButtons.Size" type="System.Drawing.Size, System.Drawing">
<value>447, 41</value>
</data>
<data name="flowButtons.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="&gt;&gt;flowButtons.Name" xml:space="preserve">
<value>flowButtons</value>
</data>
<data name="&gt;&gt;flowButtons.Type" xml:space="preserve">
<value>System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;flowButtons.Parent" xml:space="preserve">
<value>tableMain</value>
</data>
<data name="&gt;&gt;flowButtons.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="Properties.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Top, Bottom, Left, Right</value>
<data name="Properties.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="Properties.HelpVisible" type="System.Boolean, mscorlib">
<value>False</value>
</data>
<data name="Properties.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 2</value>
<value>3, 3</value>
</data>
<data name="Properties.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 2, 3, 2</value>
<value>4, 3, 4, 3</value>
</data>
<data name="Properties.Size" type="System.Drawing.Size, System.Drawing">
<value>447, 464</value>
<value>603, 651</value>
</data>
<data name="Properties.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
@ -310,55 +622,73 @@
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;Properties.Parent" xml:space="preserve">
<value>tableMain</value>
<value>_tabProperties</value>
</data>
<data name="&gt;&gt;Properties.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="tableMain.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 0</value>
</data>
<data name="tableMain.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 2, 3, 2</value>
</data>
<data name="tableMain.RowCount" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="tableMain.Size" type="System.Drawing.Size, System.Drawing">
<value>453, 513</value>
</data>
<data name="tableMain.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="&gt;&gt;tableMain.Name" xml:space="preserve">
<value>tableMain</value>
<data name="listWrapperTypes.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="&gt;&gt;tableMain.Type" xml:space="preserve">
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<data name="listWrapperTypes.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 3</value>
</data>
<data name="&gt;&gt;tableMain.Parent" xml:space="preserve">
<value>$this</value>
<data name="listWrapperTypes.Size" type="System.Drawing.Size, System.Drawing">
<value>603, 651</value>
</data>
<data name="&gt;&gt;tableMain.ZOrder" xml:space="preserve">
<data name="listWrapperTypes.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="tableMain.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
<value>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="flowButtons" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="Properties" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="Percent,100" /&gt;&lt;Rows Styles="Percent,100,AutoSize,0" /&gt;&lt;/TableLayoutSettings&gt;</value>
<data name="&gt;&gt;listWrapperTypes.Name" xml:space="preserve">
<value>listWrapperTypes</value>
</data>
<data name="&gt;&gt;listWrapperTypes.Type" xml:space="preserve">
<value>System.Windows.Forms.ListView, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;listWrapperTypes.Parent" xml:space="preserve">
<value>_tabWrapperTypes</value>
</data>
<data name="&gt;&gt;listWrapperTypes.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="columnHeader1.Text" xml:space="preserve">
<value>Type</value>
</data>
<data name="columnHeader1.Width" type="System.Int32, mscorlib">
<value>44</value>
</data>
<data name="columnHeader2.Text" xml:space="preserve">
<value>Count</value>
</data>
<data name="columnHeader2.Width" type="System.Int32, mscorlib">
<value>44</value>
</data>
<data name="columnHeader3.Text" xml:space="preserve">
<value>Type</value>
</data>
<data name="columnHeader3.Width" type="System.Int32, mscorlib">
<value>44</value>
</data>
<data name="columnHeader4.Text" xml:space="preserve">
<value>Count</value>
</data>
<data name="columnHeader4.Width" type="System.Int32, mscorlib">
<value>44</value>
</data>
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
<value>8, 16</value>
<value>11, 24</value>
</data>
<data name="$this.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
<value>453, 511</value>
<value>623, 766</value>
</data>
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 2, 3, 2</value>
<value>4, 3, 4, 3</value>
</data>
<data name="$this.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
<value>CenterParent</value>
@ -366,10 +696,52 @@
<data name="$this.Text" xml:space="preserve">
<value>Debug</value>
</data>
<data name="&gt;&gt;columnMethod.Name" xml:space="preserve">
<value>columnMethod</value>
</data>
<data name="&gt;&gt;columnMethod.Type" xml:space="preserve">
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;columnFile.Name" xml:space="preserve">
<value>columnFile</value>
</data>
<data name="&gt;&gt;columnFile.Type" xml:space="preserve">
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;columnLine.Name" xml:space="preserve">
<value>columnLine</value>
</data>
<data name="&gt;&gt;columnLine.Type" xml:space="preserve">
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;columnHeader1.Name" xml:space="preserve">
<value>columnHeader1</value>
</data>
<data name="&gt;&gt;columnHeader1.Type" xml:space="preserve">
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;columnHeader2.Name" xml:space="preserve">
<value>columnHeader2</value>
</data>
<data name="&gt;&gt;columnHeader2.Type" xml:space="preserve">
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;columnHeader3.Name" xml:space="preserve">
<value>columnHeader3</value>
</data>
<data name="&gt;&gt;columnHeader3.Type" xml:space="preserve">
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;columnHeader4.Name" xml:space="preserve">
<value>columnHeader4</value>
</data>
<data name="&gt;&gt;columnHeader4.Type" xml:space="preserve">
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;$this.Name" xml:space="preserve">
<value>DebugDialog</value>
</data>
<data name="&gt;&gt;$this.Type" xml:space="preserve">
<value>System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>Acacia.UI.KopanoDialog, Kopano, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null</value>
</data>
</root>

View File

@ -273,7 +273,7 @@ namespace Acacia.Features.DebugSupport
#endregion
#region Helpers
#region Helpers
private string TimeToString(Stopwatch time)
{
@ -297,6 +297,6 @@ namespace Acacia.Features.DebugSupport
return string.Format("{0:n1} {1}", dValue, SizeSuffixes[i]);
}
#endregion
#endregion
}
}

View File

@ -107,6 +107,15 @@ namespace Acacia
}
private static readonly BoolOption COM_RELEASE = new BoolOption("COMRelease", true);
[AcaciaOption("Enables tracing of wrapper allocation. Should only be enabled for debugging, as it's very " +
"resource intensive.")]
public bool WrapperTrace
{
get { return GetOption(null, WRAPPER_TRACE); }
set { SetOption(null, WRAPPER_TRACE, value); }
}
private static readonly BoolOption WRAPPER_TRACE = new BoolOption("WrapperTrace", false);
[AcaciaOption("Enables or disables logging completely.")]
public bool Logging
{

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Acacia.Utils
{
public interface DisposableTracer
{
void Created(DisposableWrapper wrapper);
void Deleted(DisposableWrapper wrapper, bool wasDisposed);
void Disposed(DisposableWrapper wrapper);
}
}

View File

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Acacia.Utils
{
public class DisposableTracerDummy : DisposableTracer
{
public void Created(DisposableWrapper wrapper)
{
}
public void Deleted(DisposableWrapper wrapper, bool wasDisposed)
{
}
public void Disposed(DisposableWrapper wrapper)
{
}
}
}

View File

@ -0,0 +1,182 @@
using Acacia.Stubs.OutlookWrappers;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
namespace Acacia.Utils
{
public class DisposableTracerFull : DisposableTracer
{
public class CustomFrame
{
private readonly StackFrame _frame;
public CustomFrame(StackFrame stackFrame)
{
this._frame = stackFrame;
}
public string MethodName
{
get
{
// Make the qualified method name
string name = _frame.GetMethod().Name;
Type t = _frame.GetMethod().DeclaringType;
while (t != null)
{
name = t.Name + "." + name;
t = t.DeclaringType;
}
return name;
}
}
public string FileName
{
get
{
return _frame.GetFileName();
}
}
public int LineNumber
{
get
{
return _frame.GetFileLineNumber();
}
}
public override string ToString()
{
// Add any file information
string location = "";
if (_frame.GetFileName() != null)
{
location += " @ " + _frame.GetFileName();
location += ":" + _frame.GetFileLineNumber();
}
return MethodName + location + "\n";
}
}
public class CustomTrace : IComparable<CustomTrace>
{
private static bool fullTrace = false;
private readonly StackTrace _stackTrace;
private readonly CustomFrame[] _frames;
private int _nameIndex;
public CustomTrace(StackTrace stackTrace)
{
this._stackTrace = stackTrace;
// Find a useful name to display
StackFrame[] frames = stackTrace.GetFrames();
for (_nameIndex = 0; _nameIndex < frames.Length; ++_nameIndex)
{
StackFrame frame = frames[_nameIndex];
if (!IsCreationMethod(frame.GetMethod()))
break;
}
int startIndex = fullTrace ? 0 : _nameIndex;
// Create a custom trace from the frames
_frames = new CustomFrame[stackTrace.FrameCount - startIndex];
for (int i = 0; i < _frames.Length; ++i)
_frames[i] = new CustomFrame(frames[i + startIndex]);
}
private bool IsCreationMethod(MethodBase method)
{
// Any method in Mapping or Wrappers is purely for creation
if (method.DeclaringType == typeof(Mapping) ||
method.DeclaringType == typeof(Stubs.Wrappers))
return true;
// As is any ctor in OutlookWrappers. Methods there aren't, as they might created a
// wrapper for a property
if (method.IsConstructor &&
method.DeclaringType.Namespace == "Acacia.Stubs.OutlookWrappers")
return true;
return false;
}
public override string ToString()
{
string s = "";
foreach (CustomFrame frame in _frames)
s += frame.ToString();
return s;
}
public override bool Equals(object obj)
{
return ToString().Equals(obj.ToString());
}
public override int GetHashCode()
{
return ToString().GetHashCode();
}
public int CompareTo(CustomTrace other)
{
return ToString().CompareTo(other.ToString());
}
public string DisplayName
{
get { return _frames[fullTrace ? _nameIndex : 0].MethodName; }
}
public CustomFrame[] Frames
{
get { return _frames; }
}
}
private readonly ConcurrentDictionary<Type, int> _types = new ConcurrentDictionary<Type, int>();
private readonly ConcurrentDictionary<CustomTrace, int> _locations = new ConcurrentDictionary<CustomTrace, int>();
public void Created(DisposableWrapper wrapper)
{
_types.AddOrUpdate(wrapper.GetType(), 1, (i, value) => value + 1);
_locations.AddOrUpdate(new CustomTrace(wrapper.StackTrace), 1, (i, value) => value + 1);
}
public void Deleted(DisposableWrapper wrapper, bool wasDisposed)
{
if (!wasDisposed)
{
_types.AddOrUpdate(wrapper.GetType(), 0, (i, value) => value - 1);
_locations.AddOrUpdate(new CustomTrace(wrapper.StackTrace), 0, (i, value) => value - 1);
}
}
public void Disposed(DisposableWrapper wrapper)
{
_types.AddOrUpdate(wrapper.GetType(), 0, (i, value) => value - 1);
_locations.AddOrUpdate(new CustomTrace(wrapper.StackTrace), 0, (i, value) => value - 1);
}
public IEnumerable<KeyValuePair<Type, int>> GetTypes()
{
return _types;
}
public IEnumerable<KeyValuePair<CustomTrace, int>> GetLocations()
{
return _locations;
}
}
}

View File

@ -26,12 +26,28 @@ namespace Acacia.Utils
{
abstract public class DisposableWrapper : IDisposable
{
private static Dictionary<Type, int> typeCounts = new Dictionary<Type, int>();
private static DisposableTracer tracer = InitTracer();
private static DisposableTracer InitTracer()
{
if (GlobalOptions.INSTANCE.WrapperTrace)
return new DisposableTracerFull();
return new DisposableTracerDummy();
}
public static DisposableTracerFull GetTracer()
{
return tracer as DisposableTracerFull;
}
private bool _isDisposed;
public readonly System.Diagnostics.StackTrace StackTrace;
protected DisposableWrapper()
{
Interlocked.Increment(ref Statistics.CreatedWrappers);
this._createdTrace = new System.Diagnostics.StackTrace();
this.StackTrace = new System.Diagnostics.StackTrace(1, true);
tracer.Created(this);
}
~DisposableWrapper()
@ -39,27 +55,17 @@ namespace Acacia.Utils
Interlocked.Increment(ref Statistics.DeletedWrappers);
if (!_isDisposed)
{
Logger.Instance.Warning(this, "Undisposed wrapper: {0}", _createdTrace);
// Dispose, but don't count auto disposals, so the stats show it.
Logger.Instance.Warning(this, "Undisposed wrapper: {0}", StackTrace);
DoRelease();
}
else
{
--typeCounts[GetType()];
}
tracer.Deleted(this, _isDisposed);
}
private bool _isDisposed;
private readonly System.Diagnostics.StackTrace _createdTrace;
virtual public void Dispose()
{
if (!_isDisposed)
{
if (!typeCounts.ContainsKey(GetType()))
typeCounts.Add(GetType(), 1);
else
++typeCounts[GetType()];
tracer.Disposed(this);
_isDisposed = true;
Interlocked.Increment(ref Statistics.DisposedWrappers);