Skip to content

Commit e399c8c

Browse files
authored
fix: catch exceptions in print-uncaught-messages destructor (#5103)
Fixes #5063 In that issue, it was reported that the printing of any unretrieved error messages upon destruction of an ImageBuf could itself have an exception (including if it, for some reason, could not correctly fwrite the output). And if that is the case, it could terminate the app. So for safety, this patch encloses this particular print statement in a try/catch. And also found another in ErrorHolder in the internals of Strutil, which is used for "global" errors issued to OIIO::errorfmt(). Assisted-by: Claude Code / Opus 4.6 I did the fix in ImageBuf, then Claude found the other spot in ErrorHolder that also needed the fix. Signed-off-by: Larry Gritz <lg@larrygritz.com>
1 parent 10533de commit e399c8c

File tree

2 files changed

+18
-8
lines changed

2 files changed

+18
-8
lines changed

src/libOpenImageIO/imagebuf.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -575,10 +575,15 @@ ImageBufImpl::~ImageBufImpl()
575575
// how to properly check for errors.
576576
if (!m_err.empty() /* Note: safe becausethis is the dtr */
577577
&& OIIO::pvt::imagebuf_print_uncaught_errors) {
578-
OIIO::print(
579-
"An ImageBuf was destroyed with a pending error message that was never\n"
580-
"retrieved via ImageBuf::geterror(). This was the error message:\n{}\n",
581-
m_err);
578+
try {
579+
OIIO::print(
580+
"An ImageBuf was destroyed with a pending error message that was never\n"
581+
"retrieved via ImageBuf::geterror(). This was the error message:\n{}\n",
582+
m_err);
583+
} catch (...) {
584+
// Swallow any exceptions (e.g., from fmt's fwrite_fully)
585+
// to avoid std::terminate from throwing in a destructor.
586+
}
582587
}
583588
}
584589

src/libutil/strutil.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,15 @@ struct ErrorHolder {
201201
~ErrorHolder()
202202
{
203203
if (!error_msg.empty() && OIIO::pvt::oiio_print_uncaught_errors) {
204-
OIIO::print(
205-
"OpenImageIO exited with a pending error message that was never\n"
206-
"retrieved via OIIO::geterror(). This was the error message:\n{}\n",
207-
error_msg);
204+
try {
205+
OIIO::print(
206+
"OpenImageIO exited with a pending error message that was never\n"
207+
"retrieved via OIIO::geterror(). This was the error message:\n{}\n",
208+
error_msg);
209+
} catch (...) {
210+
// Swallow any exceptions (e.g., from fmt's fwrite_fully)
211+
// to avoid std::terminate from throwing in a destructor.
212+
}
208213
}
209214
}
210215
};

0 commit comments

Comments
 (0)