diff --git a/include/libcamera/base/log.h b/include/libcamera/base/log.h
index 5cb14311e..7bd43a423 100644
--- a/include/libcamera/base/log.h
+++ b/include/libcamera/base/log.h
@@ -88,6 +88,19 @@ private:
 	std::string prefix_;
 };
 
+#ifndef __DOXYGEN__
+template<LogSeverity>
+struct LogMessageAbortGuard {
+};
+
+template<>
+struct LogMessageAbortGuard<LogFatal> {
+	LogMessageAbortGuard() = default;
+	LIBCAMERA_DISABLE_COPY_AND_MOVE(LogMessageAbortGuard)
+	[[noreturn]] ~LogMessageAbortGuard();
+};
+#endif
+
 class Loggable
 {
 public:
@@ -124,7 +137,8 @@ constexpr int isLogSeverityEnabled(const LogCategory &category)
 	switch (const auto &_logCategory = (cat);             \
 		isLogSeverityEnabled<Log##sev>(_logCategory)) \
 	case 1:                                               \
-		_log(_logCategory, Log##sev).stream()
+		(LogMessageAbortGuard<Log##sev>(),            \
+		 _log(_logCategory, Log##sev).stream())
 
 #define _LOG1(severity) \
 	_LOG(LogCategory::defaultCategory(), severity)
diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp
index 0921e5485..3404471fc 100644
--- a/src/libcamera/base/log.cpp
+++ b/src/libcamera/base/log.cpp
@@ -869,11 +869,6 @@ LogMessage::~LogMessage()
 	msgStream_ << std::endl;
 
 	logger->write(*this);
-
-	if (severity_ == LogSeverity::LogFatal) {
-		logger->backtrace();
-		std::abort();
-	}
 }
 
 /**
@@ -922,6 +917,17 @@ LogMessage::~LogMessage()
  * \return The message text of the message, as a string
  */
 
+#ifndef __DOXYGEN__
+LogMessageAbortGuard<LogFatal>::~LogMessageAbortGuard()
+{
+	Logger *logger = Logger::instance();
+	if (logger)
+		logger->backtrace();
+
+	std::abort();
+}
+#endif
+
 /**
  * \class Loggable
  * \brief Base class to support log message extensions
