From 56d4479b405a6f36ae43de9991bcbcbdcc384839 Mon Sep 17 00:00:00 2001 From: "Denis Kuzmin (github/3F)" Date: Mon, 9 Dec 2024 19:08:33 +0300 Subject: [PATCH] Updated .PDB deletion logic according to ISymUnmanagedWriter problem --- .tools/net.r_eg.DllExport.targets | 2 +- src/DllExport/Core/Parsing/ILAsm.cs | 100 ++++++++++++++++++---------- 2 files changed, 65 insertions(+), 37 deletions(-) diff --git a/.tools/net.r_eg.DllExport.targets b/.tools/net.r_eg.DllExport.targets index fc27b9b..51fafee 100644 --- a/.tools/net.r_eg.DllExport.targets +++ b/.tools/net.r_eg.DllExport.targets @@ -119,7 +119,7 @@ DebugOptimize Debug DebugImpl - $(DebugSymbols) + $(DebugSymbols) { - if(!string.IsNullOrEmpty(str1) && File.Exists(str1)) - { - File.Delete(str1); - } - } + return EnsurePdb(f, () => RunCore(cpu, outputFile, resource.ToString(), ilSuffix)); + }); } private int RunCore(CpuPlatform cpu, string fileName, string ressourceParam, string ilSuffix) @@ -475,5 +446,62 @@ private string GetKeysToDebug(DebugType type) _ => throw new NotImplementedException() }; } + + private T EnsurePdb(string inputModule, Func action) where T : struct + { + string pdb = Path.ChangeExtension(inputModule, ".pdb"); + string pdbt = Path.ChangeExtension(inputModule, ".pdbt"); + + if(File.Exists(pdb)) + { + // Due to possible incorrect ISymUnmanagedWriter when exists initial pdb data for non-modified module. + // https://github.com/3F/coreclr/blob/05afa4f81fdf671429b54467c64d65cde6b5fadc/src/debug/ildbsymlib/symwrite.cpp#L308 + // \- Part of https://github.com/3F/DllExport/issues/90 + + if(File.Exists(pdbt)) File.Delete(pdbt); + File.Move(pdb, pdbt); + } + + try + { + return action?.Invoke() ?? default; + } + finally + { + if(!File.Exists(pdb)) // https://github.com/3F/DllExport/issues/23#issuecomment-263951782 + { + if(File.Exists(pdbt)) File.Move(pdbt, pdb); + } + else + { + File.Delete(pdbt); + } + } + } + + private T PrepareOutput(string fullpath, string src, Func action) where T: struct + { + string bak = null; + try + { + if(string.Equals(src, fullpath, StringComparison.OrdinalIgnoreCase)) + { + int num = 1; + do + { + bak = $"{src}.bak{num}"; + ++num; + } + while(File.Exists(bak)); + File.Move(src, bak); + } + + return action?.Invoke(src) ?? default; + } + finally + { + if(bak != null && File.Exists(bak)) File.Delete(bak); + } + } } }