Index: lib/xray/xray_fdr_logging.cc =================================================================== --- lib/xray/xray_fdr_logging.cc +++ lib/xray/xray_fdr_logging.cc @@ -125,9 +125,16 @@ clock_gettime(CLOCK_REALTIME, &Header.TS); retryingWriteAll(Fd, reinterpret_cast(&Header), reinterpret_cast(&Header) + sizeof(Header)); + LocalBQ->apply([&](const BufferQueue::Buffer &B) { - retryingWriteAll(Fd, reinterpret_cast(B.Buffer), - reinterpret_cast(B.Buffer) + B.Size); + uint64_t BufferSize = B.Size; + if (BufferSize > 0) { + retryingWriteAll(Fd, reinterpret_cast(&BufferSize), + reinterpret_cast(&BufferSize) + + sizeof(BufferSize)); + retryingWriteAll(Fd, reinterpret_cast(B.Buffer), + reinterpret_cast(B.Buffer) + B.Size); + } }); LogFlushStatus.store(XRayLogFlushStatus::XRAY_LOG_FLUSHED, std::memory_order_release); Index: lib/xray/xray_fdr_logging_impl.h =================================================================== --- lib/xray/xray_fdr_logging_impl.h +++ lib/xray/xray_fdr_logging_impl.h @@ -308,9 +308,23 @@ const std::atomic &LoggingStatus, const std::shared_ptr &BQ) XRAY_NEVER_INSTRUMENT { // Bail out right away if logging is not initialized yet. - if (LoggingStatus.load(std::memory_order_acquire) != - XRayLogInitStatus::XRAY_LOG_INITIALIZED) + // We should take the opportunity to release the buffer though. + auto Status = LoggingStatus.load(std::memory_order_acquire); + if (Status != XRayLogInitStatus::XRAY_LOG_INITIALIZED) { + if (RecordPtr != nullptr && + (Status == XRayLogInitStatus::XRAY_LOG_FINALIZING || + Status == XRayLogInitStatus::XRAY_LOG_FINALIZED)) { + writeEOBMetadata(); + auto EC = BQ->releaseBuffer(Buffer); + if (EC != BufferQueue::ErrorCode::Ok) { + Report("Failed to release buffer at %p; error=%s\n", Buffer.Buffer, + BufferQueue::getErrorString(EC)); + return; + } + RecordPtr = nullptr; + } return; + } // We use a thread_local variable to keep track of which CPUs we've already // run, and the TSC times for these CPUs. This allows us to stop repeating the