Skip to content

Commit 75683c0

Browse files
authored
Synchronize access to symbols dictionary (#411)
1 parent df3b584 commit 75683c0

File tree

2 files changed

+75
-36
lines changed

2 files changed

+75
-36
lines changed

Mono.Debugging.Soft/DebugSymbolsManager.cs

Lines changed: 68 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public class DebugSymbolsManager
4141
private string[] symbolServerUrls;
4242
private SymbolStore symbolStore;
4343
private SoftDebuggerSession session;
44+
private readonly object _lock = new object();
4445

4546
internal DebugSymbolsManager (SoftDebuggerSession session)
4647
{
@@ -49,10 +50,13 @@ internal DebugSymbolsManager (SoftDebuggerSession session)
4950
}
5051
public string HasSymbolLoaded (AssemblyMirror assembly)
5152
{
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+
}
5660
return null;
5761
}
5862
public bool ForceLoadSymbolFromAssembly (AssemblyMirror assembly)
@@ -77,7 +81,13 @@ public async Task SetSymbolServerUrl (string[] symbolServerUrls)
7781

7882
public async Task TryLoadSymbolFromSymbolServerIfNeeded ()
7983
{
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+
8191
foreach (var asm in assembliesToTryToLoadPPDB) {
8292
await TryLoadSymbolFromSymbolServerIfNeeded (asm.Key);
8393
}
@@ -87,8 +97,11 @@ internal PortablePdbData GetPdbData (AssemblyMirror asm, bool force = false)
8797
{
8898
string pdbFileName;
8999
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+
}
92105
}
93106

94107
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)
104117
var pdbBlob = asm.GetPdbBlob ();
105118
portablePdb = pdbBlob != null ? new PortablePdbData (pdbBlob) : null;
106119
}
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+
}
111128
return portablePdb;
112129
}
113130

114131
internal Location FindLocationsByFileInPdbLoadedOnDebuggerSide (string fileName, int line, int column)
115132
{
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+
}
121141
}
122142
return null;
123143
}
@@ -150,19 +170,27 @@ public async Task<bool> TryLoadSymbolFromSymbolServerIfNeeded (AssemblyMirror as
150170
if (session.SymbolPathMap.ContainsKey (asmName)) {
151171
var portablePdb = GetPdbData (asm, true);
152172
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+
}
155178
}
156179
return true;
157180
}
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+
}
165192
}
193+
166194
if (symbolStore == null)
167195
CreateSymbolStore ();
168196
if (symbolStore == null)
@@ -173,21 +201,25 @@ public async Task<bool> TryLoadSymbolFromSymbolServerIfNeeded (AssemblyMirror as
173201
var pdbGuid = guid.ToString ("N").ToUpperInvariant () + (isPortableCodeView ? "FFFFFFFF" : age.ToString ());
174202
var key = $"{pdbName}/{pdbGuid}/{pdbName}";
175203
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 {
183219
symbolsByAssembly[asm] = new DebugSymbolsInfo (SymbolStatus.NotFound, null);
184220
return false;
185221
}
186222
}
187-
else {
188-
symbolsByAssembly[asm] = new DebugSymbolsInfo (SymbolStatus.NotFound, null);
189-
return false;
190-
}
191223
return true;
192224
}
193225
}

Mono.Debugging.Soft/nuget.config

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<configuration>
2+
<packageSources>
3+
<clear />
4+
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
5+
<add key="dnceng" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" />
6+
</packageSources>
7+
</configuration>

0 commit comments

Comments
 (0)