Skip to content

Commit 8bd8268

Browse files
[Java.Interop.Tools.Cecil] Fix retry logic in ReadAssembly to skip symbol loading
The retry in ReadAssembly sets reader_parameters.ReadSymbols = false, but LoadFromMemoryMappedFile checks the instance field loadDebugSymbols instead, so the retry re-opens the same locked PDB file and throws the same IOException. Fix by passing an explicit loadSymbols parameter to LoadFromMemoryMappedFile so the retry can actually skip symbol loading. When loadDebugSymbols is false, rethrow immediately since there is nothing to retry. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent c7b4ea6 commit 8bd8268

File tree

2 files changed

+24
-6
lines changed

2 files changed

+24
-6
lines changed

src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil/DirectoryAssemblyResolver.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -162,34 +162,36 @@ protected virtual AssemblyDefinition ReadAssembly (string file)
162162
SymbolReaderProvider = loadReaderParameters.SymbolReaderProvider,
163163
};
164164
try {
165-
return LoadFromMemoryMappedFile (file, reader_parameters);
165+
return LoadFromMemoryMappedFile (file, reader_parameters, loadDebugSymbols);
166166
} catch (Exception ex) {
167+
if (!loadDebugSymbols)
168+
throw;
167169
logger (
168170
TraceLevel.Verbose,
169171
$"Failed to read '{file}' with debugging symbols. Retrying to load it without it. Error details are logged below.");
170172
logger (TraceLevel.Verbose, ex.ToString ());
171173
reader_parameters.ReadSymbols = false;
172-
return LoadFromMemoryMappedFile (file, reader_parameters);
174+
return LoadFromMemoryMappedFile (file, reader_parameters, loadSymbols: false);
173175
} finally {
174176
reader_parameters.SymbolStream?.Dispose ();
175177
}
176178
}
177179

178-
AssemblyDefinition LoadFromMemoryMappedFile (string file, ReaderParameters options)
180+
AssemblyDefinition LoadFromMemoryMappedFile (string file, ReaderParameters options, bool loadSymbols)
179181
{
180182
// We can't use MemoryMappedFile when ReadWrite is true
181183
if (options.ReadWrite) {
182-
if (loadDebugSymbols) {
184+
if (loadSymbols) {
183185
LoadSymbols (file, options, File.OpenRead);
184186
}
185187
return AssemblyDefinition.ReadAssembly (file, options);
186188
}
187189

188190
// We know the capacity for disposables
189191
var disposables = new List<IDisposable> (
190-
(1 + (loadDebugSymbols ? 1 : 0)) * OpenMemoryMappedViewStream_disposables_Add_calls);
192+
(1 + (loadSymbols ? 1 : 0)) * OpenMemoryMappedViewStream_disposables_Add_calls);
191193
try {
192-
if (loadDebugSymbols) {
194+
if (loadSymbols) {
193195
LoadSymbols (file, options, f => OpenMemoryMappedViewStream (f, disposables));
194196
}
195197

tests/Java.Interop.Tools.JavaCallableWrappers-Tests/Java.Interop.Tools.JavaCallableWrappers/DirectoryAssemblyResolverTests.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,21 @@ public void LoadSymbols ([Values (true, false)] bool loadDebugSymbols, [Values (
4949
Assert.IsNotNull (assembly);
5050
Assert.AreEqual (loadDebugSymbols, assembly.MainModule.HasSymbols);
5151
}
52+
53+
[Test]
54+
public void LoadSymbols_LockedPdb ([Values (true, false)] bool readWrite)
55+
{
56+
// Lock the PDB file exclusively so LoadSymbols will fail with IOException
57+
using var lockStream = new FileStream (symbol_path, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
58+
59+
using var resolver = new DirectoryAssemblyResolver (Log, loadDebugSymbols: true, new ReaderParameters {
60+
ReadWrite = readWrite
61+
});
62+
63+
// Should succeed by retrying without symbols instead of throwing
64+
var assembly = resolver.Load (assembly_path);
65+
Assert.IsNotNull (assembly);
66+
Assert.IsFalse (assembly.MainModule.HasSymbols);
67+
}
5268
}
5369
}

0 commit comments

Comments
 (0)