Skip to content

Commit f893961

Browse files
authored
Merge pull request #1 from mderoy/use-file-for-callstack
Use file for callstack
2 parents 85e3634 + ffe03e6 commit f893961

File tree

7 files changed

+139
-168
lines changed

7 files changed

+139
-168
lines changed

FuzzyRangeComparer.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System.Collections.Generic;
2+
3+
namespace PmipMyCallStack
4+
{
5+
struct Range
6+
{
7+
public ulong Start;
8+
public ulong End;
9+
public string Name;
10+
}
11+
class FuzzyRangeComparer : IComparer<Range>
12+
{
13+
public int Compare(Range x, Range y)
14+
{
15+
if (x.Name == null && y.Start <= x.Start && y.End >= x.Start)
16+
{
17+
return 0;
18+
}
19+
20+
if (y.Name == null && x.Start <= y.Start && x.End >= y.Start)
21+
{
22+
return 0;
23+
}
24+
25+
return x.Start.CompareTo(y.Start);
26+
}
27+
}
28+
}

Images/cs.png

5.49 KB
Loading

Images/csb.png

-25.6 KB
Loading

PmipCallStackFilter.cs

Lines changed: 109 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,120 @@
1-
using Microsoft.VisualStudio.Debugger.CallStack;
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Globalization;
4+
using System.IO;
5+
using Microsoft.VisualStudio.Debugger.CallStack;
26
using Microsoft.VisualStudio.Debugger.ComponentInterfaces;
37

48
namespace PmipMyCallStack
59
{
610
public class PmipCallStackFilter : IDkmCallStackFilter
711
{
12+
private static Range[] _rangesSortedByIp;
13+
private static long _previousFileLength;
14+
private static FuzzyRangeComparer _comparer = new FuzzyRangeComparer();
815

9-
public DkmStackWalkFrame[] FilterNextFrame(DkmStackContext stackContext, DkmStackWalkFrame input)
10-
{
11-
if (input == null) // after last frame
12-
return null;
16+
public DkmStackWalkFrame[] FilterNextFrame(DkmStackContext stackContext, DkmStackWalkFrame input)
17+
{
18+
if (input == null) // after last frame
19+
return null;
1320

14-
if (input.InstructionAddress == null) // error case
15-
return new[] { input };
21+
if (input.InstructionAddress == null) // error case
22+
return new[] { input };
1623

17-
if (input.InstructionAddress.ModuleInstance != null && input.InstructionAddress.ModuleInstance.Module != null) // code in existing module
18-
return new[] { input };
24+
if (input.InstructionAddress.ModuleInstance != null && input.InstructionAddress.ModuleInstance.Module != null) // code in existing module
25+
return new[] { input };
1926

20-
var runner = new PmipRunner(stackContext, input);
21-
return new[] { runner.PmipStackFrame() };
22-
}
23-
}
27+
if (!stackContext.Thread.IsMainThread) // error case
28+
return new[] { input };
29+
30+
31+
return new[] { PmipStackFrame(stackContext, input) };
32+
}
33+
34+
public static DkmStackWalkFrame PmipStackFrame(DkmStackContext stackContext, DkmStackWalkFrame frame)
35+
{
36+
var fileName = Path.Combine(Path.GetTempPath(), "pmip." + frame.Process.LivePart.Id);
37+
RefreshStackData(fileName);
38+
string name = null;
39+
if (TryGetDescriptionForIp(frame.InstructionAddress.CPUInstructionPart.InstructionPointer, out name))
40+
return DkmStackWalkFrame.Create(
41+
stackContext.Thread,
42+
frame.InstructionAddress,
43+
frame.FrameBase,
44+
frame.FrameSize,
45+
frame.Flags,
46+
name,
47+
frame.Registers,
48+
frame.Annotations);
49+
50+
return frame;
51+
}
52+
53+
public static void RefreshStackData(string fileName)
54+
{
55+
try
56+
{
57+
if (!File.Exists(fileName))
58+
return;
59+
60+
var fileInfo = new FileInfo(fileName);
61+
if (fileInfo.Length == _previousFileLength)
62+
return;
63+
64+
var list = new List<Range>(10000);
65+
using (var inStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
66+
{
67+
using (var file = new StreamReader(inStream))
68+
{
69+
string line;
70+
while ((line = file.ReadLine()) != null)
71+
{
72+
const char delemiter = ';';
73+
var tokens = line.Split(delemiter);
74+
75+
//should never happen, but lets be safe and not get array out of bounds if it does
76+
if (tokens.Length != 3)
77+
continue;
78+
79+
var startip = tokens[0];
80+
var endip = tokens[1];
81+
var description = tokens[2];
82+
83+
var startiplong = ulong.Parse(startip, NumberStyles.HexNumber);
84+
var endipint = ulong.Parse(endip, NumberStyles.HexNumber);
85+
86+
list.Add(new Range() { Name = description, Start = startiplong, End = endipint });
87+
}
88+
}
89+
}
90+
91+
list.Sort((r1, r2) => r1.Start.CompareTo(r2.Start));
92+
_rangesSortedByIp = list.ToArray();
93+
_previousFileLength = fileInfo.Length;
94+
}
95+
catch (Exception ex)
96+
{
97+
Console.WriteLine("Unable to read dumped pmip file: " + ex.Message);
98+
}
99+
100+
}
101+
102+
public static bool TryGetDescriptionForIp(ulong ip, out string name)
103+
{
104+
name = string.Empty;
105+
106+
if (_rangesSortedByIp == null)
107+
return false;
108+
109+
var rangeToFindIp = new Range() { Start = ip };
110+
var index = Array.BinarySearch(_rangesSortedByIp, rangeToFindIp, _comparer);
111+
112+
if (index < 0)
113+
return false;
114+
115+
name = _rangesSortedByIp[index].Name;
116+
117+
return true;
118+
}
119+
}
24120
}

PmipFunctionDataItem.cs

Lines changed: 0 additions & 9 deletions
This file was deleted.

PmipMyCallStack.csproj

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
33
<PropertyGroup>
44
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
@@ -58,9 +58,8 @@
5858
</Reference>
5959
</ItemGroup>
6060
<ItemGroup>
61+
<Compile Include="FuzzyRangeComparer.cs" />
6162
<Compile Include="PmipCallStackFilter.cs" />
62-
<Compile Include="PmipFunctionDataItem.cs" />
63-
<Compile Include="PmipRunner.cs" />
6463
<Compile Include="Properties\AssemblyInfo.cs" />
6564
</ItemGroup>
6665
<ItemGroup>

PmipRunner.cs

Lines changed: 0 additions & 143 deletions
This file was deleted.

0 commit comments

Comments
 (0)