From f04d6ff193a95bd8d2add5dbfea83b74e4bcb029 Mon Sep 17 00:00:00 2001 From: Konstantin Baladurin Date: Fri, 20 Jul 2018 15:19:50 +0300 Subject: Zapper::CompileAssembly: save NI file atomically It can get rid of possible problems with corrupted NI files if crossgen will be killed during image saving. --- src/zap/zapimage.cpp | 4 ++-- src/zap/zapimage.h | 2 +- src/zap/zapper.cpp | 11 ++++++++++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/zap/zapimage.cpp b/src/zap/zapimage.cpp index 3ad696720a..a58e372120 100644 --- a/src/zap/zapimage.cpp +++ b/src/zap/zapimage.cpp @@ -1082,7 +1082,7 @@ HANDLE ZapImage::GenerateFile(LPCWSTR wszOutputFileName, CORCOMPILE_NGEN_SIGNATU } -HANDLE ZapImage::SaveImage(LPCWSTR wszOutputFileName, CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig) +HANDLE ZapImage::SaveImage(LPCWSTR wszOutputFileName, LPCWSTR wszDllPath, CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig) { if (!IsReadyToRunCompilation()) { @@ -1095,7 +1095,7 @@ HANDLE ZapImage::SaveImage(LPCWSTR wszOutputFileName, CORCOMPILE_NGEN_SIGNATURE // that native images are resoure-only DLLs. It is important to NOT // be a resource-only DLL because those DLL's PDBS are not put up on the // symbol server and we want NEN PDBS to be placed there. - ZapPEExports* exports = new(GetHeap()) ZapPEExports(wszOutputFileName); + ZapPEExports* exports = new(GetHeap()) ZapPEExports(wszDllPath); m_pDebugSection->Place(exports); SetDirectoryEntry(IMAGE_DIRECTORY_ENTRY_EXPORT, exports); diff --git a/src/zap/zapimage.h b/src/zap/zapimage.h index 4687d75003..826f1bcf9b 100644 --- a/src/zap/zapimage.h +++ b/src/zap/zapimage.h @@ -666,7 +666,7 @@ public: void AllocateVirtualSections(); - HANDLE SaveImage(LPCWSTR wszOutputFileName, CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig); + HANDLE SaveImage(LPCWSTR wszOutputFileName, LPCWSTR wszDllPath, CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig); void Preload(); void LinkPreload(); diff --git a/src/zap/zapper.cpp b/src/zap/zapper.cpp index 683805eacf..5cecda827e 100644 --- a/src/zap/zapper.cpp +++ b/src/zap/zapper.cpp @@ -1457,6 +1457,7 @@ void Zapper::CompileAssembly(CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig) DefineOutputAssembly(strAssemblyName, &hashAlgId); SString strNativeImagePath; + SString strNativeImageTempPath; HANDLE hFile = INVALID_HANDLE_VALUE; StackSArray hFiles; @@ -1505,7 +1506,10 @@ void Zapper::CompileAssembly(CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig) pAssemblyModule->SetPdbFileName(SString(strAssemblyName, SL(W(".ni.pdb")))); - hFile = pAssemblyModule->SaveImage(strNativeImagePath.GetUnicode(), pNativeImageSig); + strNativeImageTempPath = strNativeImagePath; + strNativeImageTempPath.Append(W(".tmp")); + + hFile = pAssemblyModule->SaveImage(strNativeImageTempPath.GetUnicode(), strNativeImagePath.GetUnicode(), pNativeImageSig); } // Throw away the assembly if we have hit fatal error during compilation @@ -1520,6 +1524,11 @@ void Zapper::CompileAssembly(CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig) CloseHandle(*i); } + if (!WszMoveFileEx(strNativeImageTempPath.GetUnicode(), strNativeImagePath.GetUnicode(), MOVEFILE_REPLACE_EXISTING)) + { + ThrowLastError(); + } + if (!m_pOpt->m_silent) { GetSvcLogger()->Printf(W("Native image %s generated successfully.\n"), strNativeImagePath.GetUnicode()); -- cgit v1.2.3