[llvm] [orc-rt] Pass the reporting Session to Session error reporters. (PR #226622)
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 25 18:46:52 PDT 2026
https://github.com/lhames created https://github.com/llvm/llvm-project/pull/226622
Session error reporters previously received only the Error, and had to be supplied to the Session constructor, so they had no direct way to refer to the Session reporting the error (e.g. to include its address in a log message).
This commit changes ErrorReporterFn to take the reporting Session along with the Error, and adds a Session::logErrors reporter that logs errors via ORC_RT_LOG at Error level in the Session category. logErrors is only available when Error-level logging is compiled in (ORC_RT_LOG_ENABLED(Error)), so that it can't silently discard errors in configurations where logging is compiled out. The noErrors and AccumulateErrors test helpers are updated to work as both plain and Session error reporters.
>From 2491fc91842ce43c1368aae314cc27c7977dd0eb Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Sat, 26 Sep 2026 11:00:50 +1000
Subject: [PATCH] [orc-rt] Pass the reporting Session to Session error
reporters.
Session error reporters previously received only the Error, and had to be
supplied to the Session constructor, so they had no direct way to refer to
the Session reporting the error (e.g. to include its address in a log
message).
This commit changes ErrorReporterFn to take the reporting Session along with
the Error, and adds a Session::logErrors reporter that logs errors via
ORC_RT_LOG at Error level in the Session category. logErrors is only
available when Error-level logging is compiled in (ORC_RT_LOG_ENABLED(Error)),
so that it can't silently discard errors in configurations where logging is
compiled out. The noErrors and AccumulateErrors test helpers are updated to
work as both plain and Session error reporters.
---
orc-rt/include/orc-rt/bedrock/Session.h | 24 +++++++++++++--
orc-rt/lib/bedrock/Session.cpp | 11 +++++++
orc-rt/test/unit/CommonTestUtils.h | 27 +++++++++++++++--
.../bedrock/InProcessControllerAccessTest.cpp | 2 +-
orc-rt/test/unit/bedrock/SessionTest.cpp | 30 +++++++++++++++----
orc-rt/tools/ogre/ogre.cpp | 2 +-
6 files changed, 83 insertions(+), 13 deletions(-)
diff --git a/orc-rt/include/orc-rt/bedrock/Session.h b/orc-rt/include/orc-rt/bedrock/Session.h
index d9bc61359ccc6..49542ca14df3c 100644
--- a/orc-rt/include/orc-rt/bedrock/Session.h
+++ b/orc-rt/include/orc-rt/bedrock/Session.h
@@ -23,6 +23,7 @@
#include "orc-rt/support/WrapperFunction.h"
#include "orc-rt/support/move_only_function.h"
+#include "orc-rt-c/config.h"
#include "orc-rt-c/support/CoreTypes.h"
#include "orc-rt-c/support/WrapperFunction.h"
@@ -71,7 +72,7 @@ class Session {
};
public:
- using ErrorReporterFn = move_only_function<void(Error) noexcept>;
+ using ErrorReporterFn = move_only_function<void(Session &, Error) noexcept>;
using OnDisconnectFn = move_only_function<void(Error) noexcept>;
using OnDetachFn = move_only_function<void() noexcept>;
using OnShutdownFn = move_only_function<void() noexcept>;
@@ -312,6 +313,11 @@ class Session {
/// program are not generally visible to ORC-RT, but can optionally be
/// reported by calling the orc_rt_Session_reportError function.)
///
+ /// The ReportError function is passed the reporting Session along with
+ /// the error, so a single reporter can serve many Sessions, and can
+ /// identify the one reporting (e.g. by address) without needing to be
+ /// constructed with a reference to it.
+ ///
/// The Dispatch callback is invoked to run tasks generated by the Session
/// (incoming wrapper-function calls, and continuations for results returned
/// by the controller), and is responsible for arranging each task to be run
@@ -339,7 +345,7 @@ class Session {
const ExecutorProcessInfo &processInfo() const noexcept { return EPI; }
/// Report an error via the ErrorReporter function.
- void reportError(Error Err) noexcept { ReportError(std::move(Err)); }
+ void reportError(Error Err) noexcept { ReportError(*this, std::move(Err)); }
/// Set a handler to be called when the Session's controller connection ends.
///
@@ -622,6 +628,20 @@ class Session {
return ControllerCaller(*this, T);
}
+ /// Error reporter that logs errors via ORC_RT_LOG at Error level in the
+ /// Session category, tagged with the reporting Session's address.
+ ///
+ /// Only available if Error-level logging is compiled in: code that must
+ /// build under every logging configuration should guard uses with
+ /// `#if ORC_RT_LOG_ENABLED(Error)`, and pick another reporter otherwise.
+ /// Errors may still be suppressed at runtime by logging configuration.
+ ///
+ /// NOTE: This is an error reporter, not a general-purpose logging API: pass
+ /// it as the Session's error reporter, and report errors via reportError.
+#if ORC_RT_LOG_ENABLED(Error)
+ static void logErrors(Session &S, Error Err) noexcept;
+#endif
+
private:
enum class State {
/// Used as a placeholder when there is no target state.
diff --git a/orc-rt/lib/bedrock/Session.cpp b/orc-rt/lib/bedrock/Session.cpp
index 4f58964289c87..886d3a9b44d5e 100644
--- a/orc-rt/lib/bedrock/Session.cpp
+++ b/orc-rt/lib/bedrock/Session.cpp
@@ -253,6 +253,17 @@ void Session::addOnShutdown(OnShutdownFn OnShutdown) {
OnShutdown();
}
+#if ORC_RT_LOG_ENABLED(Error)
+void Session::logErrors(Session &S, Error Err) noexcept {
+ // Take the message outside ORC_RT_LOG: the os_log backend only evaluates
+ // log arguments if the log type is enabled at runtime, which would leave
+ // Err unchecked otherwise.
+ auto ErrMsg = toString(std::move(Err));
+ ORC_RT_LOG(Error, Session, "Session %p error: " ORC_RT_LOG_PUB_S, &S,
+ ErrMsg.c_str());
+}
+#endif // ORC_RT_LOG_ENABLED(Error)
+
void Session::appendService(std::unique_ptr<Service> Srv) {
bool ShuttingDown = false;
diff --git a/orc-rt/test/unit/CommonTestUtils.h b/orc-rt/test/unit/CommonTestUtils.h
index a54a2055c29e1..f715b689da0bc 100644
--- a/orc-rt/test/unit/CommonTestUtils.h
+++ b/orc-rt/test/unit/CommonTestUtils.h
@@ -11,7 +11,9 @@
// Helpers here must not depend on Bedrock: this header is included by
// SupportTests translation units, which link Support alone. Bedrock-dependent
-// helpers belong in BedrockTestUtils.h.
+// helpers belong in BedrockTestUtils.h. (Session is forward-declared below so
+// that the error-reporter helpers can also serve as Session error reporters;
+// they never use the Session, so this adds no link dependency.)
#include "orc-rt/support/Error.h"
#include "orc-rt/support/WrapperFunction.h"
@@ -29,12 +31,29 @@
#include "gtest/gtest.h"
+namespace orc_rt {
+class Session;
+} // namespace orc_rt
+
namespace orc_rt::test {
-inline void noErrors(Error Err) noexcept { cantFail(std::move(Err)); }
+/// Error reporter for tests that expect no errors. Usable both as a plain
+/// error reporter and as a Session error reporter.
+///
+/// This is a function object rather than a pair of overloaded functions so
+/// that it can be passed to templated callable parameters (e.g.
+/// move_only_function's constructor): the name of an overload set can't be
+/// deduced.
+inline constexpr struct NoErrors {
+ void operator()(Error Err) const noexcept { cantFail(std::move(Err)); }
+ void operator()(Session &, Error Err) const noexcept {
+ cantFail(std::move(Err));
+ }
+} noErrors;
/// ReportError callback for tests that records the message of every reported
-/// error, in the order reported.
+/// error, in the order reported. Like noErrors, usable both as a plain error
+/// reporter and as a Session error reporter.
class AccumulateErrors {
public:
AccumulateErrors(std::vector<std::string> &ErrMsgs) : ErrMsgs(ErrMsgs) {}
@@ -43,6 +62,8 @@ class AccumulateErrors {
ErrMsgs.push_back(toString(std::move(Err)));
}
+ void operator()(Session &, Error Err) noexcept { (*this)(std::move(Err)); }
+
private:
std::vector<std::string> &ErrMsgs;
};
diff --git a/orc-rt/test/unit/bedrock/InProcessControllerAccessTest.cpp b/orc-rt/test/unit/bedrock/InProcessControllerAccessTest.cpp
index f936105210b11..e8535241ff62e 100644
--- a/orc-rt/test/unit/bedrock/InProcessControllerAccessTest.cpp
+++ b/orc-rt/test/unit/bedrock/InProcessControllerAccessTest.cpp
@@ -175,7 +175,7 @@ TEST(InProcessControllerAccessTest, OnConnectFailureIsReportedAndDetaches) {
cantFail(std::move(Reported)); // force checked state
Session S(mockExecutorProcessInfo(), noDispatch,
- [&](Error E) noexcept { Reported = std::move(E); });
+ [&](Session &, Error E) noexcept { Reported = std::move(E); });
S.attach<InProcessControllerAccess>(
BootstrapInfo(S),
diff --git a/orc-rt/test/unit/bedrock/SessionTest.cpp b/orc-rt/test/unit/bedrock/SessionTest.cpp
index 493249ad55689..30389e44d0ae5 100644
--- a/orc-rt/test/unit/bedrock/SessionTest.cpp
+++ b/orc-rt/test/unit/bedrock/SessionTest.cpp
@@ -338,21 +338,38 @@ TEST(SessionTest, TrivialConstructionAndDestruction) {
TEST(SessionTest, ReportError) {
Error E = Error::success();
cantFail(std::move(E)); // Force error into checked state.
+ Session *Reporter = nullptr;
Session S(mockExecutorProcessInfo(), noDispatch,
- [&](Error Err) noexcept { E = std::move(Err); });
+ [&](Session &RS, Error Err) noexcept {
+ Reporter = &RS;
+ E = std::move(Err);
+ });
S.reportError(make_error<StringError>("foo"));
+ // The reporter should be passed the reporting Session.
+ EXPECT_EQ(Reporter, &S);
EXPECT_THAT_ERROR(std::move(E), FailedWithMessage("foo"));
}
+TEST(SessionTest, LogErrors) {
+#if ORC_RT_LOG_ENABLED(Error)
+ // Check that Session::logErrors can be used as an error reporter, and
+ // consumes the reported error (an unchecked Error would abort).
+ Session S(mockExecutorProcessInfo(), noDispatch, Session::logErrors);
+ S.reportError(make_error<StringError>("foo"));
+#else
+ GTEST_SKIP() << "Test requires ORC_RT_LOG_ENABLED(Error)";
+#endif // ORC_RT_LOG_ENABLED(Error)
+}
+
TEST(SessionTest, ReportErrorsViaSession) {
Error E = Error::success();
cantFail(std::move(E)); // Force error into checked state.
// Check that the ReportErrorsViaSession utility works as advertised.
Session S(mockExecutorProcessInfo(), noDispatch,
- [&](Error Err) noexcept { E = std::move(Err); });
+ [&](Session &, Error Err) noexcept { E = std::move(Err); });
(ReportErrorsViaSession(S))(make_error<StringError>("foo"));
EXPECT_THAT_ERROR(std::move(E), FailedWithMessage("foo"));
@@ -854,10 +871,11 @@ TEST(ControllerAccessTest, FailConnect) {
// Simulate failure to connect.
bool GotError = false;
std::string ErrMsg = "failed to connect";
- Session S(mockExecutorProcessInfo(), noDispatch, [&](Error Err) noexcept {
- GotError = true;
- EXPECT_THAT_ERROR(std::move(Err), FailedWithMessage(ErrMsg));
- });
+ Session S(mockExecutorProcessInfo(), noDispatch,
+ [&](Session &, Error Err) noexcept {
+ GotError = true;
+ EXPECT_THAT_ERROR(std::move(Err), FailedWithMessage(ErrMsg));
+ });
BootstrapInfo BI(S);
S.attach<MockControllerAccess>(
std::move(BI), MockControllerAccess::PostFn{},
diff --git a/orc-rt/tools/ogre/ogre.cpp b/orc-rt/tools/ogre/ogre.cpp
index c98da66fba319..398622275066a 100644
--- a/orc-rt/tools/ogre/ogre.cpp
+++ b/orc-rt/tools/ogre/ogre.cpp
@@ -136,7 +136,7 @@ Expected<int> runOgre(const Options &Opts) noexcept {
ThreadPoolRunner Run(4);
Session S(
std::move(*EPI), [&Run](Session::Task T) { Run(std::move(T)); },
- reportError);
+ [](Session &, Error Err) noexcept { reportError(std::move(Err)); });
std::promise<void> StopP;
auto StopF = StopP.get_future();
More information about the llvm-commits
mailing list