internal void Save(Stream stream) { ExceptionUtilities.HandleRecoverableIOException( () => { // We don't have anything in particular to correlate this file to, // so we are simply creating a unique correlation id that is used as part // of the header consistency check. FileEnvelopeId correlationId = FileEnvelopeId.Create(); FileEnvelope.WriteHeader(stream, correlationId); using (BuildXLWriter writer = new BuildXLWriter(debug: false, stream: stream, leaveOpen: true, logStats: false)) { writer.Write(m_runtimeData.Count); foreach (KeyValuePair<long, PipHistoricPerfData> kvp in m_runtimeData) { writer.Write(kvp.Key); kvp.Value.Serialize(writer); } } FileEnvelope.FixUpHeader(stream, correlationId); return (object)null; }, ex => { throw new BuildXLException("Writing of file failed", ex); }); }
private void Save(FileEnvelopeId atomicSaveToken, string path) { Contract.Requires(!string.IsNullOrWhiteSpace(path)); FileUtilities.DeleteFile(path); FileUtilities.CreateDirectory(Path.GetDirectoryName(path)); using (var stream = FileUtilities.CreateFileStream( path, FileMode.Create, FileAccess.Write, FileShare.Delete, // Do not write the file with SequentialScan since it will be reread in the subsequent build FileOptions.None)) { ExceptionUtilities.HandleRecoverableIOException( () => { using (var pm = BuildXL.Tracing.PerformanceMeasurement.StartWithoutStatistic( m_loggingContext, loggingContext => Logger.Log.StartSavingChangeTracker(loggingContext, path), loggingContext => Logger.Log.EndSavingChangeTracker(loggingContext))) { Stopwatch sw = Stopwatch.StartNew(); FileEnvelope.WriteHeader(stream, atomicSaveToken); using (var writer = new BuildXLWriter(debug: false, stream: stream, leaveOpen: true, logStats: false)) { if (IsDisabledOrNullTrackingSet) { writer.Write(true); } else { writer.Write(false); writer.Write(m_buildEngineFingerprint, (w, s) => w.Write(s)); m_changeTrackingSet.Save(writer); } } FileEnvelope.FixUpHeader(stream, atomicSaveToken); Logger.Log.SavingChangeTracker( pm.LoggingContext, path, atomicSaveToken.ToString(), m_changeTrackingSet == null ? "Null" : TrackingState.ToString(), m_changeTrackingSet == null ? 0 : m_changeTrackingSet.TrackedVolumes.Count(), sw.ElapsedMilliseconds); } }, ex => { throw new BuildXLException("Failed to save file change tracker", ex); }); } }
public void Success() { var fe = new FileEnvelope("Dummy", 0); using (var stream = new MemoryStream()) { FileEnvelopeId id = FileEnvelopeId.Create(); fe.WriteHeader(stream, id); fe.FixUpHeader(stream, id); stream.Position = 0; fe.ReadHeader(stream); } }
public void WrongEnvelopeVersion() { var fe0 = new FileEnvelope("Dummy0", 0); var fe1 = new FileEnvelope("Dummy0", 1); using (var stream = new MemoryStream()) { FileEnvelopeId id = FileEnvelopeId.Create(); fe0.WriteHeader(stream, id); fe0.FixUpHeader(stream, id); stream.Position = 0; Assert.Throws <BuildXLException>( () => { fe1.ReadHeader(stream); }); } }
public void DetectFileLengthCorruption() { var fe = new FileEnvelope("Dummy", 0); using (var stream = new MemoryStream()) { FileEnvelopeId id = FileEnvelopeId.Create(); fe.WriteHeader(stream, id); fe.FixUpHeader(stream, id); stream.WriteByte(0); // not taken into account in fixed up header magic stream.Position = 0; Assert.Throws <BuildXLException>( () => { fe.ReadHeader(stream); }); } }
/// <nodoc /> public void Dispose() { // NOTE: it is essential not to call m_lazyBxlWriter.Value.Dispose() if bxlWriter hasn't been created. // // reason: // - when running a process in VM, a sideband writer is created twice for that process: (1) first in the // bxl process, and (2) second in the VM process // - the VM process then runs, and writes stuff to its instance of this logger; once it finishes, // all shared opaque output writes are saved to the underlying sideband file // - the bxl process disposes its instance of this logger; without the check below, the Dispose method // creates a BuildXLWriter for the same underlying sideband file and immediately closes it, which // effectively deletes the content of that file. if (m_lazyBxlWriter.IsValueCreated) { FileEnvelope.FixUpHeader(m_lazyBxlWriter.Value.BaseStream, m_envelopeId); m_lazyBxlWriter.Value.Dispose(); } }
public void DetectHeaderCorruption() { var r = new Random(0); var fe = new FileEnvelope("Dummy", 0); for (int i = 0; i < 10000; i++) { using (var stream = new MemoryStream()) { FileEnvelopeId id = FileEnvelopeId.Create(); fe.WriteHeader(stream, id); fe.FixUpHeader(stream, id); stream.Position = r.Next((int)stream.Length - 1); int b = stream.ReadByte(); stream.Position = stream.Position - 1; stream.WriteByte((byte)(b ^ (1 << r.Next(8)))); stream.Position = 0; Assert.Throws <BuildXLException>( () => { fe.ReadHeader(stream); }); } } }
/// <summary> /// Writes a file containing versioning information to the provided store directory. /// </summary> private static void WriteVersionFile(string storeDirectory, int storeVersion) { var versionFile = GetVersionFile(storeDirectory); using (var stream = FileUtilities.CreateFileStream( versionFile, FileMode.Create, FileAccess.ReadWrite, FileShare.Delete)) { // We don't have anything in particular to correlate this file to, // so we are simply creating a unique correlation id that is used as part // of the header consistency check. var correlationId = FileEnvelopeId.Create(); s_fileEnvelope.WriteHeader(stream, correlationId); using (var writer = new BuildXLWriter(debug: false, stream: stream, leaveOpen: true, logStats: false)) { writer.Write(storeVersion); } s_fileEnvelope.FixUpHeader(stream, correlationId); } }