@@ -41,6 +41,7 @@ public class DebugSymbolsManager
41
41
private string [ ] symbolServerUrls ;
42
42
private SymbolStore symbolStore ;
43
43
private SoftDebuggerSession session ;
44
+ private readonly object _lock = new object ( ) ;
44
45
45
46
internal DebugSymbolsManager ( SoftDebuggerSession session )
46
47
{
@@ -49,10 +50,13 @@ internal DebugSymbolsManager (SoftDebuggerSession session)
49
50
}
50
51
public string HasSymbolLoaded ( AssemblyMirror assembly )
51
52
{
52
- if ( session . SymbolPathMap . TryGetValue ( assembly . Location , out string symbolPath ) )
53
- return symbolPath ;
54
- if ( symbolsByAssembly . TryGetValue ( assembly , out var symbolsInfo ) )
55
- return symbolsInfo . Status == SymbolStatus . NotLoadedFromSymbolServer ? "Dynamically loaded" : null ;
53
+ lock ( _lock )
54
+ {
55
+ if ( session . SymbolPathMap . TryGetValue ( assembly . Location , out string symbolPath ) )
56
+ return symbolPath ;
57
+ if ( symbolsByAssembly . TryGetValue ( assembly , out var symbolsInfo ) )
58
+ return symbolsInfo . Status == SymbolStatus . NotLoadedFromSymbolServer ? "Dynamically loaded" : null ;
59
+ }
56
60
return null ;
57
61
}
58
62
public bool ForceLoadSymbolFromAssembly ( AssemblyMirror assembly )
@@ -77,7 +81,13 @@ public async Task SetSymbolServerUrl (string[] symbolServerUrls)
77
81
78
82
public async Task TryLoadSymbolFromSymbolServerIfNeeded ( )
79
83
{
80
- var assembliesToTryToLoadPPDB = symbolsByAssembly . Where ( asm => asm . Value . Status == SymbolStatus . NotFound || asm . Value . Status == SymbolStatus . NotTriedToLoad ) . ToList ( ) ;
84
+ List < KeyValuePair < AssemblyMirror , DebugSymbolsInfo > > assembliesToTryToLoadPPDB ;
85
+
86
+ lock ( _lock )
87
+ {
88
+ assembliesToTryToLoadPPDB = symbolsByAssembly . Where ( asm => asm . Value . Status == SymbolStatus . NotFound || asm . Value . Status == SymbolStatus . NotTriedToLoad ) . ToList ( ) ;
89
+ }
90
+
81
91
foreach ( var asm in assembliesToTryToLoadPPDB ) {
82
92
await TryLoadSymbolFromSymbolServerIfNeeded ( asm . Key ) ;
83
93
}
@@ -87,8 +97,11 @@ internal PortablePdbData GetPdbData (AssemblyMirror asm, bool force = false)
87
97
{
88
98
string pdbFileName ;
89
99
PortablePdbData portablePdb = null ;
90
- if ( symbolsByAssembly . TryGetValue ( asm , out var symbolsInfo ) && ( symbolsInfo . PdbData != null || ( ! force && symbolsInfo . Status == SymbolStatus . NotFound ) ) ) {
91
- return symbolsInfo . PdbData ;
100
+ lock ( _lock )
101
+ {
102
+ if ( symbolsByAssembly . TryGetValue ( asm , out var symbolsInfo ) && ( symbolsInfo . PdbData != null || ( ! force && symbolsInfo . Status == SymbolStatus . NotFound ) ) ) {
103
+ return symbolsInfo . PdbData ;
104
+ }
92
105
}
93
106
94
107
if ( ! session . SymbolPathMap . TryGetValue ( asm . GetName ( ) . FullName , out pdbFileName ) || Path . GetExtension ( pdbFileName ) != ".pdb" ) {
@@ -104,20 +117,27 @@ internal PortablePdbData GetPdbData (AssemblyMirror asm, bool force = false)
104
117
var pdbBlob = asm . GetPdbBlob ( ) ;
105
118
portablePdb = pdbBlob != null ? new PortablePdbData ( pdbBlob ) : null ;
106
119
}
107
- if ( portablePdb == null )
108
- symbolsByAssembly [ asm ] = new DebugSymbolsInfo ( SymbolStatus . NotFound , null ) ;
109
- else
110
- symbolsByAssembly [ asm ] = new DebugSymbolsInfo ( SymbolStatus . NotLoadedFromSymbolServer , portablePdb ) ;
120
+
121
+ lock ( _lock )
122
+ {
123
+ if ( portablePdb == null )
124
+ symbolsByAssembly [ asm ] = new DebugSymbolsInfo ( SymbolStatus . NotFound , null ) ;
125
+ else
126
+ symbolsByAssembly [ asm ] = new DebugSymbolsInfo ( SymbolStatus . NotLoadedFromSymbolServer , portablePdb ) ;
127
+ }
111
128
return portablePdb ;
112
129
}
113
130
114
131
internal Location FindLocationsByFileInPdbLoadedOnDebuggerSide ( string fileName , int line , int column )
115
132
{
116
- var symbolsByAssemblyList = symbolsByAssembly . Where ( item => item . Value . Status == SymbolStatus . LoadedOnDebuggerSide ) . ToList ( ) ;
117
- foreach ( var symbolServerPPDB in symbolsByAssemblyList ) {
118
- var location = symbolServerPPDB . Value . PdbData . GetLocationByFileName ( symbolServerPPDB . Key , fileName , line , column ) ;
119
- if ( location != null )
120
- return location ;
133
+ lock ( _lock )
134
+ {
135
+ var symbolsByAssemblyList = symbolsByAssembly . Where ( item => item . Value . Status == SymbolStatus . LoadedOnDebuggerSide ) . ToList ( ) ;
136
+ foreach ( var symbolServerPPDB in symbolsByAssemblyList ) {
137
+ var location = symbolServerPPDB . Value . PdbData . GetLocationByFileName ( symbolServerPPDB . Key , fileName , line , column ) ;
138
+ if ( location != null )
139
+ return location ;
140
+ }
121
141
}
122
142
return null ;
123
143
}
@@ -150,19 +170,27 @@ public async Task<bool> TryLoadSymbolFromSymbolServerIfNeeded (AssemblyMirror as
150
170
if ( session . SymbolPathMap . ContainsKey ( asmName ) ) {
151
171
var portablePdb = GetPdbData ( asm , true ) ;
152
172
if ( portablePdb != null ) {
153
- symbolsByAssembly [ asm ] = new DebugSymbolsInfo ( SymbolStatus . LoadedOnDebuggerSide , portablePdb ) ;
154
- session . TryResolvePendingBreakpoints ( ) ;
173
+ lock ( _lock )
174
+ {
175
+ symbolsByAssembly [ asm ] = new DebugSymbolsInfo ( SymbolStatus . LoadedOnDebuggerSide , portablePdb ) ;
176
+ session . TryResolvePendingBreakpoints ( ) ;
177
+ }
155
178
}
156
179
return true ;
157
180
}
158
- if ( symbolsByAssembly . TryGetValue ( asm , out var symbolsInfo ) ) {
159
- if ( symbolsInfo . PdbData != null )
160
- return true ;
161
- }
162
- if ( session . JustMyCode ) {
163
- symbolsByAssembly [ asm ] = new DebugSymbolsInfo ( SymbolStatus . NotTriedToLoad , null ) ;
164
- return false ;
181
+
182
+ lock ( _lock )
183
+ {
184
+ if ( symbolsByAssembly . TryGetValue ( asm , out var symbolsInfo ) ) {
185
+ if ( symbolsInfo . PdbData != null )
186
+ return true ;
187
+ }
188
+ if ( session . JustMyCode ) {
189
+ symbolsByAssembly [ asm ] = new DebugSymbolsInfo ( SymbolStatus . NotTriedToLoad , null ) ;
190
+ return false ;
191
+ }
165
192
}
193
+
166
194
if ( symbolStore == null )
167
195
CreateSymbolStore ( ) ;
168
196
if ( symbolStore == null )
@@ -173,21 +201,25 @@ public async Task<bool> TryLoadSymbolFromSymbolServerIfNeeded (AssemblyMirror as
173
201
var pdbGuid = guid . ToString ( "N" ) . ToUpperInvariant ( ) + ( isPortableCodeView ? "FFFFFFFF" : age . ToString ( ) ) ;
174
202
var key = $ "{ pdbName } /{ pdbGuid } /{ pdbName } ";
175
203
SymbolStoreFile file = await symbolStore . GetFile ( new SymbolStoreKey ( key , pdbPath , false , pdbChecksums ) , new CancellationTokenSource ( ) . Token ) ;
176
- if ( file != null ) {
177
- session . SymbolPathMap [ asmName ] = Path . Combine ( symbolCachePath , key ) ;
178
- var portablePdb = GetPdbData ( asm , true ) ;
179
- if ( portablePdb != null ) {
180
- symbolsByAssembly [ asm ] = new DebugSymbolsInfo ( SymbolStatus . LoadedOnDebuggerSide , portablePdb ) ;
181
- session . TryResolvePendingBreakpoints ( ) ;
182
- } else {
204
+
205
+ lock ( _lock )
206
+ {
207
+ if ( file != null ) {
208
+ session . SymbolPathMap [ asmName ] = Path . Combine ( symbolCachePath , key ) ;
209
+ var portablePdb = GetPdbData ( asm , true ) ;
210
+ if ( portablePdb != null ) {
211
+ symbolsByAssembly [ asm ] = new DebugSymbolsInfo ( SymbolStatus . LoadedOnDebuggerSide , portablePdb ) ;
212
+ session . TryResolvePendingBreakpoints ( ) ;
213
+ } else {
214
+ symbolsByAssembly [ asm ] = new DebugSymbolsInfo ( SymbolStatus . NotFound , null ) ;
215
+ return false ;
216
+ }
217
+ }
218
+ else {
183
219
symbolsByAssembly [ asm ] = new DebugSymbolsInfo ( SymbolStatus . NotFound , null ) ;
184
220
return false ;
185
221
}
186
222
}
187
- else {
188
- symbolsByAssembly [ asm ] = new DebugSymbolsInfo ( SymbolStatus . NotFound , null ) ;
189
- return false ;
190
- }
191
223
return true ;
192
224
}
193
225
}
0 commit comments