From 8e8d88e4b2d542c269ce4673bb6177d6519aa54e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Mon, 18 Dec 2023 14:22:57 +0100 Subject: [PATCH] Update for OPENPMD_VERBOSE logging (#1574) * Log intercepted I/O exceptions in verbose mode * Fix undefined behavior in verbose logging of deregister task --- include/openPMD/IO/IOTask.hpp | 13 +++++++-- src/IO/AbstractIOHandlerImpl.cpp | 50 ++++++++++++++++++++++++++------ src/backend/Writable.cpp | 2 +- 3 files changed, 53 insertions(+), 12 deletions(-) diff --git a/include/openPMD/IO/IOTask.hpp b/include/openPMD/IO/IOTask.hpp index 8ded6f1775..f32fc36785 100644 --- a/include/openPMD/IO/IOTask.hpp +++ b/include/openPMD/IO/IOTask.hpp @@ -30,6 +30,7 @@ #include "openPMD/backend/Attribute.hpp" #include "openPMD/backend/ParsePreference.hpp" +#include #include #include #include @@ -680,15 +681,23 @@ template <> struct OPENPMDAPI_EXPORT Parameter : public AbstractParameter { - Parameter() = default; - Parameter(Parameter const &) : AbstractParameter() + Parameter(void const *ptr_in) : former_parent(ptr_in) {} + Parameter(Parameter const &) = default; + Parameter(Parameter &&) = default; + + Parameter &operator=(Parameter const &) = default; + Parameter &operator=(Parameter &&) = default; + std::unique_ptr to_heap() && override { return std::make_unique>( std::move(*this)); } + + // Just for verbose logging. + void const *former_parent = nullptr; }; /** @brief Self-contained description of a single IO operation. diff --git a/src/IO/AbstractIOHandlerImpl.cpp b/src/IO/AbstractIOHandlerImpl.cpp index 01b489f4dd..edacb0e402 100644 --- a/src/IO/AbstractIOHandlerImpl.cpp +++ b/src/IO/AbstractIOHandlerImpl.cpp @@ -358,7 +358,11 @@ std::future AbstractIOHandlerImpl::flush() auto ¶meter = deref_dynamic_cast>( i.parameter.get()); writeToStderr( - "[", i.writable->parent, "->", i.writable, "] DEREGISTER"); + "[", + parameter.former_parent, + "->", + i.writable, + "] DEREGISTER"); deregister(i.writable, parameter); break; } @@ -366,16 +370,44 @@ std::future AbstractIOHandlerImpl::flush() } catch (...) { - std::cerr << "[AbstractIOHandlerImpl] IO Task " - << internal::operationAsString(i.operation) - << " failed with exception. Clearing IO queue and " - "passing on the exception." - << std::endl; - while (!m_handler->m_work.empty()) + auto base_handler = [&i, this]() { + std::cerr << "[AbstractIOHandlerImpl] IO Task " + << internal::operationAsString(i.operation) + << " failed with exception. Clearing IO queue and " + "passing on the exception." + << std::endl; + while (!m_handler->m_work.empty()) + { + m_handler->m_work.pop(); + } + }; + + if (m_verboseIOTasks) + { + try + { + // Throw again so we can distinguish between std::exception + // and other exception types. + throw; + } + catch (std::exception const &e) + { + base_handler(); + std::cerr << "Original exception: " << e.what() + << std::endl; + throw; + } + catch (...) + { + base_handler(); + throw; + } + } + else { - m_handler->m_work.pop(); + base_handler(); + throw; } - throw; } (*m_handler).m_work.pop(); } diff --git a/src/backend/Writable.cpp b/src/backend/Writable.cpp index 97d13ce5f0..1762a4cefb 100644 --- a/src/backend/Writable.cpp +++ b/src/backend/Writable.cpp @@ -39,7 +39,7 @@ Writable::~Writable() * remove references to this object from internal data structures. */ IOHandler->value()->enqueue( - IOTask(this, Parameter())); + IOTask(this, Parameter(parent))); } void Writable::seriesFlush(std::string backendConfig)