Zapper::CompileAssembly: save NI file atomically
authorKonstantin Baladurin <k.baladurin@partner.samsung.com>
Fri, 20 Jul 2018 12:19:50 +0000 (15:19 +0300)
committerGleb Balykov <g.balykov@samsung.com>
Tue, 18 Sep 2018 12:49:14 +0000 (15:49 +0300)
It can get rid of possible problems with corrupted NI files if crossgen
will be killed during image saving.

src/zap/zapimage.cpp
src/zap/zapimage.h
src/zap/zapper.cpp

index 3ad6967..a58e372 100644 (file)
@@ -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);
     
index 4687d75..826f1bc 100644 (file)
@@ -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();
index 683805e..5cecda8 100644 (file)
@@ -1457,6 +1457,7 @@ void Zapper::CompileAssembly(CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig)
     DefineOutputAssembly(strAssemblyName, &hashAlgId);
 
     SString strNativeImagePath;
+    SString strNativeImageTempPath;
     HANDLE hFile = INVALID_HANDLE_VALUE;
     StackSArray<HANDLE> 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());