├── .gitignore
├── ILDebugging.Decoder
├── DynamicMethodILProvider.cs
├── DynamicScopeTokenResolver.cs
├── FormatProvider.cs
├── ILDebugging.Decoder.csproj
├── ILInstruction.cs
├── ILProvider.cs
├── ILReader.cs
├── ILReaderFactory.cs
├── Properties
│ └── AssemblyInfo.cs
├── README.txt
├── ReadableILStringVisitor.cs
└── TokenResolver.cs
├── ILDebugging.Monitor
├── ILDebugging.Monitor.csproj
├── ILMonitorForm.Designer.cs
├── ILMonitorForm.cs
├── ILMonitorForm.resx
├── IncrementalData.cs
├── MiniBrowser.Designer.cs
├── MiniBrowser.cs
├── MiniBrowser.resx
├── MonitorHelper.cs
├── Program.cs
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Settings.Designer.cs
│ └── Settings.settings
├── Resources
│ └── XSLT.txt
└── app.config
├── ILDebugging.Sample
├── ILDebugging.Sample.csproj
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
└── app.config
├── ILDebugging.Visualizer
├── ILDebugging.Visualizer.csproj
├── MethodBodyInfo.cs
├── MethodBodyNoVisualizer.cs
├── MethodBodyObjectSource.cs
├── MethodBodyViewer.Designer.cs
├── MethodBodyViewer.cs
├── MethodBodyViewer.resx
├── MethodBodyVisualizer.cs
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resource.Designer.cs
│ ├── Resource.resx
│ ├── Settings.Designer.cs
│ └── Settings.settings
└── Resources
│ └── app.ico
├── ILDebugging.sln
├── Images
├── il-monitor.png
├── il-visualizer.png
└── launching-visualizer.png
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | Debug/
2 | Release/
3 | bin/
4 | obj/
5 | _ReSharper*/
6 | *.suo
7 | *.user
8 | *.ReSharper
9 | *.DotSettings.user
10 | *.nupkg
11 | packages/
12 | artifacts/
13 | node_modules/
14 | .vs/
15 | .bowerrc
16 | project.lock.json
17 | /.idea/
18 |
--------------------------------------------------------------------------------
/ILDebugging.Decoder/DynamicMethodILProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 | using System.Reflection.Emit;
4 |
5 | namespace ILDebugging.Decoder
6 | {
7 | public class DynamicMethodILProvider : IILProvider
8 | {
9 | private static readonly FieldInfo s_fiLen = typeof(ILGenerator).GetField("m_length", BindingFlags.NonPublic | BindingFlags.Instance);
10 | private static readonly FieldInfo s_fiStream = typeof(ILGenerator).GetField("m_ILStream", BindingFlags.NonPublic | BindingFlags.Instance);
11 | private static readonly MethodInfo s_miBakeByteArray = typeof(ILGenerator).GetMethod("BakeByteArray", BindingFlags.NonPublic | BindingFlags.Instance);
12 |
13 | private readonly DynamicMethod m_method;
14 | private byte[] m_byteArray;
15 |
16 | public DynamicMethodILProvider(DynamicMethod method)
17 | {
18 | m_method = method;
19 | }
20 |
21 | public byte[] GetByteArray()
22 | {
23 | if (m_byteArray == null)
24 | {
25 | var ilgen = m_method.GetILGenerator();
26 | try
27 | {
28 | m_byteArray = (byte[])s_miBakeByteArray.Invoke(ilgen, null) ?? new byte[0];
29 | }
30 | catch (TargetInvocationException)
31 | {
32 | var length = (int)s_fiLen.GetValue(ilgen);
33 | m_byteArray = new byte[length];
34 | Array.Copy((byte[])s_fiStream.GetValue(ilgen), m_byteArray, length);
35 | }
36 | }
37 | return m_byteArray;
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/ILDebugging.Decoder/DynamicScopeTokenResolver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Reflection;
4 | using System.Reflection.Emit;
5 |
6 | namespace ILDebugging.Decoder
7 | {
8 | internal class DynamicScopeTokenResolver : ITokenResolver
9 | {
10 | #region Static stuff
11 |
12 | private static readonly PropertyInfo s_indexer;
13 | private static readonly FieldInfo s_scopeFi;
14 |
15 | private static readonly Type s_genMethodInfoType;
16 | private static readonly FieldInfo s_genmethFi1;
17 | private static readonly FieldInfo s_genmethFi2;
18 |
19 | private static readonly Type s_varArgMethodType;
20 | private static readonly FieldInfo s_varargFi1;
21 |
22 | private static readonly Type s_genFieldInfoType;
23 | private static readonly FieldInfo s_genfieldFi1;
24 | private static readonly FieldInfo s_genfieldFi2;
25 |
26 | static DynamicScopeTokenResolver()
27 | {
28 | const BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance;
29 |
30 | s_indexer = Type.GetType("System.Reflection.Emit.DynamicScope").GetProperty("Item", flags);
31 | s_scopeFi = Type.GetType("System.Reflection.Emit.DynamicILGenerator").GetField("m_scope", flags);
32 |
33 | s_varArgMethodType = Type.GetType("System.Reflection.Emit.VarArgMethod");
34 | s_varargFi1 = s_varArgMethodType.GetField("m_method", flags);
35 |
36 | s_genMethodInfoType = Type.GetType("System.Reflection.Emit.GenericMethodInfo");
37 | s_genmethFi1 = s_genMethodInfoType.GetField("m_methodHandle", flags);
38 | s_genmethFi2 = s_genMethodInfoType.GetField("m_context", flags);
39 |
40 | s_genFieldInfoType = Type.GetType("System.Reflection.Emit.GenericFieldInfo", throwOnError: false);
41 |
42 | s_genfieldFi1 = s_genFieldInfoType?.GetField("m_fieldHandle", flags);
43 | s_genfieldFi2 = s_genFieldInfoType?.GetField("m_context", flags);
44 | }
45 |
46 | #endregion
47 |
48 | private readonly object m_scope;
49 |
50 | private object this[int token] => s_indexer.GetValue(m_scope, new object[] {token});
51 |
52 | public DynamicScopeTokenResolver(DynamicMethod dm)
53 | {
54 | m_scope = s_scopeFi.GetValue(dm.GetILGenerator());
55 | }
56 |
57 | public string AsString(int token)
58 | {
59 | return this[token] as string;
60 | }
61 |
62 | public FieldInfo AsField(int token)
63 | {
64 | if (this[token] is RuntimeFieldHandle)
65 | return FieldInfo.GetFieldFromHandle((RuntimeFieldHandle)this[token]);
66 |
67 | if (this[token].GetType() == s_genFieldInfoType)
68 | {
69 | return FieldInfo.GetFieldFromHandle(
70 | (RuntimeFieldHandle)s_genfieldFi1.GetValue(this[token]),
71 | (RuntimeTypeHandle)s_genfieldFi2.GetValue(this[token]));
72 | }
73 |
74 | Debug.Assert(false, $"unexpected type: {this[token].GetType()}");
75 | return null;
76 | }
77 |
78 | public Type AsType(int token)
79 | {
80 | return Type.GetTypeFromHandle((RuntimeTypeHandle)this[token]);
81 | }
82 |
83 | public MethodBase AsMethod(int token)
84 | {
85 | var dynamicMethod = this[token] as DynamicMethod;
86 | if (dynamicMethod != null)
87 | return dynamicMethod;
88 |
89 | if (this[token] is RuntimeMethodHandle)
90 | return MethodBase.GetMethodFromHandle((RuntimeMethodHandle)this[token]);
91 |
92 | if (this[token].GetType() == s_genMethodInfoType)
93 | return MethodBase.GetMethodFromHandle(
94 | (RuntimeMethodHandle)s_genmethFi1.GetValue(this[token]),
95 | (RuntimeTypeHandle)s_genmethFi2.GetValue(this[token]));
96 |
97 | if (this[token].GetType() == s_varArgMethodType)
98 | return (MethodInfo)s_varargFi1.GetValue(this[token]);
99 |
100 | Debug.Assert(false, $"unexpected type: {this[token].GetType()}");
101 | return null;
102 | }
103 |
104 | public MemberInfo AsMember(int token)
105 | {
106 | if ((token & 0x02000000) == 0x02000000)
107 | return AsType(token);
108 | if ((token & 0x06000000) == 0x06000000)
109 | return AsMethod(token);
110 | if ((token & 0x04000000) == 0x04000000)
111 | return AsField(token);
112 |
113 | Debug.Assert(false, $"unexpected token type: {token:x8}");
114 | return null;
115 | }
116 |
117 | public byte[] AsSignature(int token)
118 | {
119 | return this[token] as byte[];
120 | }
121 | }
122 | }
--------------------------------------------------------------------------------
/ILDebugging.Decoder/FormatProvider.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 |
3 | namespace ILDebugging.Decoder
4 | {
5 | public interface IFormatProvider
6 | {
7 | string Int32ToHex(int int32);
8 | string Int16ToHex(int int16);
9 | string Int8ToHex(int int8);
10 | string Argument(int ordinal);
11 | string EscapedString(string str);
12 | string Label(int offset);
13 | string MultipleLabels(int[] offsets);
14 | string SigByteArrayToString(byte[] sig);
15 | }
16 |
17 | public sealed class DefaultFormatProvider : IFormatProvider
18 | {
19 | private DefaultFormatProvider()
20 | {
21 | }
22 |
23 | public static DefaultFormatProvider Instance { get; } = new DefaultFormatProvider();
24 |
25 | public string Int32ToHex(int int32) => int32.ToString("X8");
26 | public string Int16ToHex(int int16) => int16.ToString("X4");
27 | public string Int8ToHex(int int8) => int8.ToString("X2");
28 | public string Argument(int ordinal) => $"V_{ordinal}";
29 | public string Label(int offset) => $"IL_{offset:x4}";
30 |
31 | public string MultipleLabels(int[] offsets)
32 | {
33 | var sb = new StringBuilder();
34 | var length = offsets.Length;
35 | for (var i = 0; i < length; i++)
36 | {
37 | sb.AppendFormat(i == 0 ? "(" : ", ");
38 | sb.Append(Label(offsets[i]));
39 | }
40 | sb.AppendFormat(")");
41 | return sb.ToString();
42 | }
43 |
44 | public string EscapedString(string str)
45 | {
46 | var length = str.Length;
47 | var sb = new StringBuilder(length*2);
48 |
49 | sb.Append('"');
50 | for (var i = 0; i < length; i++)
51 | {
52 | var ch = str[i];
53 | switch (ch)
54 | {
55 | case '\t':
56 | sb.Append("\\t");
57 | break;
58 | case '\n':
59 | sb.Append("\\n");
60 | break;
61 | case '\r':
62 | sb.Append("\\r");
63 | break;
64 | case '\"':
65 | sb.Append("\\\"");
66 | break;
67 | case '\\':
68 | sb.Append("\\");
69 | break;
70 | default:
71 | if (ch < 0x20 || ch >= 0x7f)
72 | sb.AppendFormat("\\u{0:x4}", (int)ch);
73 | else
74 | sb.Append(ch);
75 | break;
76 | }
77 | }
78 | sb.Append('"');
79 |
80 | return sb.ToString();
81 | }
82 |
83 | public string SigByteArrayToString(byte[] sig)
84 | {
85 | var sb = new StringBuilder();
86 | var length = sig.Length;
87 | for (var i = 0; i < length; i++)
88 | {
89 | sb.AppendFormat(i == 0 ? "SIG [" : " ");
90 | sb.Append(Int8ToHex(sig[i]));
91 | }
92 | sb.AppendFormat("]");
93 | return sb.ToString();
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/ILDebugging.Decoder/ILDebugging.Decoder.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.50727
7 | 2.0
8 | {3B40E8C3-C4E8-4085-9F82-F64308F3791C}
9 | Library
10 | Properties
11 | ILDebugging.Decoder
12 | ILDebugging.Decoder
13 |
14 |
15 |
16 |
17 | 3.5
18 | v4.0
19 |
20 |
21 |
22 | true
23 | full
24 | false
25 | bin\Debug\
26 | DEBUG;TRACE
27 | prompt
28 | 4
29 |
30 |
31 | pdbonly
32 | true
33 | bin\Release\
34 | TRACE
35 | prompt
36 | 4
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
64 |
--------------------------------------------------------------------------------
/ILDebugging.Decoder/ILInstruction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 | using System.Reflection.Emit;
4 |
5 | namespace ILDebugging.Decoder
6 | {
7 | public abstract class ILInstruction
8 | {
9 | internal ILInstruction(int offset, OpCode opCode)
10 | {
11 | Offset = offset;
12 | OpCode = opCode;
13 | }
14 |
15 | public int Offset { get; }
16 | public OpCode OpCode { get; }
17 |
18 | public abstract void Accept(ILInstructionVisitor visitor);
19 | }
20 |
21 | public class InlineNoneInstruction : ILInstruction
22 | {
23 | internal InlineNoneInstruction(int offset, OpCode opCode)
24 | : base(offset, opCode)
25 | {
26 | }
27 |
28 | public override void Accept(ILInstructionVisitor visitor)
29 | {
30 | visitor.VisitInlineNoneInstruction(this);
31 | }
32 | }
33 |
34 | public class InlineBrTargetInstruction : ILInstruction
35 | {
36 | internal InlineBrTargetInstruction(int offset, OpCode opCode, int delta)
37 | : base(offset, opCode)
38 | {
39 | Delta = delta;
40 | }
41 |
42 | public int Delta { get; }
43 |
44 | public int TargetOffset => Offset + Delta + 1 + 4;
45 |
46 | public override void Accept(ILInstructionVisitor visitor)
47 | {
48 | visitor.VisitInlineBrTargetInstruction(this);
49 | }
50 | }
51 |
52 | public class ShortInlineBrTargetInstruction : ILInstruction
53 | {
54 | internal ShortInlineBrTargetInstruction(int offset, OpCode opCode, sbyte delta)
55 | : base(offset, opCode)
56 | {
57 | Delta = delta;
58 | }
59 |
60 | public sbyte Delta { get; }
61 |
62 | public int TargetOffset => Offset + Delta + 1 + 1;
63 |
64 | public override void Accept(ILInstructionVisitor visitor)
65 | {
66 | visitor.VisitShortInlineBrTargetInstruction(this);
67 | }
68 | }
69 |
70 | public class InlineSwitchInstruction : ILInstruction
71 | {
72 | private readonly int[] m_deltas;
73 | private int[] m_targetOffsets;
74 |
75 | internal InlineSwitchInstruction(int offset, OpCode opCode, int[] deltas)
76 | : base(offset, opCode)
77 | {
78 | m_deltas = deltas;
79 | }
80 |
81 | public int[] Deltas => (int[])m_deltas.Clone();
82 |
83 | public int[] TargetOffsets
84 | {
85 | get
86 | {
87 | if (m_targetOffsets == null)
88 | {
89 | var cases = m_deltas.Length;
90 | var itself = 1 + 4 + 4*cases;
91 | m_targetOffsets = new int[cases];
92 | for (var i = 0; i < cases; i++)
93 | m_targetOffsets[i] = Offset + m_deltas[i] + itself;
94 | }
95 | return m_targetOffsets;
96 | }
97 | }
98 |
99 | public override void Accept(ILInstructionVisitor visitor)
100 | {
101 | visitor.VisitInlineSwitchInstruction(this);
102 | }
103 | }
104 |
105 | public class InlineIInstruction : ILInstruction
106 | {
107 | internal InlineIInstruction(int offset, OpCode opCode, int value)
108 | : base(offset, opCode)
109 | {
110 | Int32 = value;
111 | }
112 |
113 | public int Int32 { get; }
114 |
115 | public override void Accept(ILInstructionVisitor visitor)
116 | {
117 | visitor.VisitInlineIInstruction(this);
118 | }
119 | }
120 |
121 | public class InlineI8Instruction : ILInstruction
122 | {
123 | internal InlineI8Instruction(int offset, OpCode opCode, long value)
124 | : base(offset, opCode)
125 | {
126 | Int64 = value;
127 | }
128 |
129 | public long Int64 { get; }
130 |
131 | public override void Accept(ILInstructionVisitor visitor)
132 | {
133 | visitor.VisitInlineI8Instruction(this);
134 | }
135 | }
136 |
137 | public class ShortInlineIInstruction : ILInstruction
138 | {
139 | internal ShortInlineIInstruction(int offset, OpCode opCode, byte value)
140 | : base(offset, opCode)
141 | {
142 | Byte = value;
143 | }
144 |
145 | public byte Byte { get; }
146 |
147 | public override void Accept(ILInstructionVisitor visitor)
148 | {
149 | visitor.VisitShortInlineIInstruction(this);
150 | }
151 | }
152 |
153 | public class InlineRInstruction : ILInstruction
154 | {
155 | internal InlineRInstruction(int offset, OpCode opCode, double value)
156 | : base(offset, opCode)
157 | {
158 | Double = value;
159 | }
160 |
161 | public double Double { get; }
162 |
163 | public override void Accept(ILInstructionVisitor visitor)
164 | {
165 | visitor.VisitInlineRInstruction(this);
166 | }
167 | }
168 |
169 | public class ShortInlineRInstruction : ILInstruction
170 | {
171 | internal ShortInlineRInstruction(int offset, OpCode opCode, float value)
172 | : base(offset, opCode)
173 | {
174 | Single = value;
175 | }
176 |
177 | public float Single { get; }
178 |
179 | public override void Accept(ILInstructionVisitor visitor)
180 | {
181 | visitor.VisitShortInlineRInstruction(this);
182 | }
183 | }
184 |
185 | public class InlineFieldInstruction : ILInstruction
186 | {
187 | private readonly ITokenResolver m_resolver;
188 | private FieldInfo m_field;
189 |
190 | internal InlineFieldInstruction(ITokenResolver resolver, int offset, OpCode opCode, int token)
191 | : base(offset, opCode)
192 | {
193 | m_resolver = resolver;
194 | Token = token;
195 | }
196 |
197 | public FieldInfo Field => m_field ?? (m_field = m_resolver.AsField(Token));
198 |
199 | public int Token { get; }
200 |
201 | public override void Accept(ILInstructionVisitor visitor)
202 | {
203 | visitor.VisitInlineFieldInstruction(this);
204 | }
205 | }
206 |
207 | public class InlineMethodInstruction : ILInstruction
208 | {
209 | private readonly ITokenResolver m_resolver;
210 | private MethodBase m_method;
211 |
212 | internal InlineMethodInstruction(int offset, OpCode opCode, int token, ITokenResolver resolver)
213 | : base(offset, opCode)
214 | {
215 | m_resolver = resolver;
216 | Token = token;
217 | }
218 |
219 | public MethodBase Method => m_method ?? (m_method = m_resolver.AsMethod(Token));
220 |
221 | public int Token { get; }
222 |
223 | public override void Accept(ILInstructionVisitor visitor)
224 | {
225 | visitor.VisitInlineMethodInstruction(this);
226 | }
227 | }
228 |
229 | public class InlineTypeInstruction : ILInstruction
230 | {
231 | private readonly ITokenResolver m_resolver;
232 | private Type m_type;
233 |
234 | internal InlineTypeInstruction(int offset, OpCode opCode, int token, ITokenResolver resolver)
235 | : base(offset, opCode)
236 | {
237 | m_resolver = resolver;
238 | Token = token;
239 | }
240 |
241 | public Type Type => m_type ?? (m_type = m_resolver.AsType(Token));
242 |
243 | public int Token { get; }
244 |
245 | public override void Accept(ILInstructionVisitor visitor)
246 | {
247 | visitor.VisitInlineTypeInstruction(this);
248 | }
249 | }
250 |
251 | public class InlineSigInstruction : ILInstruction
252 | {
253 | private readonly ITokenResolver m_resolver;
254 | private byte[] m_signature;
255 |
256 | internal InlineSigInstruction(int offset, OpCode opCode, int token, ITokenResolver resolver)
257 | : base(offset, opCode)
258 | {
259 | m_resolver = resolver;
260 | Token = token;
261 | }
262 |
263 | public byte[] Signature => m_signature ?? (m_signature = m_resolver.AsSignature(Token));
264 |
265 | public int Token { get; }
266 |
267 | public override void Accept(ILInstructionVisitor visitor)
268 | {
269 | visitor.VisitInlineSigInstruction(this);
270 | }
271 | }
272 |
273 | public class InlineTokInstruction : ILInstruction
274 | {
275 | private readonly ITokenResolver m_resolver;
276 | private MemberInfo m_member;
277 |
278 | internal InlineTokInstruction(int offset, OpCode opCode, int token, ITokenResolver resolver)
279 | : base(offset, opCode)
280 | {
281 | m_resolver = resolver;
282 | Token = token;
283 | }
284 |
285 | public MemberInfo Member => m_member ?? (m_member = m_resolver.AsMember(Token));
286 |
287 | public int Token { get; }
288 |
289 | public override void Accept(ILInstructionVisitor visitor)
290 | {
291 | visitor.VisitInlineTokInstruction(this);
292 | }
293 | }
294 |
295 | public class InlineStringInstruction : ILInstruction
296 | {
297 | private readonly ITokenResolver m_resolver;
298 | private string m_string;
299 |
300 | internal InlineStringInstruction(int offset, OpCode opCode, int token, ITokenResolver resolver)
301 | : base(offset, opCode)
302 | {
303 | m_resolver = resolver;
304 | Token = token;
305 | }
306 |
307 | public string String => m_string ?? (m_string = m_resolver.AsString(Token));
308 |
309 | public int Token { get; }
310 |
311 | public override void Accept(ILInstructionVisitor visitor)
312 | {
313 | visitor.VisitInlineStringInstruction(this);
314 | }
315 | }
316 |
317 | public class InlineVarInstruction : ILInstruction
318 | {
319 | internal InlineVarInstruction(int offset, OpCode opCode, ushort ordinal)
320 | : base(offset, opCode)
321 | {
322 | Ordinal = ordinal;
323 | }
324 |
325 | public ushort Ordinal { get; }
326 |
327 | public override void Accept(ILInstructionVisitor visitor)
328 | {
329 | visitor.VisitInlineVarInstruction(this);
330 | }
331 | }
332 |
333 | public class ShortInlineVarInstruction : ILInstruction
334 | {
335 | internal ShortInlineVarInstruction(int offset, OpCode opCode, byte ordinal)
336 | : base(offset, opCode)
337 | {
338 | Ordinal = ordinal;
339 | }
340 |
341 | public byte Ordinal { get; }
342 |
343 | public override void Accept(ILInstructionVisitor visitor)
344 | {
345 | visitor.VisitShortInlineVarInstruction(this);
346 | }
347 | }
348 | }
--------------------------------------------------------------------------------
/ILDebugging.Decoder/ILProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 |
4 | namespace ILDebugging.Decoder
5 | {
6 | public interface IILProvider
7 | {
8 | byte[] GetByteArray();
9 | }
10 |
11 | public class MethodBaseILProvider : IILProvider
12 | {
13 | private static readonly Type s_runtimeMethodInfoType = Type.GetType("System.Reflection.RuntimeMethodInfo");
14 | private static readonly Type s_runtimeConstructorInfoType = Type.GetType("System.Reflection.RuntimeConstructorInfo");
15 |
16 | private readonly MethodBase m_method;
17 | private byte[] m_byteArray;
18 |
19 | public MethodBaseILProvider(MethodBase method)
20 | {
21 | if (method == null)
22 | throw new ArgumentNullException(nameof(method));
23 |
24 | var methodType = method.GetType();
25 |
26 | if (methodType != s_runtimeMethodInfoType && methodType != s_runtimeConstructorInfoType)
27 | throw new ArgumentException("Must have type RuntimeMethodInfo or RuntimeConstructorInfo.", nameof(method));
28 |
29 | m_method = method;
30 | }
31 |
32 | public byte[] GetByteArray()
33 | {
34 | return m_byteArray ?? (m_byteArray = m_method.GetMethodBody()?.GetILAsByteArray() ?? new byte[0]);
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/ILDebugging.Decoder/ILReader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Reflection;
5 | using System.Reflection.Emit;
6 |
7 | namespace ILDebugging.Decoder
8 | {
9 | public sealed class ILReader : IEnumerable
10 | {
11 | #region Static members
12 |
13 | private static readonly OpCode[] s_OneByteOpCodes = new OpCode[0x100];
14 | private static readonly OpCode[] s_TwoByteOpCodes = new OpCode[0x100];
15 |
16 | static ILReader()
17 | {
18 | foreach (var fi in typeof(OpCodes).GetFields(BindingFlags.Public | BindingFlags.Static))
19 | {
20 | var opCode = (OpCode)fi.GetValue(null);
21 | var value = (ushort)opCode.Value;
22 |
23 | if (value < 0x100)
24 | s_OneByteOpCodes[value] = opCode;
25 | else if ((value & 0xff00) == 0xfe00)
26 | s_TwoByteOpCodes[value & 0xff] = opCode;
27 | }
28 | }
29 |
30 | #endregion
31 |
32 | private readonly ITokenResolver m_resolver;
33 | private readonly byte[] m_byteArray;
34 |
35 | public ILReader(MethodBase method)
36 | : this(new MethodBaseILProvider(method), new ModuleScopeTokenResolver(method))
37 | {
38 | }
39 |
40 | public ILReader(IILProvider ilProvider, ITokenResolver tokenResolver)
41 | {
42 | if (ilProvider == null)
43 | throw new ArgumentNullException(nameof(ilProvider));
44 |
45 | m_resolver = tokenResolver;
46 | m_byteArray = ilProvider.GetByteArray();
47 | }
48 |
49 | public IEnumerator GetEnumerator()
50 | {
51 | var position = 0;
52 |
53 | while (position < m_byteArray.Length)
54 | yield return Next(ref position);
55 | }
56 |
57 | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
58 |
59 | private ILInstruction Next(ref int position)
60 | {
61 | var offset = position;
62 | OpCode opCode;
63 |
64 | // read first 1 or 2 bytes as opCode
65 | var code = ReadByte(ref position);
66 | if (code != 0xFE)
67 | {
68 | opCode = s_OneByteOpCodes[code];
69 | }
70 | else
71 | {
72 | code = ReadByte(ref position);
73 | opCode = s_TwoByteOpCodes[code];
74 | }
75 |
76 | switch (opCode.OperandType)
77 | {
78 | case OperandType.InlineNone:
79 | {
80 | return new InlineNoneInstruction(offset, opCode);
81 | }
82 | case OperandType.ShortInlineBrTarget:
83 | {
84 | // 8-bit integer branch target
85 | var shortDelta = ReadSByte(ref position);
86 | return new ShortInlineBrTargetInstruction(offset, opCode, shortDelta);
87 | }
88 | case OperandType.InlineBrTarget:
89 | {
90 | // 32-bit integer branch target
91 | var delta = ReadInt32(ref position);
92 | return new InlineBrTargetInstruction(offset, opCode, delta);
93 | }
94 | case OperandType.ShortInlineI:
95 | {
96 | // 8-bit integer: 001F ldc.i4.s, FE12 unaligned.
97 | var int8 = ReadByte(ref position);
98 | return new ShortInlineIInstruction(offset, opCode, int8);
99 | }
100 | case OperandType.InlineI:
101 | {
102 | // 32-bit integer
103 | var int32 = ReadInt32(ref position);
104 | return new InlineIInstruction(offset, opCode, int32);
105 | }
106 | case OperandType.InlineI8:
107 | {
108 | // 64-bit integer
109 | var int64 = ReadInt64(ref position);
110 | return new InlineI8Instruction(offset, opCode, int64);
111 | }
112 | case OperandType.ShortInlineR:
113 | {
114 | // 32-bit IEEE floating point number
115 | var float32 = ReadSingle(ref position);
116 | return new ShortInlineRInstruction(offset, opCode, float32);
117 | }
118 | case OperandType.InlineR:
119 | {
120 | // 64-bit IEEE floating point number
121 | var float64 = ReadDouble(ref position);
122 | return new InlineRInstruction(offset, opCode, float64);
123 | }
124 | case OperandType.ShortInlineVar:
125 | {
126 | // 8-bit integer containing the ordinal of a local variable or an argument
127 | var index8 = ReadByte(ref position);
128 | return new ShortInlineVarInstruction(offset, opCode, index8);
129 | }
130 | case OperandType.InlineVar:
131 | {
132 | // 16-bit integer containing the ordinal of a local variable or an argument
133 | var index16 = ReadUInt16(ref position);
134 | return new InlineVarInstruction(offset, opCode, index16);
135 | }
136 | case OperandType.InlineString:
137 | {
138 | // 32-bit metadata string token
139 | var token = ReadInt32(ref position);
140 | return new InlineStringInstruction(offset, opCode, token, m_resolver);
141 | }
142 | case OperandType.InlineSig:
143 | {
144 | // 32-bit metadata signature token
145 | var token = ReadInt32(ref position);
146 | return new InlineSigInstruction(offset, opCode, token, m_resolver);
147 | }
148 | case OperandType.InlineMethod:
149 | {
150 | // 32-bit metadata token
151 | var token = ReadInt32(ref position);
152 | return new InlineMethodInstruction(offset, opCode, token, m_resolver);
153 | }
154 | case OperandType.InlineField:
155 | {
156 | // 32-bit metadata token
157 | var token = ReadInt32(ref position);
158 | return new InlineFieldInstruction(m_resolver, offset, opCode, token);
159 | }
160 | case OperandType.InlineType:
161 | {
162 | // 32-bit metadata token
163 | var token = ReadInt32(ref position);
164 | return new InlineTypeInstruction(offset, opCode, token, m_resolver);
165 | }
166 | case OperandType.InlineTok:
167 | {
168 | // FieldRef, MethodRef, or TypeRef token
169 | var token = ReadInt32(ref position);
170 | return new InlineTokInstruction(offset, opCode, token, m_resolver);
171 | }
172 | case OperandType.InlineSwitch:
173 | {
174 | // 32-bit integer argument to a switch instruction
175 | var cases = ReadInt32(ref position);
176 | var deltas = new int[cases];
177 | for (var i = 0; i < cases; i++)
178 | deltas[i] = ReadInt32(ref position);
179 | return new InlineSwitchInstruction(offset, opCode, deltas);
180 | }
181 |
182 | default:
183 | throw new NotSupportedException($"Unsupported operand type: {opCode.OperandType}");
184 | }
185 | }
186 |
187 | public void Accept(ILInstructionVisitor visitor)
188 | {
189 | if (visitor == null)
190 | throw new ArgumentNullException(nameof(visitor));
191 |
192 | foreach (var instruction in this)
193 | instruction.Accept(visitor);
194 | }
195 |
196 | #region read in operands
197 |
198 | private byte ReadByte(ref int position) => m_byteArray[position++];
199 |
200 | private sbyte ReadSByte(ref int position) => (sbyte)ReadByte(ref position);
201 |
202 | private ushort ReadUInt16(ref int position)
203 | {
204 | var value = BitConverter.ToUInt16(m_byteArray, position);
205 | position += 2;
206 | return value;
207 | }
208 |
209 | private uint ReadUInt32(ref int position)
210 | {
211 | var value = BitConverter.ToUInt32(m_byteArray, position);
212 | position += 4;
213 | return value;
214 | }
215 |
216 | private ulong ReadUInt64(ref int position)
217 | {
218 | var value = BitConverter.ToUInt64(m_byteArray, position);
219 | position += 8;
220 | return value;
221 | }
222 |
223 | private int ReadInt32(ref int position)
224 | {
225 | var value = BitConverter.ToInt32(m_byteArray, position);
226 | position += 4;
227 | return value;
228 | }
229 |
230 | private long ReadInt64(ref int position)
231 | {
232 | var value = BitConverter.ToInt64(m_byteArray, position);
233 | position += 8;
234 | return value;
235 | }
236 |
237 | private float ReadSingle(ref int position)
238 | {
239 | var value = BitConverter.ToSingle(m_byteArray, position);
240 | position += 4;
241 | return value;
242 | }
243 |
244 | private double ReadDouble(ref int position)
245 | {
246 | var value = BitConverter.ToDouble(m_byteArray, position);
247 | position += 8;
248 | return value;
249 | }
250 |
251 | #endregion
252 | }
253 | }
--------------------------------------------------------------------------------
/ILDebugging.Decoder/ILReaderFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 | using System.Reflection.Emit;
4 |
5 | namespace ILDebugging.Decoder
6 | {
7 | public static class ILReaderFactory
8 | {
9 | public static ILReader Create(object obj)
10 | {
11 | var type = obj.GetType();
12 |
13 | if (type == s_dynamicMethodType || type == s_rtDynamicMethodType)
14 | {
15 | DynamicMethod dm;
16 | if (type == s_rtDynamicMethodType)
17 | {
18 | //
19 | // if the target is RTDynamicMethod, get the value of
20 | // RTDynamicMethod.m_owner instead
21 | //
22 | dm = (DynamicMethod)s_fiOwner.GetValue(obj);
23 | }
24 | else
25 | {
26 | dm = obj as DynamicMethod;
27 | }
28 |
29 | return new ILReader(new DynamicMethodILProvider(dm), new DynamicScopeTokenResolver(dm));
30 | }
31 |
32 | if (type == s_runtimeMethodInfoType || type == s_runtimeConstructorInfoType)
33 | {
34 | var method = obj as MethodBase;
35 | return new ILReader(method);
36 | }
37 |
38 | throw new NotSupportedException($"Reading IL from type {type} is currently not supported");
39 | }
40 |
41 | private static readonly Type s_dynamicMethodType = Type.GetType("System.Reflection.Emit.DynamicMethod");
42 | private static readonly Type s_runtimeMethodInfoType = Type.GetType("System.Reflection.RuntimeMethodInfo");
43 | private static readonly Type s_runtimeConstructorInfoType = Type.GetType("System.Reflection.RuntimeConstructorInfo");
44 |
45 | private static readonly Type s_rtDynamicMethodType = Type.GetType("System.Reflection.Emit.DynamicMethod+RTDynamicMethod");
46 | private static readonly FieldInfo s_fiOwner = s_rtDynamicMethodType.GetField("m_owner", BindingFlags.Instance | BindingFlags.NonPublic);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/ILDebugging.Decoder/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 | using System.Security;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 |
9 | [assembly: AssemblyTitle("ILDebugging.Decoder")]
10 | [assembly: AssemblyDescription("Reads IL bytes as a sequence of opcodes and operands.")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("Microsoft")]
13 | [assembly: AssemblyProduct("")]
14 | [assembly: AssemblyCopyright("Copyright © 2006")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 |
18 | // Setting ComVisible to false makes the types in this assembly not visible
19 | // to COM components. If you need to access a type in this assembly from
20 | // COM, set the ComVisible attribute to true on that type.
21 |
22 | [assembly: ComVisible(false)]
23 |
24 | // The following GUID is for the ID of the typelib if this project is exposed to COM
25 |
26 | [assembly: Guid("1032b116-0bc4-4877-9d09-86ce346c17ab")]
27 |
28 | // Version information for an assembly consists of the following four values:
29 | //
30 | // Major Version
31 | // Minor Version
32 | // Build Number
33 | // Revision
34 | //
35 | // You can specify all the values or you can default the Revision and Build Numbers
36 | // by using the '*' as shown below:
37 |
38 | [assembly: AssemblyVersion("1.0.0.0")]
39 | [assembly: AssemblyFileVersion("1.0.0.0")]
40 | [assembly: SecurityTransparent]
--------------------------------------------------------------------------------
/ILDebugging.Decoder/README.txt:
--------------------------------------------------------------------------------
1 |
2 | THE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES INTENDED OR IMPLIED. USE AT YOUR OWN RISK
--------------------------------------------------------------------------------
/ILDebugging.Decoder/ReadableILStringVisitor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | namespace ILDebugging.Decoder
5 | {
6 | public interface IILStringCollector
7 | {
8 | void Process(ILInstruction ilInstruction, string operandString);
9 | }
10 |
11 | public class ReadableILStringToTextWriter : IILStringCollector
12 | {
13 | protected readonly TextWriter writer;
14 |
15 | public ReadableILStringToTextWriter(TextWriter writer)
16 | {
17 | this.writer = writer;
18 | }
19 |
20 | public virtual void Process(ILInstruction ilInstruction, string operandString)
21 | {
22 | writer.WriteLine("IL_{0:x4}: {1,-10} {2}",
23 | ilInstruction.Offset,
24 | ilInstruction.OpCode.Name,
25 | operandString);
26 | }
27 | }
28 |
29 | public class RawILStringToTextWriter : ReadableILStringToTextWriter
30 | {
31 | public RawILStringToTextWriter(TextWriter writer)
32 | : base(writer)
33 | {
34 | }
35 |
36 | public override void Process(ILInstruction ilInstruction, string operandString)
37 | {
38 | writer.WriteLine("IL_{0:x4}: {1,-4:x2}| {2, -8}",
39 | ilInstruction.Offset,
40 | ilInstruction.OpCode.Value,
41 | operandString);
42 | }
43 | }
44 |
45 | public abstract class ILInstructionVisitor
46 | {
47 | public virtual void VisitInlineBrTargetInstruction(InlineBrTargetInstruction inlineBrTargetInstruction)
48 | {
49 | }
50 |
51 | public virtual void VisitInlineFieldInstruction(InlineFieldInstruction inlineFieldInstruction)
52 | {
53 | }
54 |
55 | public virtual void VisitInlineIInstruction(InlineIInstruction inlineIInstruction)
56 | {
57 | }
58 |
59 | public virtual void VisitInlineI8Instruction(InlineI8Instruction inlineI8Instruction)
60 | {
61 | }
62 |
63 | public virtual void VisitInlineMethodInstruction(InlineMethodInstruction inlineMethodInstruction)
64 | {
65 | }
66 |
67 | public virtual void VisitInlineNoneInstruction(InlineNoneInstruction inlineNoneInstruction)
68 | {
69 | }
70 |
71 | public virtual void VisitInlineRInstruction(InlineRInstruction inlineRInstruction)
72 | {
73 | }
74 |
75 | public virtual void VisitInlineSigInstruction(InlineSigInstruction inlineSigInstruction)
76 | {
77 | }
78 |
79 | public virtual void VisitInlineStringInstruction(InlineStringInstruction inlineStringInstruction)
80 | {
81 | }
82 |
83 | public virtual void VisitInlineSwitchInstruction(InlineSwitchInstruction inlineSwitchInstruction)
84 | {
85 | }
86 |
87 | public virtual void VisitInlineTokInstruction(InlineTokInstruction inlineTokInstruction)
88 | {
89 | }
90 |
91 | public virtual void VisitInlineTypeInstruction(InlineTypeInstruction inlineTypeInstruction)
92 | {
93 | }
94 |
95 | public virtual void VisitInlineVarInstruction(InlineVarInstruction inlineVarInstruction)
96 | {
97 | }
98 |
99 | public virtual void VisitShortInlineBrTargetInstruction(ShortInlineBrTargetInstruction shortInlineBrTargetInstruction)
100 | {
101 | }
102 |
103 | public virtual void VisitShortInlineIInstruction(ShortInlineIInstruction shortInlineIInstruction)
104 | {
105 | }
106 |
107 | public virtual void VisitShortInlineRInstruction(ShortInlineRInstruction shortInlineRInstruction)
108 | {
109 | }
110 |
111 | public virtual void VisitShortInlineVarInstruction(ShortInlineVarInstruction shortInlineVarInstruction)
112 | {
113 | }
114 | }
115 |
116 | public class ReadableILStringVisitor : ILInstructionVisitor
117 | {
118 | protected readonly IFormatProvider formatProvider;
119 | protected readonly IILStringCollector collector;
120 |
121 | public ReadableILStringVisitor(IILStringCollector collector)
122 | : this(collector, DefaultFormatProvider.Instance)
123 | {
124 | }
125 |
126 | public ReadableILStringVisitor(IILStringCollector collector, IFormatProvider formatProvider)
127 | {
128 | this.formatProvider = formatProvider;
129 | this.collector = collector;
130 | }
131 |
132 | public override void VisitInlineBrTargetInstruction(InlineBrTargetInstruction inlineBrTargetInstruction)
133 | {
134 | collector.Process(inlineBrTargetInstruction, formatProvider.Label(inlineBrTargetInstruction.TargetOffset));
135 | }
136 |
137 | public override void VisitInlineFieldInstruction(InlineFieldInstruction inlineFieldInstruction)
138 | {
139 | string field;
140 | try
141 | {
142 | field = inlineFieldInstruction.Field + "/" + inlineFieldInstruction.Field.DeclaringType;
143 | }
144 | catch (Exception ex)
145 | {
146 | field = "!" + ex.Message + "!";
147 | }
148 | collector.Process(inlineFieldInstruction, field);
149 | }
150 |
151 | public override void VisitInlineIInstruction(InlineIInstruction inlineIInstruction)
152 | {
153 | collector.Process(inlineIInstruction, inlineIInstruction.Int32.ToString());
154 | }
155 |
156 | public override void VisitInlineI8Instruction(InlineI8Instruction inlineI8Instruction)
157 | {
158 | collector.Process(inlineI8Instruction, inlineI8Instruction.Int64.ToString());
159 | }
160 |
161 | public override void VisitInlineMethodInstruction(InlineMethodInstruction inlineMethodInstruction)
162 | {
163 | string method;
164 | try
165 | {
166 | method = inlineMethodInstruction.Method + "/" + inlineMethodInstruction.Method.DeclaringType;
167 | }
168 | catch (Exception ex)
169 | {
170 | method = "!" + ex.Message + "!";
171 | }
172 | collector.Process(inlineMethodInstruction, method);
173 | }
174 |
175 | public override void VisitInlineNoneInstruction(InlineNoneInstruction inlineNoneInstruction)
176 | {
177 | collector.Process(inlineNoneInstruction, string.Empty);
178 | }
179 |
180 | public override void VisitInlineRInstruction(InlineRInstruction inlineRInstruction)
181 | {
182 | collector.Process(inlineRInstruction, inlineRInstruction.Double.ToString());
183 | }
184 |
185 | public override void VisitInlineSigInstruction(InlineSigInstruction inlineSigInstruction)
186 | {
187 | collector.Process(inlineSigInstruction, formatProvider.SigByteArrayToString(inlineSigInstruction.Signature));
188 | }
189 |
190 | public override void VisitInlineStringInstruction(InlineStringInstruction inlineStringInstruction)
191 | {
192 | collector.Process(inlineStringInstruction, formatProvider.EscapedString(inlineStringInstruction.String));
193 | }
194 |
195 | public override void VisitInlineSwitchInstruction(InlineSwitchInstruction inlineSwitchInstruction)
196 | {
197 | collector.Process(inlineSwitchInstruction, formatProvider.MultipleLabels(inlineSwitchInstruction.TargetOffsets));
198 | }
199 |
200 | public override void VisitInlineTokInstruction(InlineTokInstruction inlineTokInstruction)
201 | {
202 | string member;
203 | try
204 | {
205 | member = inlineTokInstruction.Member + "/" + inlineTokInstruction.Member.DeclaringType;
206 | }
207 | catch (Exception ex)
208 | {
209 | member = "!" + ex.Message + "!";
210 | }
211 | collector.Process(inlineTokInstruction, member);
212 | }
213 |
214 | public override void VisitInlineTypeInstruction(InlineTypeInstruction inlineTypeInstruction)
215 | {
216 | string type;
217 | try
218 | {
219 | type = inlineTypeInstruction.Type.ToString();
220 | }
221 | catch (Exception ex)
222 | {
223 | type = "!" + ex.Message + "!";
224 | }
225 | collector.Process(inlineTypeInstruction, type);
226 | }
227 |
228 | public override void VisitInlineVarInstruction(InlineVarInstruction inlineVarInstruction)
229 | {
230 | collector.Process(inlineVarInstruction, formatProvider.Argument(inlineVarInstruction.Ordinal));
231 | }
232 |
233 | public override void VisitShortInlineBrTargetInstruction(ShortInlineBrTargetInstruction shortInlineBrTargetInstruction)
234 | {
235 | collector.Process(shortInlineBrTargetInstruction, formatProvider.Label(shortInlineBrTargetInstruction.TargetOffset));
236 | }
237 |
238 | public override void VisitShortInlineIInstruction(ShortInlineIInstruction shortInlineIInstruction)
239 | {
240 | collector.Process(shortInlineIInstruction, shortInlineIInstruction.Byte.ToString());
241 | }
242 |
243 | public override void VisitShortInlineRInstruction(ShortInlineRInstruction shortInlineRInstruction)
244 | {
245 | collector.Process(shortInlineRInstruction, shortInlineRInstruction.Single.ToString());
246 | }
247 |
248 | public override void VisitShortInlineVarInstruction(ShortInlineVarInstruction shortInlineVarInstruction)
249 | {
250 | collector.Process(shortInlineVarInstruction, formatProvider.Argument(shortInlineVarInstruction.Ordinal));
251 | }
252 | }
253 |
254 | public class RawILStringVisitor : ReadableILStringVisitor
255 | {
256 | public RawILStringVisitor(IILStringCollector collector)
257 | : this(collector, DefaultFormatProvider.Instance)
258 | {
259 | }
260 |
261 | public RawILStringVisitor(IILStringCollector collector, IFormatProvider formatProvider)
262 | : base(collector, formatProvider)
263 | {
264 | }
265 |
266 | public override void VisitInlineBrTargetInstruction(InlineBrTargetInstruction inlineBrTargetInstruction)
267 | {
268 | collector.Process(inlineBrTargetInstruction, formatProvider.Int32ToHex(inlineBrTargetInstruction.Delta));
269 | }
270 |
271 | public override void VisitInlineFieldInstruction(InlineFieldInstruction inlineFieldInstruction)
272 | {
273 | collector.Process(inlineFieldInstruction, formatProvider.Int32ToHex(inlineFieldInstruction.Token));
274 | }
275 |
276 | public override void VisitInlineMethodInstruction(InlineMethodInstruction inlineMethodInstruction)
277 | {
278 | collector.Process(inlineMethodInstruction, formatProvider.Int32ToHex(inlineMethodInstruction.Token));
279 | }
280 |
281 | public override void VisitInlineSigInstruction(InlineSigInstruction inlineSigInstruction)
282 | {
283 | collector.Process(inlineSigInstruction, formatProvider.Int32ToHex(inlineSigInstruction.Token));
284 | }
285 |
286 | public override void VisitInlineStringInstruction(InlineStringInstruction inlineStringInstruction)
287 | {
288 | collector.Process(inlineStringInstruction, formatProvider.Int32ToHex(inlineStringInstruction.Token));
289 | }
290 |
291 | public override void VisitInlineSwitchInstruction(InlineSwitchInstruction inlineSwitchInstruction)
292 | {
293 | collector.Process(inlineSwitchInstruction, "...");
294 | }
295 |
296 | public override void VisitInlineTokInstruction(InlineTokInstruction inlineTokInstruction)
297 | {
298 | collector.Process(inlineTokInstruction, formatProvider.Int32ToHex(inlineTokInstruction.Token));
299 | }
300 |
301 | public override void VisitInlineTypeInstruction(InlineTypeInstruction inlineTypeInstruction)
302 | {
303 | collector.Process(inlineTypeInstruction, formatProvider.Int32ToHex(inlineTypeInstruction.Token));
304 | }
305 |
306 | public override void VisitInlineVarInstruction(InlineVarInstruction inlineVarInstruction)
307 | {
308 | collector.Process(inlineVarInstruction, formatProvider.Int16ToHex(inlineVarInstruction.Ordinal));
309 | }
310 |
311 | public override void VisitShortInlineBrTargetInstruction(ShortInlineBrTargetInstruction shortInlineBrTargetInstruction)
312 | {
313 | collector.Process(shortInlineBrTargetInstruction, formatProvider.Int8ToHex(shortInlineBrTargetInstruction.Delta));
314 | }
315 |
316 | public override void VisitShortInlineVarInstruction(ShortInlineVarInstruction shortInlineVarInstruction)
317 | {
318 | collector.Process(shortInlineVarInstruction, formatProvider.Int8ToHex(shortInlineVarInstruction.Ordinal));
319 | }
320 | }
321 | }
322 |
--------------------------------------------------------------------------------
/ILDebugging.Decoder/TokenResolver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 |
4 | namespace ILDebugging.Decoder
5 | {
6 | public interface ITokenResolver
7 | {
8 | MethodBase AsMethod(int token);
9 | FieldInfo AsField(int token);
10 | Type AsType(int token);
11 | string AsString(int token);
12 | MemberInfo AsMember(int token);
13 | byte[] AsSignature(int token);
14 | }
15 |
16 | public class ModuleScopeTokenResolver : ITokenResolver
17 | {
18 | private readonly Module m_module;
19 | private readonly Type[] m_methodContext;
20 | private readonly Type[] m_typeContext;
21 |
22 | public ModuleScopeTokenResolver(MethodBase method)
23 | {
24 | m_module = method.Module;
25 | m_methodContext = method is ConstructorInfo ? null : method.GetGenericArguments();
26 | m_typeContext = method.DeclaringType == null ? null : method.DeclaringType.GetGenericArguments();
27 | }
28 |
29 | public MethodBase AsMethod(int token) => m_module.ResolveMethod(token, m_typeContext, m_methodContext);
30 | public FieldInfo AsField(int token) => m_module.ResolveField(token, m_typeContext, m_methodContext);
31 | public Type AsType(int token) => m_module.ResolveType(token, m_typeContext, m_methodContext);
32 | public MemberInfo AsMember(int token) => m_module.ResolveMember(token, m_typeContext, m_methodContext);
33 | public string AsString(int token) => m_module.ResolveString(token);
34 | public byte[] AsSignature(int token) => m_module.ResolveSignature(token);
35 | }
36 | }
--------------------------------------------------------------------------------
/ILDebugging.Monitor/ILDebugging.Monitor.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.50727
7 | 2.0
8 | {77F852DD-35CD-4B2D-AA0E-0516F1E7597F}
9 | WinExe
10 | Properties
11 | ILDebugging.Monitor
12 | ILDebugging.Monitor
13 |
14 |
15 |
16 |
17 | 3.5
18 | v4.6
19 |
20 |
21 |
22 | true
23 | full
24 | false
25 | bin\Debug\
26 | DEBUG;TRACE
27 | prompt
28 | 4
29 | false
30 |
31 |
32 | pdbonly
33 | true
34 | bin\Release\
35 | TRACE
36 | prompt
37 | 4
38 | false
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | Form
49 |
50 |
51 | ILMonitorForm.cs
52 |
53 |
54 |
55 | Form
56 |
57 |
58 | MiniBrowser.cs
59 |
60 |
61 |
62 |
63 |
64 | Designer
65 | ILMonitorForm.cs
66 |
67 |
68 | Designer
69 | MiniBrowser.cs
70 |
71 |
72 | ResXFileCodeGenerator
73 | Resources.Designer.cs
74 | Designer
75 |
76 |
77 | True
78 | Resources.resx
79 | True
80 |
81 |
82 |
83 | SettingsSingleFileGenerator
84 | Settings.Designer.cs
85 |
86 |
87 | True
88 | True
89 | Settings.settings
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 | {6F6E9FC5-40A9-4ABD-89F3-EF7B6406F07B}
98 | ILDebugging.Visualizer
99 |
100 |
101 |
102 |
109 |
--------------------------------------------------------------------------------
/ILDebugging.Monitor/ILMonitorForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace ILDebugging.Monitor {
2 | partial class ILMonitorForm {
3 | ///
4 | /// Required designer variable.
5 | ///
6 | private System.ComponentModel.IContainer components = null;
7 |
8 | ///
9 | /// Clean up any resources being used.
10 | ///
11 | /// true if managed resources should be disposed; otherwise, false.
12 | protected override void Dispose(bool disposing) {
13 | if (disposing && (components != null)) {
14 | components.Dispose();
15 | }
16 | base.Dispose(disposing);
17 | }
18 |
19 | #region Windows Form Designer generated code
20 |
21 | ///
22 | /// Required method for Designer support - do not modify
23 | /// the contents of this method with the code editor.
24 | ///
25 | private void InitializeComponent() {
26 | this.components = new System.ComponentModel.Container();
27 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ILMonitorForm));
28 | this.menuStrip = new System.Windows.Forms.MenuStrip();
29 | this.fileMenu = new System.Windows.Forms.ToolStripMenuItem();
30 | this.startToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
31 | this.stopToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
32 | this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator();
33 | this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
34 | this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
35 | this.autoStartToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
36 | this.showStatusBarToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
37 | this.windowsMenu = new System.Windows.Forms.ToolStripMenuItem();
38 | this.cascadeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
39 | this.tileVerticalToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
40 | this.tileHorizontalToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
41 | this.closeAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
42 | this.arrangeIconsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
43 | this.statusStrip = new System.Windows.Forms.StatusStrip();
44 | this.toolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
45 | this.ToolTip = new System.Windows.Forms.ToolTip(this.components);
46 | this.menuStrip.SuspendLayout();
47 | this.statusStrip.SuspendLayout();
48 | this.SuspendLayout();
49 | //
50 | // menuStrip
51 | //
52 | this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
53 | this.fileMenu,
54 | this.optionsToolStripMenuItem,
55 | this.windowsMenu});
56 | this.menuStrip.Location = new System.Drawing.Point(0, 0);
57 | this.menuStrip.MdiWindowListItem = this.windowsMenu;
58 | this.menuStrip.Name = "menuStrip";
59 | this.menuStrip.Size = new System.Drawing.Size(632, 24);
60 | this.menuStrip.TabIndex = 0;
61 | this.menuStrip.Text = "MenuStrip";
62 | //
63 | // fileMenu
64 | //
65 | this.fileMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
66 | this.startToolStripMenuItem,
67 | this.stopToolStripMenuItem,
68 | this.toolStripSeparator5,
69 | this.exitToolStripMenuItem});
70 | this.fileMenu.ImageTransparentColor = System.Drawing.SystemColors.ActiveBorder;
71 | this.fileMenu.Name = "fileMenu";
72 | this.fileMenu.Size = new System.Drawing.Size(37, 20);
73 | this.fileMenu.Text = "&File";
74 | //
75 | // startToolStripMenuItem
76 | //
77 | this.startToolStripMenuItem.Name = "startToolStripMenuItem";
78 | this.startToolStripMenuItem.Size = new System.Drawing.Size(98, 22);
79 | this.startToolStripMenuItem.Text = "Start";
80 | this.startToolStripMenuItem.Click += new System.EventHandler(this.startToolStripMenuItem_Click);
81 | //
82 | // stopToolStripMenuItem
83 | //
84 | this.stopToolStripMenuItem.Enabled = false;
85 | this.stopToolStripMenuItem.Name = "stopToolStripMenuItem";
86 | this.stopToolStripMenuItem.Size = new System.Drawing.Size(98, 22);
87 | this.stopToolStripMenuItem.Text = "Stop";
88 | this.stopToolStripMenuItem.Click += new System.EventHandler(this.stopToolStripMenuItem_Click);
89 | //
90 | // toolStripSeparator5
91 | //
92 | this.toolStripSeparator5.Name = "toolStripSeparator5";
93 | this.toolStripSeparator5.Size = new System.Drawing.Size(95, 6);
94 | //
95 | // exitToolStripMenuItem
96 | //
97 | this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
98 | this.exitToolStripMenuItem.Size = new System.Drawing.Size(98, 22);
99 | this.exitToolStripMenuItem.Text = "E&xit";
100 | this.exitToolStripMenuItem.Click += new System.EventHandler(this.ExitToolsStripMenuItem_Click);
101 | //
102 | // optionsToolStripMenuItem
103 | //
104 | this.optionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
105 | this.autoStartToolStripMenuItem,
106 | this.showStatusBarToolStripMenuItem});
107 | this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
108 | this.optionsToolStripMenuItem.Size = new System.Drawing.Size(61, 20);
109 | this.optionsToolStripMenuItem.Text = "&Options";
110 | //
111 | // autoStartToolStripMenuItem
112 | //
113 | this.autoStartToolStripMenuItem.Name = "autoStartToolStripMenuItem";
114 | this.autoStartToolStripMenuItem.Size = new System.Drawing.Size(238, 22);
115 | this.autoStartToolStripMenuItem.Text = "Start Monitoring Automatically";
116 | this.autoStartToolStripMenuItem.Click += new System.EventHandler(this.autoStartToolStripMenuItem_Click);
117 | //
118 | // showStatusBarToolStripMenuItem
119 | //
120 | this.showStatusBarToolStripMenuItem.Checked = true;
121 | this.showStatusBarToolStripMenuItem.CheckOnClick = true;
122 | this.showStatusBarToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
123 | this.showStatusBarToolStripMenuItem.Name = "showStatusBarToolStripMenuItem";
124 | this.showStatusBarToolStripMenuItem.Size = new System.Drawing.Size(238, 22);
125 | this.showStatusBarToolStripMenuItem.Text = "Show Status Bar";
126 | this.showStatusBarToolStripMenuItem.Click += new System.EventHandler(this.showStatusBarToolStripMenuItem_Click);
127 | //
128 | // windowsMenu
129 | //
130 | this.windowsMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
131 | this.cascadeToolStripMenuItem,
132 | this.tileVerticalToolStripMenuItem,
133 | this.tileHorizontalToolStripMenuItem,
134 | this.closeAllToolStripMenuItem,
135 | this.arrangeIconsToolStripMenuItem});
136 | this.windowsMenu.Name = "windowsMenu";
137 | this.windowsMenu.Size = new System.Drawing.Size(68, 20);
138 | this.windowsMenu.Text = "&Windows";
139 | //
140 | // cascadeToolStripMenuItem
141 | //
142 | this.cascadeToolStripMenuItem.Name = "cascadeToolStripMenuItem";
143 | this.cascadeToolStripMenuItem.Size = new System.Drawing.Size(151, 22);
144 | this.cascadeToolStripMenuItem.Text = "&Cascade";
145 | this.cascadeToolStripMenuItem.Click += new System.EventHandler(this.CascadeToolStripMenuItem_Click);
146 | //
147 | // tileVerticalToolStripMenuItem
148 | //
149 | this.tileVerticalToolStripMenuItem.Name = "tileVerticalToolStripMenuItem";
150 | this.tileVerticalToolStripMenuItem.Size = new System.Drawing.Size(151, 22);
151 | this.tileVerticalToolStripMenuItem.Text = "Tile &Vertical";
152 | this.tileVerticalToolStripMenuItem.Click += new System.EventHandler(this.TileVerticalToolStripMenuItem_Click);
153 | //
154 | // tileHorizontalToolStripMenuItem
155 | //
156 | this.tileHorizontalToolStripMenuItem.Name = "tileHorizontalToolStripMenuItem";
157 | this.tileHorizontalToolStripMenuItem.Size = new System.Drawing.Size(151, 22);
158 | this.tileHorizontalToolStripMenuItem.Text = "Tile &Horizontal";
159 | this.tileHorizontalToolStripMenuItem.Click += new System.EventHandler(this.TileHorizontalToolStripMenuItem_Click);
160 | //
161 | // closeAllToolStripMenuItem
162 | //
163 | this.closeAllToolStripMenuItem.Name = "closeAllToolStripMenuItem";
164 | this.closeAllToolStripMenuItem.Size = new System.Drawing.Size(151, 22);
165 | this.closeAllToolStripMenuItem.Text = "C&lose All";
166 | this.closeAllToolStripMenuItem.Click += new System.EventHandler(this.CloseAllToolStripMenuItem_Click);
167 | //
168 | // arrangeIconsToolStripMenuItem
169 | //
170 | this.arrangeIconsToolStripMenuItem.Name = "arrangeIconsToolStripMenuItem";
171 | this.arrangeIconsToolStripMenuItem.Size = new System.Drawing.Size(151, 22);
172 | this.arrangeIconsToolStripMenuItem.Text = "&Arrange Icons";
173 | this.arrangeIconsToolStripMenuItem.Click += new System.EventHandler(this.ArrangeIconsToolStripMenuItem_Click);
174 | //
175 | // statusStrip
176 | //
177 | this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
178 | this.toolStripStatusLabel});
179 | this.statusStrip.Location = new System.Drawing.Point(0, 431);
180 | this.statusStrip.Name = "statusStrip";
181 | this.statusStrip.Size = new System.Drawing.Size(632, 22);
182 | this.statusStrip.TabIndex = 2;
183 | this.statusStrip.Text = "StatusStrip";
184 | //
185 | // toolStripStatusLabel
186 | //
187 | this.toolStripStatusLabel.ForeColor = System.Drawing.Color.Red;
188 | this.toolStripStatusLabel.Name = "toolStripStatusLabel";
189 | this.toolStripStatusLabel.Size = new System.Drawing.Size(90, 17);
190 | this.toolStripStatusLabel.Text = "Not monitoring";
191 | //
192 | // ILMonitorForm
193 | //
194 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
195 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
196 | this.ClientSize = new System.Drawing.Size(632, 453);
197 | this.Controls.Add(this.statusStrip);
198 | this.Controls.Add(this.menuStrip);
199 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
200 | this.IsMdiContainer = true;
201 | this.MainMenuStrip = this.menuStrip;
202 | this.Name = "ILMonitorForm";
203 | this.Text = "IL Monitor";
204 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.ILMonitorForm_FormClosing);
205 | this.Load += new System.EventHandler(this.ILMonitorForm_Load);
206 | this.menuStrip.ResumeLayout(false);
207 | this.menuStrip.PerformLayout();
208 | this.statusStrip.ResumeLayout(false);
209 | this.statusStrip.PerformLayout();
210 | this.ResumeLayout(false);
211 | this.PerformLayout();
212 |
213 | }
214 | #endregion
215 |
216 |
217 | private System.Windows.Forms.MenuStrip menuStrip;
218 | private System.Windows.Forms.StatusStrip statusStrip;
219 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator5;
220 | private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel;
221 | private System.Windows.Forms.ToolStripMenuItem tileHorizontalToolStripMenuItem;
222 | private System.Windows.Forms.ToolStripMenuItem fileMenu;
223 | private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
224 | private System.Windows.Forms.ToolStripMenuItem windowsMenu;
225 | private System.Windows.Forms.ToolStripMenuItem cascadeToolStripMenuItem;
226 | private System.Windows.Forms.ToolStripMenuItem tileVerticalToolStripMenuItem;
227 | private System.Windows.Forms.ToolStripMenuItem closeAllToolStripMenuItem;
228 | private System.Windows.Forms.ToolStripMenuItem arrangeIconsToolStripMenuItem;
229 | private System.Windows.Forms.ToolTip ToolTip;
230 | private System.Windows.Forms.ToolStripMenuItem stopToolStripMenuItem;
231 | private System.Windows.Forms.ToolStripMenuItem startToolStripMenuItem;
232 | private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem;
233 | private System.Windows.Forms.ToolStripMenuItem autoStartToolStripMenuItem;
234 | private System.Windows.Forms.ToolStripMenuItem showStatusBarToolStripMenuItem;
235 | }
236 | }
237 |
238 |
239 |
240 |
--------------------------------------------------------------------------------
/ILDebugging.Monitor/ILMonitorForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Windows.Forms;
4 | using ILDebugging.Monitor.Properties;
5 | using ILDebugging.Visualizer;
6 |
7 | namespace ILDebugging.Monitor
8 | {
9 | public partial class ILMonitorForm : Form
10 | {
11 | private AbstractXmlDataMonitor m_monitor;
12 |
13 | public ILMonitorForm()
14 | {
15 | InitializeComponent();
16 | }
17 |
18 | private void ExitToolsStripMenuItem_Click(object sender, EventArgs e) => Application.Exit();
19 |
20 | private void CascadeToolStripMenuItem_Click(object sender, EventArgs e) => LayoutMdi(MdiLayout.Cascade);
21 | private void TileVerticalToolStripMenuItem_Click(object sender, EventArgs e) => LayoutMdi(MdiLayout.TileVertical);
22 | private void TileHorizontalToolStripMenuItem_Click(object sender, EventArgs e) => LayoutMdi(MdiLayout.TileHorizontal);
23 | private void ArrangeIconsToolStripMenuItem_Click(object sender, EventArgs e) => LayoutMdi(MdiLayout.ArrangeIcons);
24 |
25 | private void CloseAllToolStripMenuItem_Click(object sender, EventArgs e)
26 | {
27 | foreach (var childForm in MdiChildren)
28 | childForm.Close();
29 | }
30 |
31 | private void ILMonitorForm_Load(object sender, EventArgs e)
32 | {
33 | m_monitor = new TcpDataMonitor(port: 22017);
34 |
35 | m_monitor.MonitorStatusChange += OnMonitorStatusChange;
36 | m_monitor.VisualizerDataReady += OnVisualizerDataReady;
37 |
38 | if (Settings.Default.AutomaticallyStart)
39 | {
40 | autoStartToolStripMenuItem.Checked = true;
41 | m_monitor.Start();
42 | }
43 | }
44 |
45 | private void OnMonitorStatusChange(object sender, MonitorStatusChangeEventArgs e)
46 | {
47 | if (e.Status == MonitorStatus.Monitoring)
48 | {
49 | toolStripStatusLabel.Text = "Monitoring";
50 | toolStripStatusLabel.ForeColor = Color.Blue;
51 | startToolStripMenuItem.Enabled = false;
52 | stopToolStripMenuItem.Enabled = true;
53 | }
54 | else
55 | {
56 | toolStripStatusLabel.Text = "Not Monitoring";
57 | toolStripStatusLabel.ForeColor = Color.Red;
58 | startToolStripMenuItem.Enabled = true;
59 | stopToolStripMenuItem.Enabled = false;
60 | }
61 | }
62 |
63 | private void OnVisualizerDataReady(object sender, VisualizerDataEventArgs e)
64 | {
65 | var mbi = e.VisualizerData;
66 | var childForm = FindOrCreateChildForm(mbi);
67 |
68 | var imbi = childForm.CurrentData != null
69 | ? IncrementalMethodBodyInfo.Create(mbi, childForm.CurrentData.LengthHistory)
70 | : IncrementalMethodBodyInfo.Create(mbi);
71 |
72 | childForm.UpdateWith(imbi);
73 | }
74 |
75 | private MiniBrowser FindOrCreateChildForm(MethodBodyInfo mbi)
76 | {
77 | foreach (var form in MdiChildren)
78 | {
79 | var miniBrowser = form as MiniBrowser;
80 |
81 | if (mbi.Identity == miniBrowser?.CurrentData?.Identity)
82 | {
83 | miniBrowser.Focus();
84 | return miniBrowser;
85 | }
86 | }
87 |
88 | var newChild = new MiniBrowser
89 | {
90 | Text = mbi.MethodToString,
91 | MdiParent = this
92 | };
93 | newChild.Show();
94 | return newChild;
95 | }
96 |
97 | private void stopToolStripMenuItem_Click(object sender, EventArgs e) => m_monitor.Stop();
98 | private void startToolStripMenuItem_Click(object sender, EventArgs e) => m_monitor.Start();
99 |
100 | private void ILMonitorForm_FormClosing(object sender, FormClosingEventArgs e)
101 | {
102 | var s = Settings.Default;
103 | s.AutomaticallyStart = autoStartToolStripMenuItem.Checked;
104 | s.Save();
105 |
106 | if (stopToolStripMenuItem.Enabled)
107 | {
108 | m_monitor.Stop();
109 | }
110 | }
111 |
112 | private void autoStartToolStripMenuItem_Click(object sender, EventArgs e)
113 | {
114 | autoStartToolStripMenuItem.Checked = !autoStartToolStripMenuItem.Checked;
115 | }
116 |
117 | private void showStatusBarToolStripMenuItem_Click(object sender, EventArgs e)
118 | {
119 | statusStrip.Visible = showStatusBarToolStripMenuItem.Checked;
120 | }
121 | }
122 | }
--------------------------------------------------------------------------------
/ILDebugging.Monitor/ILMonitorForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 218, 17
122 |
123 |
124 | 17, 17
125 |
126 |
127 | 126, 17
128 |
129 |
130 | 51
131 |
132 |
133 |
134 |
135 | AAABAAMAEBAQAAAABAAoAQAANgAAACAgEAAAAAQA6AIAAF4BAAAQEAAAAAAIAGgFAABGBAAAKAAAABAA
136 | AAAgAAAAAQAEAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAIAAAACAgACAAAAAgACAAICA
137 | AACAgIAAwMDAAAAA/wAA/wAAAP//AP8AAAD/AP8A//8AAP///wAAAAAAAAAAAAB//4/4/48AAH//j/j/
138 | jwAAeIiIiIiIAAB/d4d4d48AAH93h3h3jwAAeIiIiIiIAAB/d4d4d48AAH93h3h3jwAAeIiIiIiIAAB/
139 | d4d4d48AAH93h3h3jwAAeIiIiIAAAAB//4/49/cAAH//j/j3cAAAd3d3d3cAAMABAADAAQAAwAEAAMAB
140 | AADAAQAAwAEAAMABAADAAQAAwAEAAMABAADAAQAAwAEAAMABAADAAwAAwAcAAMAPAAAoAAAAIAAAAEAA
141 | AAABAAQAAAAAAIACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAICA
142 | gADAwMAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAB4iIiIiIiIiI
143 | iIiIiAAAAAf////4///4///4//gAAAAH////+P//+P//+P/4AAAAB/////j///j///j/+AAAAAf////4
144 | ///4///4//gAAAAH////+P//+P//+P/4AAAAB4iIiIiIiIiIiIiIiAAAAAf/eHh4eHh4eHh4//gAAAAH
145 | /4eHiIeHiIeHiP/4AAAAB/94eHh4eHh4eHj/+AAAAAf/h4eIh4eIh4eI//gAAAAH/3h4eHh4eHh4eP/4
146 | AAAAB4iIiIiIiIiIiIiIiAAAAAf/eHh4eHh4eHh4//gAAAAH/4eHiIeHiIeHiP/4AAAAB/94eHh4eHh4
147 | eHj/+AAAAAf/h4eIh4eIh4eI//gAAAAH/3h4eHh4eHh4eP/4AAAAB4iIiIiIiIiIiIiIiAAAAAf/eHh4
148 | eHh4eHh4//gAAAAH/4eHiIeHiIeHiP/4AAAAB/94eHh4eHh4eHj/+AAAAAf/h4eIh4eIh4eI//gAAAAH
149 | /3h4eHh4eHh4eP/4AAAAB4iIiIiIiIiIiHAAAAAAAAf////4///4//9/+HAAAAAH////+P//+P//f4cA
150 | AAAAB/////j///j//3hwAAAAAAf////4///4//93AAAAAAAH////+P//+P//cAAAAAAAB3d3d3d3d3d3
151 | d3AAAAAA4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AA
152 | AAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAP4AAAH+AA
153 | AD/gAAB/4AAA/+AAAf8oAAAAEAAAACAAAAABAAgAAAAAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAA
154 | gAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwADA3MAA8MqmAAQEBAAICAgADAwMABEREQAWFhYAHBwcACIi
155 | IgApKSkAVVVVAE1NTQBCQkIAOTk5AIB8/wBQUP8AkwDWAP/szADG1u8A1ufnAJCprQAAADMAAABmAAAA
156 | mQAAAMwAADMAAAAzMwAAM2YAADOZAAAzzAAAM/8AAGYAAABmMwAAZmYAAGaZAABmzAAAZv8AAJkAAACZ
157 | MwAAmWYAAJmZAACZzAAAmf8AAMwAAADMMwAAzGYAAMyZAADMzAAAzP8AAP9mAAD/mQAA/8wAMwAAADMA
158 | MwAzAGYAMwCZADMAzAAzAP8AMzMAADMzMwAzM2YAMzOZADMzzAAzM/8AM2YAADNmMwAzZmYAM2aZADNm
159 | zAAzZv8AM5kAADOZMwAzmWYAM5mZADOZzAAzmf8AM8wAADPMMwAzzGYAM8yZADPMzAAzzP8AM/8zADP/
160 | ZgAz/5kAM//MADP//wBmAAAAZgAzAGYAZgBmAJkAZgDMAGYA/wBmMwAAZjMzAGYzZgBmM5kAZjPMAGYz
161 | /wBmZgAAZmYzAGZmZgBmZpkAZmbMAGaZAABmmTMAZplmAGaZmQBmmcwAZpn/AGbMAABmzDMAZsyZAGbM
162 | zABmzP8AZv8AAGb/MwBm/5kAZv/MAMwA/wD/AMwAmZkAAJkzmQCZAJkAmQDMAJkAAACZMzMAmQBmAJkz
163 | zACZAP8AmWYAAJlmMwCZM2YAmWaZAJlmzACZM/8AmZkzAJmZZgCZmZkAmZnMAJmZ/wCZzAAAmcwzAGbM
164 | ZgCZzJkAmczMAJnM/wCZ/wAAmf8zAJnMZgCZ/5kAmf/MAJn//wDMAAAAmQAzAMwAZgDMAJkAzADMAJkz
165 | AADMMzMAzDNmAMwzmQDMM8wAzDP/AMxmAADMZjMAmWZmAMxmmQDMZswAmWb/AMyZAADMmTMAzJlmAMyZ
166 | mQDMmcwAzJn/AMzMAADMzDMAzMxmAMzMmQDMzMwAzMz/AMz/AADM/zMAmf9mAMz/mQDM/8wAzP//AMwA
167 | MwD/AGYA/wCZAMwzAAD/MzMA/zNmAP8zmQD/M8wA/zP/AP9mAAD/ZjMAzGZmAP9mmQD/ZswAzGb/AP+Z
168 | AAD/mTMA/5lmAP+ZmQD/mcwA/5n/AP/MAAD/zDMA/8xmAP/MmQD/zMwA/8z/AP//MwDM/2YA//+ZAP//
169 | zABmZv8AZv9mAGb//wD/ZmYA/2b/AP//ZgAhAKUAX19fAHd3dwCGhoYAlpaWAMvLywCysrIA19fXAN3d
170 | 3QDj4+MA6urqAPHx8QD4+PgA8Pv/AKSgoACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAoK
171 | CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgUFBQUFBQUFBQUKCgoKCgUFBQUFBQUFBQUF
172 | CgoKCqurq6urq6urq6sFBQoKCgqrq6v//////6urBQUKCgoKq6v//6ur//+rqwUFCgoKCqur//+rq///
173 | q6sFBQoKCgqrq///q6v//6urBQUKCgoKq6v//6ur//+rqwUFCgoKCqurq///////q6sFBQoKCgqrq6ur
174 | q6v//6urBQoKCgoKq6urq6ur//+rqwUKCgoKCqurq6urq///q6sKCgoKCgoKCgoKCgoKCgoKCgoKCgoK
175 | CgoKCgoKCgoKCgoKCgr//wAA//8AAPADAADgAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMAH
176 | AADABwAAwA8AAP//AAD//wAA
177 |
178 |
179 |
--------------------------------------------------------------------------------
/ILDebugging.Monitor/IncrementalData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using ILDebugging.Visualizer;
5 |
6 | namespace ILDebugging.Monitor
7 | {
8 | [Serializable]
9 | public class IncrementalMethodBodyInfo
10 | {
11 | [Serializable]
12 | public class AgingInstruction
13 | {
14 | public int Age;
15 | public string ILString;
16 | }
17 |
18 | public int Identity;
19 | public string TypeName;
20 | public AgingInstruction[] Instructions;
21 | public string MethodToString;
22 |
23 | // hidden field
24 | public List LengthHistory;
25 |
26 | public static IncrementalMethodBodyInfo Create(MethodBodyInfo mbi, IEnumerable history = null)
27 | {
28 | var imbi = new IncrementalMethodBodyInfo
29 | {
30 | Identity = mbi.Identity,
31 | TypeName = mbi.TypeName,
32 | MethodToString = mbi.MethodToString,
33 | Instructions = mbi.Instructions.Select(i => new AgingInstruction {ILString = i}).ToArray(),
34 | LengthHistory = new List(history ?? Enumerable.Empty()) {mbi.Instructions.Count}
35 | };
36 |
37 | for (var i = 0; i < imbi.LengthHistory.Count - 1; i++)
38 | {
39 | for (var a = imbi.LengthHistory[i]; a < imbi.LengthHistory[i + 1]; a++)
40 | {
41 | imbi.Instructions[a].Age = i + 1;
42 | }
43 | }
44 |
45 | return imbi;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/ILDebugging.Monitor/MiniBrowser.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace ILDebugging.Monitor {
2 | partial class MiniBrowser {
3 | ///
4 | /// Required designer variable.
5 | ///
6 | private System.ComponentModel.IContainer components = null;
7 |
8 | ///
9 | /// Clean up any resources being used.
10 | ///
11 | /// true if managed resources should be disposed; otherwise, false.
12 | protected override void Dispose(bool disposing) {
13 | if (disposing && (components != null)) {
14 | components.Dispose();
15 | }
16 | base.Dispose(disposing);
17 | }
18 |
19 | #region Windows Form Designer generated code
20 |
21 | ///
22 | /// Required method for Designer support - do not modify
23 | /// the contents of this method with the code editor.
24 | ///
25 | private void InitializeComponent() {
26 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MiniBrowser));
27 | this.webBrowser = new System.Windows.Forms.WebBrowser();
28 | this.SuspendLayout();
29 | //
30 | // webBrowser
31 | //
32 | this.webBrowser.Dock = System.Windows.Forms.DockStyle.Fill;
33 | this.webBrowser.Location = new System.Drawing.Point(0, 0);
34 | this.webBrowser.MinimumSize = new System.Drawing.Size(20, 20);
35 | this.webBrowser.Name = "webBrowser";
36 | this.webBrowser.Size = new System.Drawing.Size(284, 264);
37 | this.webBrowser.TabIndex = 0;
38 | //
39 | // MiniBrowser
40 | //
41 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
42 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
43 | this.ClientSize = new System.Drawing.Size(284, 264);
44 | this.Controls.Add(this.webBrowser);
45 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
46 | this.Name = "MiniBrowser";
47 | this.Text = "ILStream";
48 | this.ResumeLayout(false);
49 |
50 | }
51 |
52 | #endregion
53 |
54 | private System.Windows.Forms.WebBrowser webBrowser;
55 | }
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/ILDebugging.Monitor/MiniBrowser.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Windows.Forms;
3 | using System.Xml;
4 | using System.Xml.Serialization;
5 | using System.Xml.Xsl;
6 | using ILDebugging.Monitor.Properties;
7 |
8 | namespace ILDebugging.Monitor
9 | {
10 | public partial class MiniBrowser : Form
11 | {
12 | public MiniBrowser()
13 | {
14 | InitializeComponent();
15 | }
16 |
17 | public IncrementalMethodBodyInfo CurrentData { get; private set; }
18 |
19 | public void UpdateWith(IncrementalMethodBodyInfo imbi)
20 | {
21 | CurrentData = imbi;
22 |
23 | var xslt = new XslCompiledTransform();
24 | using (var sr = new StringReader(Resources.XSLT))
25 | {
26 | using (var xtr = new XmlTextReader(sr))
27 | {
28 | xslt.Load(xtr);
29 | }
30 | }
31 |
32 | var serializer = new XmlSerializer(typeof(IncrementalMethodBodyInfo));
33 | using (var beforeTransform = new MemoryStream())
34 | {
35 | var afterTransform = new MemoryStream();
36 | serializer.Serialize(beforeTransform, CurrentData);
37 |
38 | beforeTransform.Position = 0;
39 | using (var reader = new XmlTextReader(beforeTransform))
40 | {
41 | xslt.Transform(reader, null, afterTransform);
42 | }
43 |
44 | afterTransform.Position = 0;
45 | webBrowser.DocumentStream = afterTransform;
46 | }
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/ILDebugging.Monitor/MiniBrowser.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 |
123 | AAABAAMAEBAQAAAABAAoAQAANgAAACAgEAAAAAQA6AIAAF4BAAAQEAAAAAAIAGgFAABGBAAAKAAAABAA
124 | AAAgAAAAAQAEAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAIAAAACAgACAAAAAgACAAICA
125 | AACAgIAAwMDAAAAA/wAA/wAAAP//AP8AAAD/AP8A//8AAP///wAAAAAAAAAAAAB//4/4/48AAH//j/j/
126 | jwAAeIiIiIiIAAB/d4d4d48AAH93h3h3jwAAeIiIiIiIAAB/d4d4d48AAH93h3h3jwAAeIiIiIiIAAB/
127 | d4d4d48AAH93h3h3jwAAeIiIiIAAAAB//4/49/cAAH//j/j3cAAAd3d3d3cAAMABAADAAQAAwAEAAMAB
128 | AADAAQAAwAEAAMABAADAAQAAwAEAAMABAADAAQAAwAEAAMABAADAAwAAwAcAAMAPAAAoAAAAIAAAAEAA
129 | AAABAAQAAAAAAIACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAICA
130 | gADAwMAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAB4iIiIiIiIiI
131 | iIiIiAAAAAf////4///4///4//gAAAAH////+P//+P//+P/4AAAAB/////j///j///j/+AAAAAf////4
132 | ///4///4//gAAAAH////+P//+P//+P/4AAAAB4iIiIiIiIiIiIiIiAAAAAf/eHh4eHh4eHh4//gAAAAH
133 | /4eHiIeHiIeHiP/4AAAAB/94eHh4eHh4eHj/+AAAAAf/h4eIh4eIh4eI//gAAAAH/3h4eHh4eHh4eP/4
134 | AAAAB4iIiIiIiIiIiIiIiAAAAAf/eHh4eHh4eHh4//gAAAAH/4eHiIeHiIeHiP/4AAAAB/94eHh4eHh4
135 | eHj/+AAAAAf/h4eIh4eIh4eI//gAAAAH/3h4eHh4eHh4eP/4AAAAB4iIiIiIiIiIiIiIiAAAAAf/eHh4
136 | eHh4eHh4//gAAAAH/4eHiIeHiIeHiP/4AAAAB/94eHh4eHh4eHj/+AAAAAf/h4eIh4eIh4eI//gAAAAH
137 | /3h4eHh4eHh4eP/4AAAAB4iIiIiIiIiIiHAAAAAAAAf////4///4//9/+HAAAAAH////+P//+P//f4cA
138 | AAAAB/////j///j//3hwAAAAAAf////4///4//93AAAAAAAH////+P//+P//cAAAAAAAB3d3d3d3d3d3
139 | d3AAAAAA4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AA
140 | AAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAP4AAAH+AA
141 | AD/gAAB/4AAA/+AAAf8oAAAAEAAAACAAAAABAAgAAAAAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAA
142 | gAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwADA3MAA8MqmAAQEBAAICAgADAwMABEREQAWFhYAHBwcACIi
143 | IgApKSkAVVVVAE1NTQBCQkIAOTk5AIB8/wBQUP8AkwDWAP/szADG1u8A1ufnAJCprQAAADMAAABmAAAA
144 | mQAAAMwAADMAAAAzMwAAM2YAADOZAAAzzAAAM/8AAGYAAABmMwAAZmYAAGaZAABmzAAAZv8AAJkAAACZ
145 | MwAAmWYAAJmZAACZzAAAmf8AAMwAAADMMwAAzGYAAMyZAADMzAAAzP8AAP9mAAD/mQAA/8wAMwAAADMA
146 | MwAzAGYAMwCZADMAzAAzAP8AMzMAADMzMwAzM2YAMzOZADMzzAAzM/8AM2YAADNmMwAzZmYAM2aZADNm
147 | zAAzZv8AM5kAADOZMwAzmWYAM5mZADOZzAAzmf8AM8wAADPMMwAzzGYAM8yZADPMzAAzzP8AM/8zADP/
148 | ZgAz/5kAM//MADP//wBmAAAAZgAzAGYAZgBmAJkAZgDMAGYA/wBmMwAAZjMzAGYzZgBmM5kAZjPMAGYz
149 | /wBmZgAAZmYzAGZmZgBmZpkAZmbMAGaZAABmmTMAZplmAGaZmQBmmcwAZpn/AGbMAABmzDMAZsyZAGbM
150 | zABmzP8AZv8AAGb/MwBm/5kAZv/MAMwA/wD/AMwAmZkAAJkzmQCZAJkAmQDMAJkAAACZMzMAmQBmAJkz
151 | zACZAP8AmWYAAJlmMwCZM2YAmWaZAJlmzACZM/8AmZkzAJmZZgCZmZkAmZnMAJmZ/wCZzAAAmcwzAGbM
152 | ZgCZzJkAmczMAJnM/wCZ/wAAmf8zAJnMZgCZ/5kAmf/MAJn//wDMAAAAmQAzAMwAZgDMAJkAzADMAJkz
153 | AADMMzMAzDNmAMwzmQDMM8wAzDP/AMxmAADMZjMAmWZmAMxmmQDMZswAmWb/AMyZAADMmTMAzJlmAMyZ
154 | mQDMmcwAzJn/AMzMAADMzDMAzMxmAMzMmQDMzMwAzMz/AMz/AADM/zMAmf9mAMz/mQDM/8wAzP//AMwA
155 | MwD/AGYA/wCZAMwzAAD/MzMA/zNmAP8zmQD/M8wA/zP/AP9mAAD/ZjMAzGZmAP9mmQD/ZswAzGb/AP+Z
156 | AAD/mTMA/5lmAP+ZmQD/mcwA/5n/AP/MAAD/zDMA/8xmAP/MmQD/zMwA/8z/AP//MwDM/2YA//+ZAP//
157 | zABmZv8AZv9mAGb//wD/ZmYA/2b/AP//ZgAhAKUAX19fAHd3dwCGhoYAlpaWAMvLywCysrIA19fXAN3d
158 | 3QDj4+MA6urqAPHx8QD4+PgA8Pv/AKSgoACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAoK
159 | CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgUFBQUFBQUFBQUKCgoKCgUFBQUFBQUFBQUF
160 | CgoKCqurq6urq6urq6sFBQoKCgqrq6v//////6urBQUKCgoKq6v//6ur//+rqwUFCgoKCqur//+rq///
161 | q6sFBQoKCgqrq///q6v//6urBQUKCgoKq6v//6ur//+rqwUFCgoKCqurq///////q6sFBQoKCgqrq6ur
162 | q6v//6urBQoKCgoKq6urq6ur//+rqwUKCgoKCqurq6urq///q6sKCgoKCgoKCgoKCgoKCgoKCgoKCgoK
163 | CgoKCgoKCgoKCgoKCgr//wAA//8AAPADAADgAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMAH
164 | AADABwAAwA8AAP//AAD//wAA
165 |
166 |
167 |
--------------------------------------------------------------------------------
/ILDebugging.Monitor/MonitorHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.IO;
4 | using System.Net;
5 | using System.Net.Sockets;
6 | using System.Threading;
7 | using System.Windows.Forms;
8 | using System.Xml.Serialization;
9 |
10 | namespace ILDebugging.Monitor
11 | {
12 | public class VisualizerDataEventArgs : EventArgs
13 | {
14 | public readonly T VisualizerData;
15 |
16 | public VisualizerDataEventArgs(T data)
17 | {
18 | VisualizerData = data;
19 | }
20 | }
21 |
22 | public class MonitorStatusChangeEventArgs : EventArgs
23 | {
24 | public readonly MonitorStatus Status;
25 |
26 | public MonitorStatusChangeEventArgs(MonitorStatus status)
27 | {
28 | Status = status;
29 | }
30 | }
31 |
32 | public enum MonitorStatus
33 | {
34 | NotMonitoring,
35 | Monitoring
36 | }
37 |
38 | public abstract class AbstractXmlDataMonitor
39 | {
40 | public abstract void Start();
41 | public abstract void Stop();
42 |
43 | public delegate void VisualizerDataReadyEventHandler(object sender, VisualizerDataEventArgs e);
44 |
45 | public delegate void MonitorStatusChangeEventHandler(object sender, MonitorStatusChangeEventArgs e);
46 |
47 | public event VisualizerDataReadyEventHandler VisualizerDataReady;
48 | public event MonitorStatusChangeEventHandler MonitorStatusChange;
49 |
50 | protected void FireStatusChangeEvent(MonitorStatus status)
51 | {
52 | if (MonitorStatusChange != null)
53 | {
54 | var args = new MonitorStatusChangeEventArgs(status);
55 |
56 | if (MonitorStatusChange.Target is Control targetCtrl)
57 | {
58 | targetCtrl.Invoke(MonitorStatusChange, this, args);
59 | }
60 | else
61 | {
62 | MonitorStatusChange(this, args);
63 | }
64 | }
65 | }
66 |
67 | protected void FireDataReadyEvent(T data)
68 | {
69 | if (VisualizerDataReady != null)
70 | {
71 | var args = new VisualizerDataEventArgs(data);
72 |
73 | if (VisualizerDataReady.Target is Control targetCtrl)
74 | {
75 | targetCtrl.Invoke(VisualizerDataReady, this, args);
76 | }
77 | else
78 | {
79 | VisualizerDataReady(this, args);
80 | }
81 | }
82 | }
83 | }
84 |
85 | public class TcpDataMonitor : AbstractXmlDataMonitor
86 | {
87 | private TcpListener m_listener;
88 | private Thread m_listenerThread;
89 | private readonly int m_port;
90 |
91 | public TcpDataMonitor(int port)
92 | {
93 | m_port = port;
94 | }
95 |
96 | private void ListenerThread()
97 | {
98 | m_listener = new TcpListener(IPAddress.Parse("127.0.0.1"), m_port);
99 | m_listener.Start();
100 |
101 | try
102 | {
103 | while (true)
104 | {
105 | while (!m_listener.Pending())
106 | {
107 | Thread.Sleep(1000);
108 | }
109 | var client = m_listener.AcceptTcpClient();
110 | ThreadPool.QueueUserWorkItem(delegate { HandleConnection(client); });
111 | }
112 | }
113 | catch (Exception ex)
114 | {
115 | Debug.WriteLine(ex);
116 | }
117 | finally
118 | {
119 | m_listener.Stop();
120 | }
121 | }
122 |
123 | private void HandleConnection(TcpClient client)
124 | {
125 | using (client)
126 | using (var network = client.GetStream())
127 | {
128 | var memory = new MemoryStream();
129 | var buffer = new byte[1024];
130 |
131 | while (true)
132 | {
133 | var received = network.Read(buffer, 0, 1024);
134 | if (received == 0)
135 | break;
136 | memory.Write(buffer, 0, received);
137 | }
138 |
139 | memory.Position = 0;
140 |
141 | var data = (T)new XmlSerializer(typeof(T)).Deserialize(memory);
142 |
143 | FireDataReadyEvent(data);
144 | }
145 | }
146 |
147 | public override void Start()
148 | {
149 | m_listenerThread = new Thread(ListenerThread);
150 | m_listenerThread.Start();
151 | FireStatusChangeEvent(MonitorStatus.Monitoring);
152 | }
153 |
154 | public override void Stop()
155 | {
156 | m_listenerThread.Abort();
157 | FireStatusChangeEvent(MonitorStatus.NotMonitoring);
158 | }
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/ILDebugging.Monitor/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms;
3 |
4 | namespace ILDebugging.Monitor
5 | {
6 | internal static class Program
7 | {
8 | [STAThread]
9 | private static void Main()
10 | {
11 | Application.EnableVisualStyles();
12 | Application.SetCompatibleTextRenderingDefault(false);
13 | Application.Run(new ILMonitorForm());
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/ILDebugging.Monitor/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 |
8 | [assembly: AssemblyTitle("ILDebugging.Monitor")]
9 | [assembly: AssemblyDescription("Receives and displays IL data from debuggees.")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Microsoft")]
12 | [assembly: AssemblyProduct("ILDebugging.Monitor")]
13 | [assembly: AssemblyCopyright("Copyright © 2006")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 |
21 | [assembly: ComVisible(false)]
22 |
23 | // The following GUID is for the ID of the typelib if this project is exposed to COM
24 |
25 | [assembly: Guid("b617795a-39df-4022-a9eb-c0caa098bdaf")]
26 |
27 | // Version information for an assembly consists of the following four values:
28 | //
29 | // Major Version
30 | // Minor Version
31 | // Build Number
32 | // Revision
33 | //
34 |
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
--------------------------------------------------------------------------------
/ILDebugging.Monitor/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace ILDebugging.Monitor.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ILDebugging.Monitor.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized string similar to <?xml version="1.0" encoding="UTF-8" ?>
65 | ///<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
66 | /// <xsl:output method="html"/>
67 | ///
68 | /// <xsl:attribute-set name="alternate">
69 | /// <xsl:attribute name="class">
70 | /// <xsl:apply-templates select="." mode="alternate"/>
71 | /// </xsl:attribute>
72 | /// </xsl:attribute-set>
73 | ///
74 | /// <xsl:template match="AgingInstruction" mode="alternate">
75 | /// <xsl:choose>
76 | /// <xsl:when test="Age mod 3 = 0">first</xsl:when>
77 | /// <xsl:when test="Age mod 3 = 1">second< [rest of string was truncated]";.
78 | ///
79 | internal static string XSLT {
80 | get {
81 | return ResourceManager.GetString("XSLT", resourceCulture);
82 | }
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/ILDebugging.Monitor/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | ..\Resources\XSLT.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252
123 |
124 |
--------------------------------------------------------------------------------
/ILDebugging.Monitor/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace ILDebugging.Monitor.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.5.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 |
26 | [global::System.Configuration.UserScopedSettingAttribute()]
27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
28 | [global::System.Configuration.DefaultSettingValueAttribute("True")]
29 | public bool AutomaticallyStart {
30 | get {
31 | return ((bool)(this["AutomaticallyStart"]));
32 | }
33 | set {
34 | this["AutomaticallyStart"] = value;
35 | }
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/ILDebugging.Monitor/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 | True
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ILDebugging.Monitor/Resources/XSLT.txt:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | first
14 | second
15 | third
16 |
17 |
18 |
19 |
20 |
21 |
22 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | |
83 |
84 |
85 | |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/ILDebugging.Monitor/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/ILDebugging.Sample/ILDebugging.Sample.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.50727
7 | 2.0
8 | {5BF03C0A-2F42-4538-B373-8B2BE569350A}
9 | Exe
10 | Properties
11 | ILDebugging.Sample
12 | ILDebugging.Sample
13 | v4.6
14 |
15 |
16 |
17 |
18 | 2.0
19 | publish\
20 | true
21 | Disk
22 | false
23 | Foreground
24 | 7
25 | Days
26 | false
27 | false
28 | true
29 | 0
30 | 1.0.0.%2a
31 | false
32 | false
33 | true
34 |
35 |
36 |
37 | true
38 | full
39 | false
40 | bin\Debug\
41 | DEBUG;TRACE
42 | prompt
43 | 4
44 | false
45 |
46 |
47 | pdbonly
48 | true
49 | bin\Release\
50 | TRACE
51 | prompt
52 | 4
53 | false
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 | {6F6E9FC5-40A9-4ABD-89F3-EF7B6406F07B}
66 | ILDebugging.Visualizer
67 |
68 |
69 |
70 |
71 | False
72 | .NET Framework 3.5 SP1 Client Profile
73 | false
74 |
75 |
76 | False
77 | .NET Framework 3.5 SP1
78 | true
79 |
80 |
81 | False
82 | Windows Installer 3.1
83 | true
84 |
85 |
86 |
87 |
88 |
89 |
90 |
97 |
--------------------------------------------------------------------------------
/ILDebugging.Sample/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection.Emit;
3 | using System.Runtime.CompilerServices;
4 | using ILDebugging.Visualizer;
5 | using Microsoft.VisualStudio.DebuggerVisualizers;
6 |
7 | namespace ILDebugging.Sample
8 | {
9 | internal class Foo
10 | {
11 | [MethodImpl(MethodImplOptions.NoInlining)]
12 | public string MyMethod(string x)
13 | {
14 | Console.WriteLine(x);
15 | return x;
16 | }
17 | }
18 |
19 | internal class Program
20 | {
21 | private static void Main()
22 | {
23 | var dm = new DynamicMethod("MyMethodWrapper", typeof(object), new[] {typeof(object[])}, typeof(Program), skipVisibility: true);
24 | var il = dm.GetILGenerator();
25 | var l1 = il.DefineLabel();
26 | var returnLocal = il.DeclareLocal(typeof(object));
27 |
28 | // grab the method parameters of the method we wish to wrap
29 | var method = typeof(Foo).GetMethod(nameof(Foo.MyMethod));
30 | var methodParameters = method.GetParameters();
31 | var parameterLength = methodParameters.Length;
32 |
33 | // check to see if the call to MyMethodWrapper has the required amount of arguments in the object[] array.
34 | il.Emit(OpCodes.Ldarg_0);
35 | il.Emit(OpCodes.Ldlen);
36 | il.Emit(OpCodes.Conv_I4);
37 | il.Emit(OpCodes.Ldc_I4, parameterLength + 1);
38 | il.Emit(OpCodes.Beq_S, l1);
39 | il.Emit(OpCodes.Ldstr, "insufficient arguments");
40 | il.Emit(OpCodes.Newobj, typeof(ArgumentException).GetConstructor(new[] {typeof(string)}));
41 | il.Emit(OpCodes.Throw);
42 | il.MarkLabel(l1);
43 |
44 | // pull out the Foo instance from the first element in the object[] args array
45 | il.Emit(OpCodes.Ldarg_0);
46 | il.Emit(OpCodes.Ldc_I4_0);
47 | il.Emit(OpCodes.Ldelem_Ref);
48 | // cast the instance to Foo
49 | il.Emit(OpCodes.Castclass, typeof(Foo));
50 |
51 | // pull out the parameters to the instance method call and push them on to the IL stack
52 | for (var i = 0; i < parameterLength; i++)
53 | {
54 | il.Emit(OpCodes.Ldarg_0);
55 | il.Emit(OpCodes.Ldc_I4, i + 1);
56 | il.Emit(OpCodes.Ldelem_Ref);
57 |
58 | // we've special cased it, for this code example
59 | if (methodParameters[i].ParameterType == typeof(string))
60 | {
61 | il.Emit(OpCodes.Castclass, typeof(string));
62 | }
63 |
64 | // test or switch on parameter types, you'll need to cast to the respective type
65 | // ...
66 | }
67 |
68 | // call the wrapped method
69 | il.Emit(OpCodes.Call, method);
70 | // return what the method invocation returned
71 | il.Emit(OpCodes.Stloc, returnLocal);
72 | il.Emit(OpCodes.Ldloc, returnLocal);
73 | il.Emit(OpCodes.Ret);
74 |
75 | // Show the visualizer (via code)
76 | var developmentHost = new VisualizerDevelopmentHost(
77 | dm,
78 | typeof(MethodBodyVisualizer),
79 | typeof(MethodBodyObjectSource)
80 | );
81 |
82 | developmentHost.ShowVisualizer();
83 | }
84 | }
85 | }
--------------------------------------------------------------------------------
/ILDebugging.Sample/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 |
8 | [assembly: AssemblyTitle("ILDebugging.Sample")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Microsoft")]
12 | [assembly: AssemblyProduct("")]
13 | [assembly: AssemblyCopyright("Copyright © 2006")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 |
21 | [assembly: ComVisible(false)]
22 |
23 | // The following GUID is for the ID of the typelib if this project is exposed to COM
24 |
25 | [assembly: Guid("9d0aaae6-e8ce-48b2-a7ad-adb788ac2ee4")]
26 |
27 | // Version information for an assembly consists of the following four values:
28 | //
29 | // Major Version
30 | // Minor Version
31 | // Build Number
32 | // Revision
33 | //
34 |
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
--------------------------------------------------------------------------------
/ILDebugging.Sample/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/ILDebugging.Visualizer/ILDebugging.Visualizer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.50727
7 | 2.0
8 | {6F6E9FC5-40A9-4ABD-89F3-EF7B6406F07B}
9 | Library
10 | Properties
11 | ILDebugging.Visualizer
12 | ILDebugging.Visualizer
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | 3.5
26 | v4.6
27 | publish\
28 | true
29 | Disk
30 | false
31 | Foreground
32 | 7
33 | Days
34 | false
35 | false
36 | true
37 | 0
38 | 1.0.0.%2a
39 | false
40 | false
41 | true
42 |
43 |
44 |
45 | true
46 | full
47 | false
48 | bin\debug\
49 | DEBUG;TRACE
50 | prompt
51 | 4
52 | false
53 |
54 |
55 | pdbonly
56 | true
57 | bin\Release\
58 | TRACE
59 | prompt
60 | 4
61 | false
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | Form
77 |
78 |
79 | MethodBodyViewer.cs
80 |
81 |
82 |
83 | True
84 | True
85 | Settings.settings
86 |
87 |
88 | True
89 | True
90 | Resource.resx
91 |
92 |
93 |
94 |
95 | Designer
96 | MethodBodyViewer.cs
97 |
98 |
99 | Designer
100 | ResXFileCodeGenerator
101 | Resource.Designer.cs
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | SettingsSingleFileGenerator
110 | Settings.Designer.cs
111 |
112 |
113 |
114 |
115 | {3B40E8C3-C4E8-4085-9F82-F64308F3791C}
116 | ILDebugging.Decoder
117 |
118 |
119 |
120 |
121 | False
122 | .NET Framework 3.5 SP1 Client Profile
123 | false
124 |
125 |
126 | False
127 | .NET Framework 3.5 SP1
128 | true
129 |
130 |
131 | False
132 | Windows Installer 3.1
133 | true
134 |
135 |
136 |
137 |
144 |
145 |
146 |
147 |
148 |
--------------------------------------------------------------------------------
/ILDebugging.Visualizer/MethodBodyInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Reflection;
4 | using ILDebugging.Decoder;
5 |
6 | namespace ILDebugging.Visualizer
7 | {
8 | [Serializable]
9 | public class MethodBodyInfo
10 | {
11 | public int Identity { get; set; }
12 | public string TypeName { get; set; }
13 | public string MethodToString { get; set; }
14 | public List Instructions { get; } = new List();
15 |
16 | private void AddInstruction(string inst)
17 | {
18 | Instructions.Add(inst);
19 | }
20 |
21 | public static MethodBodyInfo Create(MethodBase method)
22 | {
23 | var mbi = new MethodBodyInfo
24 | {
25 | Identity = method.GetHashCode(),
26 | TypeName = method.GetType().Name,
27 | MethodToString = method.ToString()
28 | };
29 |
30 | var visitor = new ReadableILStringVisitor(
31 | new MethodBodyInfoBuilder(mbi),
32 | DefaultFormatProvider.Instance);
33 |
34 | var reader = ILReaderFactory.Create(method);
35 | reader.Accept(visitor);
36 |
37 | return mbi;
38 | }
39 |
40 | private class MethodBodyInfoBuilder : IILStringCollector
41 | {
42 | private readonly MethodBodyInfo m_mbi;
43 |
44 | public MethodBodyInfoBuilder(MethodBodyInfo mbi)
45 | {
46 | m_mbi = mbi;
47 | }
48 |
49 | public void Process(ILInstruction instruction, string operandString)
50 | {
51 | m_mbi.AddInstruction($"IL_{instruction.Offset:x4}: {instruction.OpCode.Name,-10} {operandString}");
52 | }
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/ILDebugging.Visualizer/MethodBodyNoVisualizer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.IO;
4 | using System.Net;
5 | using System.Net.Sockets;
6 | using System.Reflection;
7 | using System.Runtime.Serialization.Formatters.Binary;
8 | using System.Windows.Forms;
9 | using System.Xml.Serialization;
10 | using ILDebugging.Visualizer;
11 | using Microsoft.VisualStudio.DebuggerVisualizers;
12 |
13 | [assembly: DebuggerVisualizer(
14 | typeof(MethodBodyNoVisualizer),
15 | typeof(MethodBodyObjectSource),
16 | Target = typeof(MethodBase),
17 | Description = "Send to IL Monitor")
18 | ]
19 |
20 | namespace ILDebugging.Visualizer
21 | {
22 | internal interface IXmlDataProvider
23 | {
24 | void Dump(T obj);
25 | }
26 |
27 | internal class TcpClientDataProvider : IXmlDataProvider
28 | {
29 | private readonly int m_portNumber;
30 |
31 | public TcpClientDataProvider(int port)
32 | {
33 | m_portNumber = port;
34 | }
35 |
36 | public void Dump(MethodBodyInfo mbi)
37 | {
38 | using (var tcpClient = new TcpClient())
39 | {
40 | tcpClient.Connect(IPAddress.Parse("127.0.0.1"), m_portNumber);
41 |
42 | var memoryStream = new MemoryStream();
43 | new XmlSerializer(typeof(MethodBodyInfo)).Serialize(memoryStream, mbi);
44 |
45 | memoryStream.Position = 0;
46 |
47 | using (var networkStream = tcpClient.GetStream())
48 | memoryStream.CopyTo(networkStream);
49 | }
50 | }
51 | }
52 |
53 | public class MethodBodyNoVisualizer : DialogDebuggerVisualizer
54 | {
55 | protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)
56 | {
57 | try
58 | {
59 | MethodBodyInfo mbi;
60 | using (var output = objectProvider.GetData())
61 | mbi = (MethodBodyInfo)new BinaryFormatter().Deserialize(output, null);
62 |
63 | IXmlDataProvider provider = new TcpClientDataProvider(port: 22017);
64 | provider.Dump(mbi);
65 | }
66 | catch (Exception ex)
67 | {
68 | MessageBox.Show(ex.Message,
69 | "Send to IL Monitor",
70 | MessageBoxButtons.OK,
71 | MessageBoxIcon.Error);
72 | }
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/ILDebugging.Visualizer/MethodBodyObjectSource.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Reflection;
4 | using System.Runtime.Serialization.Formatters.Binary;
5 | using Microsoft.VisualStudio.DebuggerVisualizers;
6 |
7 | namespace ILDebugging.Visualizer
8 | {
9 | public class MethodBodyObjectSource : VisualizerObjectSource
10 | {
11 | public override void GetData(object target, Stream outgoingData)
12 | {
13 | if (target is MethodBase method)
14 | {
15 | try
16 | {
17 | var mbi = MethodBodyInfo.Create(method);
18 |
19 | var formatter = new BinaryFormatter();
20 | formatter.Serialize(outgoingData, mbi);
21 | }
22 | catch (Exception)
23 | {
24 | }
25 | }
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/ILDebugging.Visualizer/MethodBodyViewer.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace ILDebugging.Visualizer {
2 | partial class MethodBodyViewer {
3 | ///
4 | /// Required designer variable.
5 | ///
6 | private System.ComponentModel.IContainer components = null;
7 |
8 | ///
9 | /// Clean up any resources being used.
10 | ///
11 | /// true if managed resources should be disposed; otherwise, false.
12 | protected override void Dispose(bool disposing) {
13 | if (disposing && (components != null)) {
14 | components.Dispose();
15 | }
16 | base.Dispose(disposing);
17 | }
18 |
19 | #region Windows Form Designer generated code
20 |
21 | ///
22 | /// Required method for Designer support - do not modify
23 | /// the contents of this method with the code editor.
24 | ///
25 | private void InitializeComponent() {
26 | this.components = new System.ComponentModel.Container();
27 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MethodBodyViewer));
28 | this.panel3 = new System.Windows.Forms.Panel();
29 | this.lblMethodToString = new System.Windows.Forms.Label();
30 | this.lblMethodGetType = new System.Windows.Forms.Label();
31 | this.panel2 = new System.Windows.Forms.Panel();
32 | this.richTextBox = new System.Windows.Forms.RichTextBox();
33 | this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
34 | this.fontNameToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
35 | this.fontSizeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
36 | this.panel3.SuspendLayout();
37 | this.panel2.SuspendLayout();
38 | this.contextMenuStrip.SuspendLayout();
39 | this.SuspendLayout();
40 | //
41 | // panel3
42 | //
43 | this.panel3.Controls.Add(this.lblMethodToString);
44 | this.panel3.Controls.Add(this.lblMethodGetType);
45 | this.panel3.Dock = System.Windows.Forms.DockStyle.Top;
46 | this.panel3.Location = new System.Drawing.Point(0, 0);
47 | this.panel3.Name = "panel3";
48 | this.panel3.Size = new System.Drawing.Size(492, 25);
49 | this.panel3.TabIndex = 7;
50 | //
51 | // lblMethodToString
52 | //
53 | this.lblMethodToString.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
54 | | System.Windows.Forms.AnchorStyles.Right)));
55 | this.lblMethodToString.AutoSize = true;
56 | this.lblMethodToString.BackColor = System.Drawing.SystemColors.Control;
57 | this.lblMethodToString.Location = new System.Drawing.Point(110, 6);
58 | this.lblMethodToString.Name = "lblMethodToString";
59 | this.lblMethodToString.Size = new System.Drawing.Size(93, 13);
60 | this.lblMethodToString.TabIndex = 1;
61 | this.lblMethodToString.Text = "lblMethodToString";
62 | //
63 | // lblMethodGetType
64 | //
65 | this.lblMethodGetType.AutoSize = true;
66 | this.lblMethodGetType.Location = new System.Drawing.Point(3, 6);
67 | this.lblMethodGetType.Name = "lblMethodGetType";
68 | this.lblMethodGetType.Size = new System.Drawing.Size(94, 13);
69 | this.lblMethodGetType.TabIndex = 1;
70 | this.lblMethodGetType.Text = "lblMethodGetType";
71 | //
72 | // panel2
73 | //
74 | this.panel2.Controls.Add(this.richTextBox);
75 | this.panel2.Dock = System.Windows.Forms.DockStyle.Fill;
76 | this.panel2.Location = new System.Drawing.Point(0, 25);
77 | this.panel2.Name = "panel2";
78 | this.panel2.Size = new System.Drawing.Size(492, 380);
79 | this.panel2.TabIndex = 8;
80 | //
81 | // richTextBox
82 | //
83 | this.richTextBox.BackColor = System.Drawing.SystemColors.Window;
84 | this.richTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
85 | this.richTextBox.ContextMenuStrip = this.contextMenuStrip;
86 | this.richTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
87 | this.richTextBox.Font = new System.Drawing.Font("Lucida Console", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
88 | this.richTextBox.ForeColor = System.Drawing.Color.Black;
89 | this.richTextBox.Location = new System.Drawing.Point(0, 0);
90 | this.richTextBox.Name = "richTextBox";
91 | this.richTextBox.Size = new System.Drawing.Size(492, 380);
92 | this.richTextBox.TabIndex = 0;
93 | this.richTextBox.Text = "";
94 | this.richTextBox.WordWrap = false;
95 | //
96 | // contextMenuStrip
97 | //
98 | this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
99 | this.fontNameToolStripMenuItem,
100 | this.fontSizeToolStripMenuItem});
101 | this.contextMenuStrip.Name = "contextMenuStrip";
102 | this.contextMenuStrip.Size = new System.Drawing.Size(134, 48);
103 | //
104 | // fontNameToolStripMenuItem
105 | //
106 | this.fontNameToolStripMenuItem.Name = "fontNameToolStripMenuItem";
107 | this.fontNameToolStripMenuItem.Size = new System.Drawing.Size(133, 22);
108 | this.fontNameToolStripMenuItem.Text = "Font Name";
109 | //
110 | // fontSizeToolStripMenuItem
111 | //
112 | this.fontSizeToolStripMenuItem.Name = "fontSizeToolStripMenuItem";
113 | this.fontSizeToolStripMenuItem.Size = new System.Drawing.Size(133, 22);
114 | this.fontSizeToolStripMenuItem.Text = "Font Size";
115 | //
116 | // MethodBodyViewer
117 | //
118 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
119 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
120 | this.ClientSize = new System.Drawing.Size(492, 405);
121 | this.Controls.Add(this.panel2);
122 | this.Controls.Add(this.panel3);
123 | this.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
124 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
125 | this.KeyPreview = true;
126 | this.MinimumSize = new System.Drawing.Size(450, 300);
127 | this.Name = "MethodBodyViewer";
128 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
129 | this.Text = "IL Visualizer";
130 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MethodBodyViewer_FormClosing);
131 | this.Load += new System.EventHandler(this.MethodBodyViewer_Load);
132 | this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.MethodForm_KeyUp);
133 | this.panel3.ResumeLayout(false);
134 | this.panel3.PerformLayout();
135 | this.panel2.ResumeLayout(false);
136 | this.contextMenuStrip.ResumeLayout(false);
137 | this.ResumeLayout(false);
138 |
139 | }
140 |
141 | #endregion
142 |
143 | private System.Windows.Forms.Panel panel3;
144 | private System.Windows.Forms.Label lblMethodToString;
145 | private System.Windows.Forms.Label lblMethodGetType;
146 | private System.Windows.Forms.Panel panel2;
147 | private System.Windows.Forms.RichTextBox richTextBox;
148 | private System.Windows.Forms.ContextMenuStrip contextMenuStrip;
149 | private System.Windows.Forms.ToolStripMenuItem fontNameToolStripMenuItem;
150 | private System.Windows.Forms.ToolStripMenuItem fontSizeToolStripMenuItem;
151 | }
152 | }
--------------------------------------------------------------------------------
/ILDebugging.Visualizer/MethodBodyViewer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.Runtime.Serialization.Formatters.Binary;
5 | using System.Windows.Forms;
6 | using ILDebugging.Visualizer.Properties;
7 | using Microsoft.VisualStudio.DebuggerVisualizers;
8 |
9 | namespace ILDebugging.Visualizer
10 | {
11 | public partial class MethodBodyViewer : Form
12 | {
13 | public MethodBodyViewer()
14 | {
15 | InitializeComponent();
16 | }
17 |
18 | public void SetObjectProvider(IVisualizerObjectProvider objectProvider)
19 | {
20 | MethodBodyInfo mbi;
21 | using (var output = objectProvider.GetData())
22 | mbi = (MethodBodyInfo)new BinaryFormatter().Deserialize(output, null);
23 |
24 | lblMethodGetType.Text = mbi.TypeName;
25 | lblMethodToString.Text = mbi.MethodToString;
26 | richTextBox.Lines = mbi.Instructions.ToArray();
27 |
28 | ActiveControl = richTextBox;
29 | }
30 |
31 | // allow ESC to close
32 | private void MethodForm_KeyUp(object sender, KeyEventArgs e)
33 | {
34 | if (e.KeyCode == Keys.Escape)
35 | Close();
36 | }
37 |
38 | private void MethodBodyViewer_Load(object sender, EventArgs e)
39 | {
40 | LoadSettings();
41 | BuildContextMenu();
42 | }
43 |
44 | private void MethodBodyViewer_FormClosing(object sender, FormClosingEventArgs e)
45 | {
46 | SaveSettings();
47 | }
48 |
49 | private string selectedFontName;
50 | private ToolStripMenuItem selectedFontNameMenuItem;
51 | private int selectedFontSize;
52 | private ToolStripMenuItem selectedFontSizeMenuItem;
53 |
54 | private void BuildContextMenu()
55 | {
56 | var fontCandidates = new[] {"Arial", "Consolas", "Courier New", "Lucida Console", "Tahoma"};
57 |
58 | var fontChoices = new List();
59 | if (Array.IndexOf(fontCandidates, selectedFontName) == -1)
60 | fontChoices.Add(selectedFontName);
61 |
62 | // only choose those available in current machine
63 | foreach (var ff in FontFamily.Families)
64 | {
65 | if (Array.IndexOf(fontCandidates, ff.Name) != -1)
66 | fontChoices.Add(ff.Name);
67 | }
68 |
69 | var nameCount = fontChoices.Count;
70 | var nameItems = new ToolStripMenuItem[nameCount];
71 | for (var i = 0; i < nameCount; i++)
72 | {
73 | nameItems[i] = new ToolStripMenuItem(fontChoices[i], null, fontNameToolStripMenuItem_Click);
74 | if (fontChoices[i] == selectedFontName)
75 | {
76 | nameItems[i].Checked = true;
77 | selectedFontNameMenuItem = nameItems[i];
78 | }
79 | }
80 | fontNameToolStripMenuItem.DropDownItems.AddRange(nameItems);
81 |
82 | var sizeChoices = new[] {9, 10, 11, 12, 14, 20};
83 | var sizeCount = sizeChoices.Length;
84 |
85 | var sizeItems = new ToolStripMenuItem[sizeCount];
86 | for (var i = 0; i < sizeCount; i++)
87 | {
88 | sizeItems[i] = new ToolStripMenuItem(sizeChoices[i].ToString(), null, fontSizeToolStripMenuItem_Click);
89 | if (sizeChoices[i] == selectedFontSize)
90 | {
91 | sizeItems[i].Checked = true;
92 | selectedFontSizeMenuItem = sizeItems[i];
93 | }
94 | }
95 | fontSizeToolStripMenuItem.DropDownItems.AddRange(sizeItems);
96 |
97 | richTextBox.Font = new Font(selectedFontName, selectedFontSize);
98 | }
99 |
100 | private void LoadSettings()
101 | {
102 | var s = Settings.Default;
103 |
104 | Width = s.WindowWidth;
105 | Height = s.WindowHeight;
106 | Left = s.WindowLeft;
107 | Top = s.WindowTop;
108 |
109 | selectedFontName = s.FontName;
110 | selectedFontSize = s.FontSize;
111 | }
112 |
113 | private void SaveSettings()
114 | {
115 | var s = Settings.Default;
116 |
117 | s.WindowWidth = Width;
118 | s.WindowHeight = Height;
119 | s.WindowLeft = Left;
120 | s.WindowTop = Top;
121 |
122 | s.FontName = selectedFontName;
123 | s.FontSize = selectedFontSize;
124 |
125 | s.Save();
126 | }
127 |
128 | private void fontNameToolStripMenuItem_Click(object sender, EventArgs e)
129 | {
130 | selectedFontNameMenuItem.Checked = false;
131 | selectedFontNameMenuItem = (ToolStripMenuItem)sender;
132 | selectedFontNameMenuItem.Checked = true;
133 |
134 | selectedFontName = selectedFontNameMenuItem.Text;
135 | richTextBox.Font = new Font(selectedFontName, richTextBox.Font.Size);
136 | Update();
137 | }
138 |
139 | private void fontSizeToolStripMenuItem_Click(object sender, EventArgs e)
140 | {
141 | selectedFontSizeMenuItem.Checked = false;
142 | selectedFontSizeMenuItem = (ToolStripMenuItem)sender;
143 | selectedFontSizeMenuItem.Checked = true;
144 |
145 | selectedFontSize = int.Parse(selectedFontSizeMenuItem.Text);
146 | richTextBox.Font = new Font(richTextBox.Font.Name, selectedFontSize);
147 | Update();
148 | }
149 | }
150 | }
--------------------------------------------------------------------------------
/ILDebugging.Visualizer/MethodBodyViewer.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
124 |
125 |
126 | AAABAAMAEBAQAAAABAAoAQAANgAAACAgEAAAAAQA6AIAAF4BAAAQEAAAAAAIAGgFAABGBAAAKAAAABAA
127 | AAAgAAAAAQAEAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAIAAAACAgACAAAAAgACAAICA
128 | AACAgIAAwMDAAAAA/wAA/wAAAP//AP8AAAD/AP8A//8AAP///wAAAAAAAAAAAAB//4/4/48AAH//j/j/
129 | jwAAeIiIiIiIAAB/d4d4d48AAH93h3h3jwAAeIiIiIiIAAB/d4d4d48AAH93h3h3jwAAeIiIiIiIAAB/
130 | d4d4d48AAH93h3h3jwAAeIiIiIAAAAB//4/49/cAAH//j/j3cAAAd3d3d3cAAMABAADAAQAAwAEAAMAB
131 | AADAAQAAwAEAAMABAADAAQAAwAEAAMABAADAAQAAwAEAAMABAADAAwAAwAcAAMAPAAAoAAAAIAAAAEAA
132 | AAABAAQAAAAAAIACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAICA
133 | gADAwMAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAB4iIiIiIiIiI
134 | iIiIiAAAAAf////4///4///4//gAAAAH////+P//+P//+P/4AAAAB/////j///j///j/+AAAAAf////4
135 | ///4///4//gAAAAH////+P//+P//+P/4AAAAB4iIiIiIiIiIiIiIiAAAAAf/eHh4eHh4eHh4//gAAAAH
136 | /4eHiIeHiIeHiP/4AAAAB/94eHh4eHh4eHj/+AAAAAf/h4eIh4eIh4eI//gAAAAH/3h4eHh4eHh4eP/4
137 | AAAAB4iIiIiIiIiIiIiIiAAAAAf/eHh4eHh4eHh4//gAAAAH/4eHiIeHiIeHiP/4AAAAB/94eHh4eHh4
138 | eHj/+AAAAAf/h4eIh4eIh4eI//gAAAAH/3h4eHh4eHh4eP/4AAAAB4iIiIiIiIiIiIiIiAAAAAf/eHh4
139 | eHh4eHh4//gAAAAH/4eHiIeHiIeHiP/4AAAAB/94eHh4eHh4eHj/+AAAAAf/h4eIh4eIh4eI//gAAAAH
140 | /3h4eHh4eHh4eP/4AAAAB4iIiIiIiIiIiHAAAAAAAAf////4///4//9/+HAAAAAH////+P//+P//f4cA
141 | AAAAB/////j///j//3hwAAAAAAf////4///4//93AAAAAAAH////+P//+P//cAAAAAAAB3d3d3d3d3d3
142 | d3AAAAAA4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AA
143 | AAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAP4AAAH+AA
144 | AD/gAAB/4AAA/+AAAf8oAAAAEAAAACAAAAABAAgAAAAAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAA
145 | gAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwADA3MAA8MqmAAQEBAAICAgADAwMABEREQAWFhYAHBwcACIi
146 | IgApKSkAVVVVAE1NTQBCQkIAOTk5AIB8/wBQUP8AkwDWAP/szADG1u8A1ufnAJCprQAAADMAAABmAAAA
147 | mQAAAMwAADMAAAAzMwAAM2YAADOZAAAzzAAAM/8AAGYAAABmMwAAZmYAAGaZAABmzAAAZv8AAJkAAACZ
148 | MwAAmWYAAJmZAACZzAAAmf8AAMwAAADMMwAAzGYAAMyZAADMzAAAzP8AAP9mAAD/mQAA/8wAMwAAADMA
149 | MwAzAGYAMwCZADMAzAAzAP8AMzMAADMzMwAzM2YAMzOZADMzzAAzM/8AM2YAADNmMwAzZmYAM2aZADNm
150 | zAAzZv8AM5kAADOZMwAzmWYAM5mZADOZzAAzmf8AM8wAADPMMwAzzGYAM8yZADPMzAAzzP8AM/8zADP/
151 | ZgAz/5kAM//MADP//wBmAAAAZgAzAGYAZgBmAJkAZgDMAGYA/wBmMwAAZjMzAGYzZgBmM5kAZjPMAGYz
152 | /wBmZgAAZmYzAGZmZgBmZpkAZmbMAGaZAABmmTMAZplmAGaZmQBmmcwAZpn/AGbMAABmzDMAZsyZAGbM
153 | zABmzP8AZv8AAGb/MwBm/5kAZv/MAMwA/wD/AMwAmZkAAJkzmQCZAJkAmQDMAJkAAACZMzMAmQBmAJkz
154 | zACZAP8AmWYAAJlmMwCZM2YAmWaZAJlmzACZM/8AmZkzAJmZZgCZmZkAmZnMAJmZ/wCZzAAAmcwzAGbM
155 | ZgCZzJkAmczMAJnM/wCZ/wAAmf8zAJnMZgCZ/5kAmf/MAJn//wDMAAAAmQAzAMwAZgDMAJkAzADMAJkz
156 | AADMMzMAzDNmAMwzmQDMM8wAzDP/AMxmAADMZjMAmWZmAMxmmQDMZswAmWb/AMyZAADMmTMAzJlmAMyZ
157 | mQDMmcwAzJn/AMzMAADMzDMAzMxmAMzMmQDMzMwAzMz/AMz/AADM/zMAmf9mAMz/mQDM/8wAzP//AMwA
158 | MwD/AGYA/wCZAMwzAAD/MzMA/zNmAP8zmQD/M8wA/zP/AP9mAAD/ZjMAzGZmAP9mmQD/ZswAzGb/AP+Z
159 | AAD/mTMA/5lmAP+ZmQD/mcwA/5n/AP/MAAD/zDMA/8xmAP/MmQD/zMwA/8z/AP//MwDM/2YA//+ZAP//
160 | zABmZv8AZv9mAGb//wD/ZmYA/2b/AP//ZgAhAKUAX19fAHd3dwCGhoYAlpaWAMvLywCysrIA19fXAN3d
161 | 3QDj4+MA6urqAPHx8QD4+PgA8Pv/AKSgoACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAoK
162 | CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgUFBQUFBQUFBQUKCgoKCgUFBQUFBQUFBQUF
163 | CgoKCqurq6urq6urq6sFBQoKCgqrq6v//////6urBQUKCgoKq6v//6ur//+rqwUFCgoKCqur//+rq///
164 | q6sFBQoKCgqrq///q6v//6urBQUKCgoKq6v//6ur//+rqwUFCgoKCqurq///////q6sFBQoKCgqrq6ur
165 | q6v//6urBQoKCgoKq6urq6ur//+rqwUKCgoKCqurq6urq///q6sKCgoKCgoKCgoKCgoKCgoKCgoKCgoK
166 | CgoKCgoKCgoKCgoKCgr//wAA//8AAPADAADgAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMAH
167 | AADABwAAwA8AAP//AAD//wAA
168 |
169 |
170 |
--------------------------------------------------------------------------------
/ILDebugging.Visualizer/MethodBodyVisualizer.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using System.Reflection;
3 | using ILDebugging.Visualizer;
4 | using Microsoft.VisualStudio.DebuggerVisualizers;
5 |
6 | [assembly: DebuggerVisualizer(
7 | typeof(MethodBodyVisualizer),
8 | typeof(MethodBodyObjectSource),
9 | Target = typeof(MethodBase),
10 | Description = "IL Visualizer")
11 | ]
12 |
13 | namespace ILDebugging.Visualizer
14 | {
15 | public class MethodBodyVisualizer : DialogDebuggerVisualizer
16 | {
17 | protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)
18 | {
19 | using (var viewer = new MethodBodyViewer())
20 | {
21 | viewer.SetObjectProvider(objectProvider);
22 | viewer.ShowDialog();
23 | }
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/ILDebugging.Visualizer/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 |
8 | [assembly: AssemblyTitle("ILDebugging.Visualizer")]
9 | [assembly: AssemblyDescription("Visual Studio debugging visualiser for types that can be represented as IL documents.")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Microsoft")]
12 | [assembly: AssemblyProduct("")]
13 | [assembly: AssemblyCopyright("Copyright © 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 |
21 | [assembly: ComVisible(false)]
22 |
23 | // The following GUID is for the ID of the typelib if this project is exposed to COM
24 |
25 | [assembly: Guid("632585a0-d9e5-4ba1-8b1e-b847b5834a77")]
26 |
27 | // Version information for an assembly consists of the following four values:
28 | //
29 | // Major Version
30 | // Minor Version
31 | // Build Number
32 | // Revision
33 | //
34 | // You can specify all the values or you can default the Revision and Build Numbers
35 | // by using the '*' as shown below:
36 |
37 | [assembly: AssemblyVersion("1.0.0.0")]
38 | [assembly: AssemblyFileVersion("1.0.0.0")]
--------------------------------------------------------------------------------
/ILDebugging.Visualizer/Properties/Resource.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace ILDebugging.Visualizer.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resource {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resource() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ILDebugging.Visualizer.Properties.Resource", typeof(Resource).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
65 | ///
66 | internal static System.Drawing.Icon app {
67 | get {
68 | object obj = ResourceManager.GetObject("app", resourceCulture);
69 | return ((System.Drawing.Icon)(obj));
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/ILDebugging.Visualizer/Properties/Resource.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | ..\Resources\app.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
123 |
124 |
--------------------------------------------------------------------------------
/ILDebugging.Visualizer/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace ILDebugging.Visualizer.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.5.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 |
26 | [global::System.Configuration.UserScopedSettingAttribute()]
27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
28 | [global::System.Configuration.DefaultSettingValueAttribute("400")]
29 | public int WindowWidth {
30 | get {
31 | return ((int)(this["WindowWidth"]));
32 | }
33 | set {
34 | this["WindowWidth"] = value;
35 | }
36 | }
37 |
38 | [global::System.Configuration.UserScopedSettingAttribute()]
39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
40 | [global::System.Configuration.DefaultSettingValueAttribute("300")]
41 | public int WindowHeight {
42 | get {
43 | return ((int)(this["WindowHeight"]));
44 | }
45 | set {
46 | this["WindowHeight"] = value;
47 | }
48 | }
49 |
50 | [global::System.Configuration.UserScopedSettingAttribute()]
51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
52 | [global::System.Configuration.DefaultSettingValueAttribute("100")]
53 | public int WindowLeft {
54 | get {
55 | return ((int)(this["WindowLeft"]));
56 | }
57 | set {
58 | this["WindowLeft"] = value;
59 | }
60 | }
61 |
62 | [global::System.Configuration.UserScopedSettingAttribute()]
63 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
64 | [global::System.Configuration.DefaultSettingValueAttribute("100")]
65 | public int WindowTop {
66 | get {
67 | return ((int)(this["WindowTop"]));
68 | }
69 | set {
70 | this["WindowTop"] = value;
71 | }
72 | }
73 |
74 | [global::System.Configuration.UserScopedSettingAttribute()]
75 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
76 | [global::System.Configuration.DefaultSettingValueAttribute("Courier New")]
77 | public string FontName {
78 | get {
79 | return ((string)(this["FontName"]));
80 | }
81 | set {
82 | this["FontName"] = value;
83 | }
84 | }
85 |
86 | [global::System.Configuration.UserScopedSettingAttribute()]
87 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
88 | [global::System.Configuration.DefaultSettingValueAttribute("10")]
89 | public int FontSize {
90 | get {
91 | return ((int)(this["FontSize"]));
92 | }
93 | set {
94 | this["FontSize"] = value;
95 | }
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/ILDebugging.Visualizer/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 | 400
9 |
10 |
11 | 300
12 |
13 |
14 | 100
15 |
16 |
17 | 100
18 |
19 |
20 | Courier New
21 |
22 |
23 | 10
24 |
25 |
26 |
--------------------------------------------------------------------------------
/ILDebugging.Visualizer/Resources/app.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drewnoakes/il-visualizer/33cdca7f9d3ff2feb9cb6ad123ecf0c62e45a562/ILDebugging.Visualizer/Resources/app.ico
--------------------------------------------------------------------------------
/ILDebugging.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25420.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILDebugging.Decoder", "ILDebugging.Decoder\ILDebugging.Decoder.csproj", "{3B40E8C3-C4E8-4085-9F82-F64308F3791C}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILDebugging.Monitor", "ILDebugging.Monitor\ILDebugging.Monitor.csproj", "{77F852DD-35CD-4B2D-AA0E-0516F1E7597F}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILDebugging.Visualizer", "ILDebugging.Visualizer\ILDebugging.Visualizer.csproj", "{6F6E9FC5-40A9-4ABD-89F3-EF7B6406F07B}"
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILDebugging.Sample", "ILDebugging.Sample\ILDebugging.Sample.csproj", "{5BF03C0A-2F42-4538-B373-8B2BE569350A}"
13 | EndProject
14 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A55BBE27-FF6F-4EB6-9261-E58D05AAE3A9}"
15 | ProjectSection(SolutionItems) = preProject
16 | .gitignore = .gitignore
17 | README.md = README.md
18 | EndProjectSection
19 | EndProject
20 | Global
21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
22 | Debug|Any CPU = Debug|Any CPU
23 | Release|Any CPU = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
26 | {3B40E8C3-C4E8-4085-9F82-F64308F3791C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {3B40E8C3-C4E8-4085-9F82-F64308F3791C}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {3B40E8C3-C4E8-4085-9F82-F64308F3791C}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {3B40E8C3-C4E8-4085-9F82-F64308F3791C}.Release|Any CPU.Build.0 = Release|Any CPU
30 | {77F852DD-35CD-4B2D-AA0E-0516F1E7597F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
31 | {77F852DD-35CD-4B2D-AA0E-0516F1E7597F}.Debug|Any CPU.Build.0 = Debug|Any CPU
32 | {77F852DD-35CD-4B2D-AA0E-0516F1E7597F}.Release|Any CPU.ActiveCfg = Release|Any CPU
33 | {77F852DD-35CD-4B2D-AA0E-0516F1E7597F}.Release|Any CPU.Build.0 = Release|Any CPU
34 | {6F6E9FC5-40A9-4ABD-89F3-EF7B6406F07B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
35 | {6F6E9FC5-40A9-4ABD-89F3-EF7B6406F07B}.Debug|Any CPU.Build.0 = Debug|Any CPU
36 | {6F6E9FC5-40A9-4ABD-89F3-EF7B6406F07B}.Release|Any CPU.ActiveCfg = Release|Any CPU
37 | {6F6E9FC5-40A9-4ABD-89F3-EF7B6406F07B}.Release|Any CPU.Build.0 = Release|Any CPU
38 | {5BF03C0A-2F42-4538-B373-8B2BE569350A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
39 | {5BF03C0A-2F42-4538-B373-8B2BE569350A}.Debug|Any CPU.Build.0 = Debug|Any CPU
40 | {5BF03C0A-2F42-4538-B373-8B2BE569350A}.Release|Any CPU.ActiveCfg = Release|Any CPU
41 | {5BF03C0A-2F42-4538-B373-8B2BE569350A}.Release|Any CPU.Build.0 = Release|Any CPU
42 | EndGlobalSection
43 | GlobalSection(SolutionProperties) = preSolution
44 | HideSolutionNode = FALSE
45 | EndGlobalSection
46 | EndGlobal
47 |
--------------------------------------------------------------------------------
/Images/il-monitor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drewnoakes/il-visualizer/33cdca7f9d3ff2feb9cb6ad123ecf0c62e45a562/Images/il-monitor.png
--------------------------------------------------------------------------------
/Images/il-visualizer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drewnoakes/il-visualizer/33cdca7f9d3ff2feb9cb6ad123ecf0c62e45a562/Images/il-visualizer.png
--------------------------------------------------------------------------------
/Images/launching-visualizer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drewnoakes/il-visualizer/33cdca7f9d3ff2feb9cb6ad123ecf0c62e45a562/Images/launching-visualizer.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # IL Visualiser
2 |
3 | Originally developed by Haibo Luo in 2005 and posted in a series of blog posts
4 | ([part one](https://blogs.msdn.microsoft.com/haibo_luo/2005/10/25/debuggervisualizer-for-dynamicmethod-show-me-the-il/),
5 | [part two](https://blogs.msdn.microsoft.com/haibo_luo/2006/11/16/take-two-il-visualizer/)).
6 |
7 | Converted to a Git repository and upgraded to VS2015 by Drew Noakes. Conversion to VS2017 by @dadhi.
8 |
9 | ## Usage
10 |
11 | When paused in the debugger, select an instance of a subclass of `MethodBase` (such as `DynamicMethod`,
12 | `MethodBuilder`, `ConstructorBuilder`, ...) and launch a visualiser:
13 |
14 | 
15 |
16 | There are two ways to use this visualiser.
17 |
18 | ### IL Visualizer (Modal)
19 |
20 | Selecting _"IL Visualizer"_ pops up a window showing the IL code.
21 |
22 | 
23 |
24 | This window is modal and debugging may only continue once the window is closed.
25 |
26 | ### Out of Process (Non-modal)
27 |
28 | Sometimes you don't want to close the window before continuing your debugging session. For such cases, you
29 | can run _IL Monitor_ as a separate process, then select _"Send to IL Monitor"_:
30 |
31 | 
32 |
33 | IL Monitor is a standalone MDI application that allows displaying mutliple IL views.
34 |
35 | ## Installation
36 |
37 | (Notes apply to VS 2015 and 2017, but are similar for earlier versions)
38 |
39 | 1. [Download the latest release for your version of Visual Studio](https://github.com/drewnoakes/il-visualizer/releases), or build from source
40 |
41 | 2. Copy `ILDebugging.Decoder.dll` and `ILDebugging.Visualizer.dll` to one of:
42 |
43 | - `%USERPROFILE%\Documents\Visual Studio 2015\Visualizers`
44 | - `%USERPROFILE%\Documents\Visual Studio 2017\Visualizers`
45 | - `VisualStudioInstallPath_\Common7\Packages\Debugger\Visualizers`
46 |
47 | 3. Restart the debugging session (you don't have to restart Visual Studio)
48 |
49 | **Note**: If you get error _"Operation not supported"_ when invoking the visualizer, restart Visual Studio and try again.
50 |
51 | If you wish to use _Send to IL Monitor_, you run `ILDebugging.Monitor.exe` before attempting to use it from the debugger.
52 |
53 | ## Earlier Visual Studio Versions
54 |
55 | You can target earlier versions of Visual Studio by updating the assembly references for
56 | `Microsoft.VisualStudio.DebuggerVisualizers.dll` to the relevant version.
57 |
58 | ## License
59 |
60 | THE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES INTENDED OR IMPLIED. USE AT YOUR OWN RISK!
61 |
--------------------------------------------------------------------------------