|
6 | 6 | #nullable enable |
7 | 7 | using System; |
8 | 8 | using System.Linq; |
| 9 | +using Datadog.System.Buffers; |
9 | 10 | using Datadog.System.Reflection.Metadata; |
| 11 | +using Datadog.System.Reflection.Metadata.Ecma335; |
10 | 12 | using Datadog.Trace.Debugger.Symbols.Model; |
11 | 13 | using Datadog.Trace.Pdb; |
12 | | -using Datadog.Trace.Vendors.dnlib.DotNet.Emit; |
13 | 14 | using Datadog.Trace.Vendors.dnlib.DotNet.Pdb.Symbols; |
14 | 15 |
|
15 | 16 | namespace Datadog.Trace.Debugger.Symbols; |
@@ -66,117 +67,70 @@ protected override Model.Scope CreateMethodScope(TypeDefinition type, MethodDefi |
66 | 67 | return methodScope; |
67 | 68 | } |
68 | 69 |
|
69 | | - public void GetLocalVariables(MethodDefinition method) |
| 70 | + private StandaloneSignature GetLocalSignature(MethodDefinition method) |
70 | 71 | { |
71 | 72 | var methodBodyBlock = _pdbReader.PEReader?.GetMethodBody(method.RelativeVirtualAddress); |
72 | | - var methodDebugInfo = _pdbReader.MetadataReader.GetMethodDebugInformation(method.Handle); |
73 | | - foreach (var localScope in MetadataReader.GetLocalScopes(method.Handle)) |
74 | | - { |
75 | | - MetadataReader.GetLocalVariableRange(localScope, out int first, out int last); |
76 | | - foreach (var localVariable in MetadataReader.LocalVariables) |
77 | | - { |
78 | | - // localVariable.RowId |
79 | | - } |
| 73 | + return MetadataReader.GetStandaloneSignature(methodBodyBlock!.LocalSignature); |
| 74 | + } |
80 | 75 |
|
81 | | - // MetadataReader.LocalVariableTable.GetName(MetadataReader.LocalVariables) |
82 | | - } |
| 76 | + private int GetLocalVariablesCount(MethodDefinition method) |
| 77 | + { |
| 78 | + var signature = GetLocalSignature(method); |
| 79 | + BlobReader blobReader = MetadataReader.GetBlobReader(signature.Signature); |
83 | 80 |
|
84 | | - MetadataReader.GetLocalScopes(method.Handle); |
85 | | - foreach (var sequencePoint in methodDebugInfo.GetSequencePoints()) |
| 81 | + if (blobReader.ReadByte() == (byte)SignatureKind.LocalVariables) |
86 | 82 | { |
87 | | - // var localScopes = _pdbReader.MetadataReader.GetLocalScopes(methodDebugInfo.); |
88 | | - // foreach (var localScope in localScopes) |
89 | | - // { |
90 | | - // _pdbReader.PEReader.GetSectionData() |
91 | | - // foreach (var localVariableHandle in localScope..GetLocalVariables()) |
92 | | - // { |
93 | | - // var localVariable = pdbReader.GetLocalVariable(localVariableHandle); |
94 | | - // Console.WriteLine($"Index: {localVariable.Index}, Name: {pdbReader.GetString(localVariable.Name)}"); |
95 | | - // } |
96 | | - // } |
| 83 | + int variableCount = blobReader.ReadCompressedInteger(); |
| 84 | + return variableCount; |
97 | 85 | } |
98 | 86 |
|
99 | | - // var localVarSig = MetadataReader.GetLocalVariable(methodBodyBlock.LocalSignature); |
100 | | - // MethodBodyBlock methodBody = MetadataReader.MethodDefTable..GetMethodImplementation(method.Handle).MethodBody; |
101 | | - // StandAloneSignature signature = MetadataReader.GetStandaloneSignature(methodBody.LocalSignature); |
102 | | - |
103 | | - // BlobReader blobReader = MetadataReader.GetBlobReader(signature.Signature); |
104 | | - |
105 | | - // if (blobReader.ReadByte() == (byte)SignatureKind.LocalVariables) |
106 | | - // { |
107 | | - // int variableCount = blobReader.ReadCompressedInteger(); |
108 | | - |
109 | | - // for (int i = 0; i < variableCount; i++) |
110 | | - // { |
111 | | - // SignatureTypeCode typeCode = (SignatureTypeCode)blobReader.ReadCompressedInteger(); |
112 | | - |
113 | | - // For simple types, the type code maps directly to the variable type. |
114 | | - // For other types, more detailed parsing will be necessary. |
115 | | - // } |
116 | | - // } |
| 87 | + return 0; |
117 | 88 | } |
118 | 89 |
|
119 | 90 | private Symbol[]? GetLocalsSymbol(MethodDefinition method, int startLine, SymbolMethod symbolMethod, out int localsCount) |
120 | 91 | { |
121 | 92 | localsCount = 0; |
122 | | - var methodBody = _pdbReader.PEReader?.GetMethodBody(method.RelativeVirtualAddress); |
123 | | - // if (method.Body is not { Variables.Count: > 0 }) |
124 | | - // { |
125 | | - // return null; |
126 | | - // } |
127 | | - |
128 | | - var methodLocals = new int[1]; // methodBody.Variables; |
129 | | - var localsSymbol = new Symbol[methodLocals.Length]; |
130 | | - var allMethodScopes = GetAllScopes(symbolMethod); |
131 | | - Symbol[]? allLocals = null; |
| 93 | + var methodLocalsCount = GetLocalVariablesCount(method); |
| 94 | + if (methodLocalsCount == 0) |
| 95 | + { |
| 96 | + return null; |
| 97 | + } |
132 | 98 |
|
133 | | - for (var k = 0; k < allMethodScopes.Count; k++) |
| 99 | + var localsSymbol = ArrayPool<Symbol>.Shared.Rent(methodLocalsCount); |
| 100 | + var signature = GetLocalSignature(method); |
| 101 | + var localTypes = signature.DecodeLocalSignature(new TypeProvider(), 0); |
| 102 | + |
| 103 | + Symbol[]? allLocals = null; |
| 104 | + foreach (var scopeHandle in MetadataReader.GetLocalScopes(method.Handle.ToDebugInformationHandle())) |
134 | 105 | { |
135 | | - var currentScope = allMethodScopes[k]; |
136 | | - for (var l = 0; l < currentScope.Locals.Count; l++) |
| 106 | + var localScope = MetadataReader.GetLocalScope(scopeHandle); |
| 107 | + foreach (var localVarHandle in localScope.GetLocalVariables()) |
137 | 108 | { |
138 | | - var localSymbol = currentScope.Locals[l]; |
139 | | - if (localSymbol.Index > methodLocals.Length || string.IsNullOrEmpty(localSymbol.Name)) |
| 109 | + var local = MetadataReader.GetLocalVariable(localVarHandle); |
| 110 | + if (local.Index > methodLocalsCount || string.IsNullOrEmpty(MetadataReader.GetString(local.Name))) |
140 | 111 | { |
141 | 112 | continue; |
142 | 113 | } |
143 | 114 |
|
144 | 115 | var line = UnknownEndLineEntireScope; |
145 | | - for (var m = 0; m < symbolMethod.SequencePoints.Count; m++) |
| 116 | + foreach (var sequencePoint in MetadataReader.GetMethodDebugInformation(method.Handle.ToDebugInformationHandle()).GetSequencePoints()) |
146 | 117 | { |
147 | | - if (symbolMethod.SequencePoints[m].Offset >= currentScope.StartOffset) |
| 118 | + if (sequencePoint.Offset >= localScope.StartOffset) |
148 | 119 | { |
149 | | - line = symbolMethod.SequencePoints[m].Line; |
| 120 | + line = sequencePoint.StartLine; |
150 | 121 | break; |
151 | 122 | } |
152 | 123 | } |
153 | 124 |
|
154 | | - Local? local = null; |
155 | | - // for (var i = 0; i < methodLocals.Length; i++) |
156 | | - // { |
157 | | - // if (methodLocals[i].Index != localSymbol.Index) |
158 | | - // { |
159 | | - // continue; |
160 | | - // } |
161 | | - |
162 | | - // local = methodLocals[i]; |
163 | | - // break; |
164 | | - // } |
165 | | - |
166 | | - if (local == null) |
167 | | - { |
168 | | - continue; |
169 | | - } |
170 | | - |
171 | 125 | // if (IsCompilerGeneratedAttributeDefined(local.Type.ToTypeDefOrRef().CustomAttributes)) |
172 | 126 | // { |
173 | 127 | // continue; |
174 | 128 | // } |
175 | 129 |
|
176 | 130 | localsSymbol[localsCount] = new Symbol |
177 | 131 | { |
178 | | - Name = localSymbol.Name, |
179 | | - Type = local.Type?.FullName, |
| 132 | + Name = MetadataReader.GetString(local.Name), |
| 133 | + Type = localTypes[local.Index].Name, |
180 | 134 | SymbolType = SymbolType.Local, |
181 | 135 | Line = line |
182 | 136 | }; |
@@ -216,7 +170,7 @@ public void GetLocalVariables(MethodDefinition method) |
216 | 170 | allLocals[localsCount] = new Symbol |
217 | 171 | { |
218 | 172 | Name = localName, |
219 | | - // Type = field.FieldType.FullName, |
| 173 | + Type = field.DecodeSignature(new TypeProvider(), 0).Name, |
220 | 174 | SymbolType = SymbolType.Local, |
221 | 175 | Line = startLine |
222 | 176 | }; |
|
0 commit comments