in src/Microsoft.Diagnostics.Runtime/DataTarget.cs [109:181]
internal PEImage? LoadPEImage(string fileName, int timeStamp, int fileSize, bool checkProperties, ulong imageBase)
{
if (_disposed)
throw new ObjectDisposedException(nameof(DataTarget));
if (string.IsNullOrEmpty(fileName))
return null;
string key = $"{fileName}/{timeStamp:x}{fileSize:x}";
PEImage? result = null;
lock (_pefileCache)
{
if (_pefileCache.TryGetValue(key, out result))
return result;
}
if (FileLocator is not null)
{
string? foundFile = FileLocator.FindPEImage(fileName, timeStamp, fileSize, checkProperties);
if (!string.IsNullOrWhiteSpace(foundFile) && File.Exists(foundFile))
{
try
{
result = new PEImage(File.OpenRead(foundFile), false, imageBase);
if (!result.IsValid)
result = null;
}
catch (IOException)
{
result = null;
}
}
}
if (result is null)
{
// If we have a custom file locator (or null), we might not have checked the file on disk
if (Path.GetFileName(fileName) != fileName && File.Exists(fileName))
{
try
{
result = new(File.OpenRead(fileName), leaveOpen: false);
if (!result.IsValid)
{
result = null;
}
else if (checkProperties)
{
if (result.IndexFileSize != fileSize || result.IndexTimeStamp != timeStamp)
result = null;
}
}
catch (IOException)
{
result = null;
}
}
}
lock (_pefileCache)
{
// We may have raced with another thread and that thread put a value here first
if (_pefileCache.TryGetValue(key, out PEImage? cached) && cached != null)
{
result?.Dispose(); // We don't need this instance now.
return cached;
}
return _pefileCache[key] = result;
}
}