From b6bb54c963e1748b9a24568dddd375cdb8f7e192 Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Fri, 12 May 2023 13:23:56 +0200 Subject: better logging/exception when reading file in IoBuffer::Materialize fails (#294) * better logging/exception when reading file in IoBuffer::Materialize fails * changelog --- CHANGELOG.md | 1 + src/zencore/iobuffer.cpp | 45 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97b0c0502..b76e5905f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - Bugfix: Return error code on exit as set by application - Bugfix: Fix crash at startup if dead process handles are detected in ZenServerState - Bugfix: Fixed assert/error when running block store GC and a block to GC does not exist +- Improvement: Log details about file and read operation when it fails inside IoBuffer::Materialize() ## 0.2.10 - Feature: zenserver now writes a state_marker file in the root of the data directory. Deleting this file will cause zenserver to exit. This is used to detect if user is deleting the data folder while zenserver is running diff --git a/src/zencore/iobuffer.cpp b/src/zencore/iobuffer.cpp index e28bf11b2..96653c670 100644 --- a/src/zencore/iobuffer.cpp +++ b/src/zencore/iobuffer.cpp @@ -283,6 +283,8 @@ IoBufferExtendedCore::Materialize() const { AllocateBuffer(m_DataBytes, sizeof(void*)); NewFlags |= kIsOwnedByThis; + int32_t Error = 0; + size_t BytesRead = 0; #if ZEN_PLATFORM_WINDOWS OVERLAPPED Ovl{}; @@ -291,16 +293,43 @@ IoBufferExtendedCore::Materialize() const Ovl.OffsetHigh = DWORD(m_FileOffset >> 32); DWORD dwNumberOfBytesRead = 0; - BOOL Success = ::ReadFile(m_FileHandle, (void*)m_DataPtr, DWORD(m_DataBytes), &dwNumberOfBytesRead, &Ovl); - - ZEN_ASSERT(Success); - ZEN_ASSERT(dwNumberOfBytesRead == m_DataBytes); + BOOL Success = ::ReadFile(m_FileHandle, (void*)m_DataPtr, DWORD(m_DataBytes), &dwNumberOfBytesRead, &Ovl) == TRUE; + if (Success) + { + BytesRead = size_t(dwNumberOfBytesRead); + } + else + { + Error = zen::GetLastError(); + } #else static_assert(sizeof(off_t) >= sizeof(uint64_t), "sizeof(off_t) does not support large files"); - int Fd = int(uintptr_t(m_FileHandle)); - int BytesRead = pread(Fd, (void*)m_DataPtr, m_DataBytes, m_FileOffset); - bool Success = (BytesRead > 0); + int Fd = int(uintptr_t(m_FileHandle)); + int ReadResult = pread(Fd, (void*)m_DataPtr, m_DataBytes, m_FileOffset); + if (ReadResult != -1) + { + BytesRead = size_t(ReadResult); + } + else + { + Error = zen::GetLastError(); + } #endif // ZEN_PLATFORM_WINDOWS + if (Error || (BytesRead != m_DataBytes)) + { + ZEN_ERROR("ReadFile/pread failed (offset {:#x}, size {:#x}) file: '{}' (size {:#x}), {}", + m_FileOffset, + m_DataBytes, + zen::PathFromHandle(m_FileHandle), + zen::FileSizeFromHandle(m_FileHandle), + GetSystemErrorAsString(Error)); + throw std::system_error(std::error_code(Error, std::system_category()), + fmt::format("ReadFile/pread failed (offset {:#x}, size {:#x}) file: '{}' (size {:#x})", + m_FileOffset, + m_DataBytes, + PathFromHandle(m_FileHandle), + FileSizeFromHandle(m_FileHandle))); + } m_Flags.fetch_or(NewFlags, std::memory_order_release); return; @@ -357,7 +386,7 @@ IoBufferExtendedCore::Materialize() const CloseHandle(NewMmapHandle); #endif // ZEN_PLATFORM_WINDOWS - ZEN_ERROR("MapViewOfFile failed (offset {:#x}, size {:#x}) file: '{}' (size {:#x}), {}", + ZEN_ERROR("MapViewOfFile/mmap failed (offset {:#x}, size {:#x}) file: '{}' (size {:#x}), {}", MapOffset, MapSize, zen::PathFromHandle(m_FileHandle), -- cgit v1.2.3