Skip to content

Commit a23fab1

Browse files
dudikeletiigoragoli
authored andcommitted
[SymDB] DEBUG-4512 Sanitize hoisted 'this' name in symbol upload (#8100)
## Summary of changes Prevented compiler-generated async/closure implementation types (e.g. `+<DoAsyncWork>d__3`, `+<>c__DisplayClass`…) from leaking into Live Debugger symbols by sanitizing the implicit `this` argument type for closure scopes to the user-declared declaring type. ## Reason for change Customers see confusing symbol entries containing <>/<…>d__… and other compiler artifacts in symbol search results. These are valid CLR metadata names but are not meaningful to users and clutter the Live Debugger UI. ## Test coverage Updated existing SymbolExtractorTest Verify approval snapshots to reflect the sanitized this type in closure scopes. ## Follow-ups If customers still see compiler-generated names from other symbol fields (e.g., local variable), we can add additional targeted sanitization rules with explicit replacements.
1 parent 5838734 commit a23fab1

18 files changed

+451
-32
lines changed

tracer/src/Datadog.Trace/Debugger/Symbols/SymbolPdbExtractor.cs

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// <copyright file="SymbolPdbExtractor.cs" company="Datadog">
1+
// <copyright file="SymbolPdbExtractor.cs" company="Datadog">
22
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
33
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
44
// </copyright>
@@ -140,6 +140,71 @@ protected override bool TryCreateMethodScopeForGeneratedMethod(MethodDefinition
140140

141141
closureMethodScope.Name = methodName;
142142
closureMethodScope.ScopeType = ScopeType.Closure;
143+
144+
// for closure scopes we want 'this' to reflect the user-declared type
145+
// that owns the original method and not the compiler-generated type.
146+
if (closureMethodScope.Symbols is { Length: > 0 } symbols)
147+
{
148+
// If the original method is static, there is no user 'this'. The generated closure/state-machine
149+
// may still have an instance 'this', but we don't want to surface that in symbols presented to users.
150+
if (method.IsStaticMethod())
151+
{
152+
var thisIndex = -1;
153+
for (var i = 0; i < symbols.Length; i++)
154+
{
155+
if (symbols[i].SymbolType == SymbolType.Arg && symbols[i].Name == "this")
156+
{
157+
thisIndex = i;
158+
break;
159+
}
160+
}
161+
162+
if (thisIndex < 0)
163+
{
164+
// Nothing to remove
165+
return true;
166+
}
167+
168+
if (symbols.Length == 1)
169+
{
170+
closureMethodScope.Symbols = null;
171+
return true;
172+
}
173+
174+
var newSymbols = new Symbol[symbols.Length - 1];
175+
if (thisIndex > 0)
176+
{
177+
Array.Copy(symbols, 0, newSymbols, 0, thisIndex);
178+
}
179+
180+
if (thisIndex < symbols.Length - 1)
181+
{
182+
Array.Copy(symbols, thisIndex + 1, newSymbols, thisIndex, symbols.Length - thisIndex - 1);
183+
}
184+
185+
closureMethodScope.Symbols = newSymbols;
186+
187+
return true;
188+
}
189+
190+
var declaringTypeName = method.GetDeclaringType().FullName(MetadataReader);
191+
if (!string.IsNullOrEmpty(declaringTypeName))
192+
{
193+
for (var i = 0; i < symbols.Length; i++)
194+
{
195+
if (symbols[i].SymbolType == SymbolType.Arg && symbols[i].Name == "this")
196+
{
197+
var updated = symbols[i];
198+
updated.Type = declaringTypeName;
199+
symbols[i] = updated;
200+
break;
201+
}
202+
}
203+
204+
closureMethodScope.Symbols = symbols;
205+
}
206+
}
207+
143208
return true;
144209
}
145210

tracer/test/Datadog.Trace.Tests/Debugger/SymbolsTests/SymbolExtractor/Approvals/SymbolExtractorTest.AsyncMethod.verified.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{
1+
{
22
"service": "test",
33
"env": "test",
44
"version": "0",
@@ -66,7 +66,7 @@
6666
"symbols": [
6767
{
6868
"name": "this",
69-
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.AsyncMethod+<>c",
69+
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.AsyncMethod",
7070
"symbol_type": "arg",
7171
"line": 0
7272
}

tracer/test/Datadog.Trace.Tests/Debugger/SymbolsTests/SymbolExtractor/Approvals/SymbolExtractorTest.ComprehensiveLinqWithClosure.verified.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{
1+
{
22
"service": "test",
33
"env": "test",
44
"version": "0",
@@ -63,7 +63,7 @@
6363
"symbols": [
6464
{
6565
"name": "this",
66-
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.ComprehensiveLinqWithClosure+<>c__DisplayClass0_0",
66+
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.ComprehensiveLinqWithClosure",
6767
"symbol_type": "arg",
6868
"line": 0
6969
},

tracer/test/Datadog.Trace.Tests/Debugger/SymbolsTests/SymbolExtractor/Approvals/SymbolExtractorTest.ComprehensiveLinqWithoutClosure.verified.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{
1+
{
22
"service": "test",
33
"env": "test",
44
"version": "0",
@@ -63,7 +63,7 @@
6363
"symbols": [
6464
{
6565
"name": "this",
66-
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.ComprehensiveLinqWithoutClosure+<>c",
66+
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.ComprehensiveLinqWithoutClosure",
6767
"symbol_type": "arg",
6868
"line": 0
6969
},

tracer/test/Datadog.Trace.Tests/Debugger/SymbolsTests/SymbolExtractor/Approvals/SymbolExtractorTest.HoistedAndNotHoistedLocals.verified.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@
132132
"symbols": [
133133
{
134134
"name": "this",
135-
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.HoistedAndNotHoistedLocals+<AssignRoom>d__3",
135+
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.HoistedAndNotHoistedLocals",
136136
"symbol_type": "arg",
137137
"line": 0
138138
}

tracer/test/Datadog.Trace.Tests/Debugger/SymbolsTests/SymbolExtractor/Approvals/SymbolExtractorTest.HoistedLocalsAndArgsInStateMachine.verified.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@
128128
"symbols": [
129129
{
130130
"name": "this",
131-
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.HoistedLocalsAndArgsInStateMachine+<DoAsyncWork>d__3",
131+
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.HoistedLocalsAndArgsInStateMachine",
132132
"symbol_type": "arg",
133133
"line": 0
134134
}

tracer/test/Datadog.Trace.Tests/Debugger/SymbolsTests/SymbolExtractor/Approvals/SymbolExtractorTest.LambdaWithClosure.verified.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{
1+
{
22
"service": "test",
33
"env": "test",
44
"version": "0",
@@ -63,7 +63,7 @@
6363
"symbols": [
6464
{
6565
"name": "this",
66-
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.LambdaWithClosure+<>c__DisplayClass0_0",
66+
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.LambdaWithClosure",
6767
"symbol_type": "arg",
6868
"line": 0
6969
}

tracer/test/Datadog.Trace.Tests/Debugger/SymbolsTests/SymbolExtractor/Approvals/SymbolExtractorTest.LambdaWithStaticFieldClosure.verified.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{
1+
{
22
"service": "test",
33
"env": "test",
44
"version": "0",
@@ -102,7 +102,7 @@
102102
"symbols": [
103103
{
104104
"name": "this",
105-
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.LambdaWithStaticFieldClosure+<>c",
105+
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.LambdaWithStaticFieldClosure",
106106
"symbol_type": "arg",
107107
"line": 0
108108
}

tracer/test/Datadog.Trace.Tests/Debugger/SymbolsTests/SymbolExtractor/Approvals/SymbolExtractorTest.LambdaWithoutClosure.verified.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{
1+
{
22
"service": "test",
33
"env": "test",
44
"version": "0",
@@ -63,7 +63,7 @@
6363
"symbols": [
6464
{
6565
"name": "this",
66-
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.LambdaWithoutClosure+<>c",
66+
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.LambdaWithoutClosure",
6767
"symbol_type": "arg",
6868
"line": 0
6969
}

tracer/test/Datadog.Trace.Tests/Debugger/SymbolsTests/SymbolExtractor/Approvals/SymbolExtractorTest.MultipleClosuresMultipleHoisted.verified.txt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{
1+
{
22
"service": "test",
33
"env": "test",
44
"version": "0",
@@ -75,7 +75,7 @@
7575
"symbols": [
7676
{
7777
"name": "this",
78-
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.MultipleClosuresMultipleHoisted+<>c",
78+
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.MultipleClosuresMultipleHoisted",
7979
"symbol_type": "arg",
8080
"line": 0
8181
},
@@ -104,7 +104,7 @@
104104
"symbols": [
105105
{
106106
"name": "this",
107-
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.MultipleClosuresMultipleHoisted+<>c",
107+
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.MultipleClosuresMultipleHoisted",
108108
"symbol_type": "arg",
109109
"line": 0
110110
},
@@ -133,7 +133,7 @@
133133
"symbols": [
134134
{
135135
"name": "this",
136-
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.MultipleClosuresMultipleHoisted+<>c",
136+
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.MultipleClosuresMultipleHoisted",
137137
"symbol_type": "arg",
138138
"line": 0
139139
},
@@ -162,7 +162,7 @@
162162
"symbols": [
163163
{
164164
"name": "this",
165-
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.MultipleClosuresMultipleHoisted+<>c",
165+
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.MultipleClosuresMultipleHoisted",
166166
"symbol_type": "arg",
167167
"line": 0
168168
},
@@ -191,7 +191,7 @@
191191
"symbols": [
192192
{
193193
"name": "this",
194-
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.MultipleClosuresMultipleHoisted+<>c",
194+
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.MultipleClosuresMultipleHoisted",
195195
"symbol_type": "arg",
196196
"line": 0
197197
},
@@ -226,7 +226,7 @@
226226
"symbols": [
227227
{
228228
"name": "this",
229-
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.MultipleClosuresMultipleHoisted+<>c__DisplayClass0_0",
229+
"type": "Datadog.Trace.Tests.Debugger.SymbolsTests.TestSamples.MultipleClosuresMultipleHoisted",
230230
"symbol_type": "arg",
231231
"line": 0
232232
},

0 commit comments

Comments
 (0)