Skip to content

Commit

Permalink
Synchronize access to symbols dictionary (#411)
Browse files Browse the repository at this point in the history
  • Loading branch information
daltzctr authored Aug 19, 2024
1 parent df3b584 commit 75683c0
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 36 deletions.
104 changes: 68 additions & 36 deletions Mono.Debugging.Soft/DebugSymbolsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public class DebugSymbolsManager
private string[] symbolServerUrls;
private SymbolStore symbolStore;
private SoftDebuggerSession session;
private readonly object _lock = new object();

internal DebugSymbolsManager (SoftDebuggerSession session)
{
Expand All @@ -49,10 +50,13 @@ internal DebugSymbolsManager (SoftDebuggerSession session)
}
public string HasSymbolLoaded (AssemblyMirror assembly)
{
if (session.SymbolPathMap.TryGetValue (assembly.Location, out string symbolPath))
return symbolPath;
if (symbolsByAssembly.TryGetValue (assembly, out var symbolsInfo))
return symbolsInfo.Status == SymbolStatus.NotLoadedFromSymbolServer ? "Dynamically loaded" : null;
lock(_lock)
{
if (session.SymbolPathMap.TryGetValue (assembly.Location, out string symbolPath))
return symbolPath;
if (symbolsByAssembly.TryGetValue (assembly, out var symbolsInfo))
return symbolsInfo.Status == SymbolStatus.NotLoadedFromSymbolServer ? "Dynamically loaded" : null;
}
return null;
}
public bool ForceLoadSymbolFromAssembly (AssemblyMirror assembly)
Expand All @@ -77,7 +81,13 @@ public async Task SetSymbolServerUrl (string[] symbolServerUrls)

public async Task TryLoadSymbolFromSymbolServerIfNeeded ()
{
var assembliesToTryToLoadPPDB = symbolsByAssembly.Where (asm => asm.Value.Status == SymbolStatus.NotFound || asm.Value.Status == SymbolStatus.NotTriedToLoad).ToList ();
List<KeyValuePair<AssemblyMirror, DebugSymbolsInfo>> assembliesToTryToLoadPPDB;

lock(_lock)
{
assembliesToTryToLoadPPDB = symbolsByAssembly.Where(asm => asm.Value.Status == SymbolStatus.NotFound || asm.Value.Status == SymbolStatus.NotTriedToLoad).ToList();
}

foreach (var asm in assembliesToTryToLoadPPDB) {
await TryLoadSymbolFromSymbolServerIfNeeded (asm.Key);
}
Expand All @@ -87,8 +97,11 @@ internal PortablePdbData GetPdbData (AssemblyMirror asm, bool force = false)
{
string pdbFileName;
PortablePdbData portablePdb = null;
if (symbolsByAssembly.TryGetValue (asm, out var symbolsInfo) && (symbolsInfo.PdbData != null || (!force && symbolsInfo.Status == SymbolStatus.NotFound))) {
return symbolsInfo.PdbData;
lock(_lock)
{
if (symbolsByAssembly.TryGetValue (asm, out var symbolsInfo) && (symbolsInfo.PdbData != null || (!force && symbolsInfo.Status == SymbolStatus.NotFound))) {
return symbolsInfo.PdbData;
}
}

if (!session.SymbolPathMap.TryGetValue (asm.GetName ().FullName, out pdbFileName) || Path.GetExtension (pdbFileName) != ".pdb") {
Expand All @@ -104,20 +117,27 @@ internal PortablePdbData GetPdbData (AssemblyMirror asm, bool force = false)
var pdbBlob = asm.GetPdbBlob ();
portablePdb = pdbBlob != null ? new PortablePdbData (pdbBlob) : null;
}
if (portablePdb == null)
symbolsByAssembly[asm] = new DebugSymbolsInfo (SymbolStatus.NotFound, null);
else
symbolsByAssembly[asm] = new DebugSymbolsInfo (SymbolStatus.NotLoadedFromSymbolServer, portablePdb);

lock(_lock)
{
if (portablePdb == null)
symbolsByAssembly[asm] = new DebugSymbolsInfo (SymbolStatus.NotFound, null);
else
symbolsByAssembly[asm] = new DebugSymbolsInfo (SymbolStatus.NotLoadedFromSymbolServer, portablePdb);
}
return portablePdb;
}

internal Location FindLocationsByFileInPdbLoadedOnDebuggerSide (string fileName, int line, int column)
{
var symbolsByAssemblyList = symbolsByAssembly.Where(item => item.Value.Status == SymbolStatus.LoadedOnDebuggerSide).ToList();
foreach (var symbolServerPPDB in symbolsByAssemblyList) {
var location = symbolServerPPDB.Value.PdbData.GetLocationByFileName (symbolServerPPDB.Key, fileName, line, column);
if (location != null)
return location;
lock(_lock)
{
var symbolsByAssemblyList = symbolsByAssembly.Where(item => item.Value.Status == SymbolStatus.LoadedOnDebuggerSide).ToList();
foreach (var symbolServerPPDB in symbolsByAssemblyList) {
var location = symbolServerPPDB.Value.PdbData.GetLocationByFileName (symbolServerPPDB.Key, fileName, line, column);
if (location != null)
return location;
}
}
return null;
}
Expand Down Expand Up @@ -150,19 +170,27 @@ public async Task<bool> TryLoadSymbolFromSymbolServerIfNeeded (AssemblyMirror as
if (session.SymbolPathMap.ContainsKey (asmName)) {
var portablePdb = GetPdbData (asm, true);
if (portablePdb != null) {
symbolsByAssembly[asm] = new DebugSymbolsInfo (SymbolStatus.LoadedOnDebuggerSide, portablePdb);
session.TryResolvePendingBreakpoints ();
lock(_lock)
{
symbolsByAssembly[asm] = new DebugSymbolsInfo (SymbolStatus.LoadedOnDebuggerSide, portablePdb);
session.TryResolvePendingBreakpoints ();
}
}
return true;
}
if (symbolsByAssembly.TryGetValue (asm, out var symbolsInfo)) {
if (symbolsInfo.PdbData != null)
return true;
}
if (session.JustMyCode) {
symbolsByAssembly[asm] = new DebugSymbolsInfo (SymbolStatus.NotTriedToLoad, null);
return false;

lock(_lock)
{
if (symbolsByAssembly.TryGetValue (asm, out var symbolsInfo)) {
if (symbolsInfo.PdbData != null)
return true;
}
if (session.JustMyCode) {
symbolsByAssembly[asm] = new DebugSymbolsInfo (SymbolStatus.NotTriedToLoad, null);
return false;
}
}

if (symbolStore == null)
CreateSymbolStore ();
if (symbolStore == null)
Expand All @@ -173,21 +201,25 @@ public async Task<bool> TryLoadSymbolFromSymbolServerIfNeeded (AssemblyMirror as
var pdbGuid = guid.ToString ("N").ToUpperInvariant () + (isPortableCodeView ? "FFFFFFFF" : age.ToString ());
var key = $"{pdbName}/{pdbGuid}/{pdbName}";
SymbolStoreFile file = await symbolStore.GetFile (new SymbolStoreKey (key, pdbPath, false, pdbChecksums), new CancellationTokenSource ().Token);
if (file != null) {
session.SymbolPathMap[asmName] = Path.Combine (symbolCachePath, key);
var portablePdb = GetPdbData (asm, true);
if (portablePdb != null) {
symbolsByAssembly[asm] = new DebugSymbolsInfo(SymbolStatus.LoadedOnDebuggerSide, portablePdb);
session.TryResolvePendingBreakpoints ();
} else {

lock(_lock)
{
if (file != null) {
session.SymbolPathMap[asmName] = Path.Combine (symbolCachePath, key);
var portablePdb = GetPdbData (asm, true);
if (portablePdb != null) {
symbolsByAssembly[asm] = new DebugSymbolsInfo(SymbolStatus.LoadedOnDebuggerSide, portablePdb);
session.TryResolvePendingBreakpoints ();
} else {
symbolsByAssembly[asm] = new DebugSymbolsInfo (SymbolStatus.NotFound, null);
return false;
}
}
else {
symbolsByAssembly[asm] = new DebugSymbolsInfo (SymbolStatus.NotFound, null);
return false;
}
}
else {
symbolsByAssembly[asm] = new DebugSymbolsInfo (SymbolStatus.NotFound, null);
return false;
}
return true;
}
}
Expand Down
7 changes: 7 additions & 0 deletions Mono.Debugging.Soft/nuget.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<configuration>
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
<add key="dnceng" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" />
</packageSources>
</configuration>

0 comments on commit 75683c0

Please sign in to comment.