Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add helper to get errno and error message #20324

Merged
merged 6 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions onnxruntime/core/platform/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,29 @@

Env::Env() = default;

std::pair<int, std::string> GetErrnoInfo() {

Check warning on line 37 in onnxruntime/core/platform/env.cc

View workflow job for this annotation

GitHub Actions / Lint C++

[cpplint] reported by reviewdog 🐶 Add #include <utility> for pair<> [build/include_what_you_use] [4] Raw Output: onnxruntime/core/platform/env.cc:37: Add #include <utility> for pair<> [build/include_what_you_use] [4]
auto err = errno;
std::string msg;

if (err != 0) {
char buf[512];

#if defined(_WIN32)
auto ret = strerror_s(buf, sizeof(buf), err);
msg = ret == 0 ? buf : "Failed to get error message"; // buf is guaranteed to be null terminated by strerror_s
#else
// strerror_r return type differs by platform.
auto ret = strerror_r(err, buf, sizeof(buf));
if constexpr (std::is_same_v<decltype(ret), int>) { // POSIX returns int
msg = ret == 0 ? buf : "Failed to get error message";
} else {
// GNU returns char*
msg = ret;
}
#endif
}

return {err, msg};
}

} // namespace onnxruntime
7 changes: 7 additions & 0 deletions onnxruntime/core/platform/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,13 @@
std::ostream& operator<<(std::ostream& os, const LogicalProcessors&);
std::ostream& operator<<(std::ostream& os, gsl::span<const LogicalProcessors>);

/// <summary>
/// Get errno and the corresponding error message.
/// </summary>
/// <returns>errno and the error message string if errno indicates an error.</returns>
std::pair<int, std::string> GetErrnoInfo();

Check warning on line 103 in onnxruntime/core/platform/env.h

View workflow job for this annotation

GitHub Actions / Lint C++

[cpplint] reported by reviewdog 🐶 Add #include <utility> for pair<> [build/include_what_you_use] [4] Raw Output: onnxruntime/core/platform/env.h:103: Add #include <utility> for pair<> [build/include_what_you_use] [4]


/// \brief An interface used by the onnxruntime implementation to
/// access operating system functionality like the filesystem etc.
///
Expand Down
48 changes: 11 additions & 37 deletions onnxruntime/core/platform/posix/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,39 +62,11 @@ class UnmapFileParam {
size_t len;
};

/**
* @brief Get System Error
*
* @return a pair of {errno, error message}
*/
static std::pair<int, std::string> GetSystemError(int e) {
char buf[1024];
const char* msg = "";
if (e > 0) {
#if defined(__GLIBC__) && defined(_GNU_SOURCE) && !defined(__ANDROID__)
msg = strerror_r(e, buf, sizeof(buf));
#else
// for Mac OS X and Android lower than API 23
if (strerror_r(e, buf, sizeof(buf)) != 0) {
buf[0] = '\0';
}
msg = buf;
#endif
}

return std::make_pair(e, msg);
}

static std::pair<int, std::string> GetSystemError() {
auto e = errno;
return GetSystemError(e);
}

static void UnmapFile(void* param) noexcept {
std::unique_ptr<UnmapFileParam> p(reinterpret_cast<UnmapFileParam*>(param));
int ret = munmap(p->addr, p->len);
if (ret != 0) {
auto [err_no, err_msg] = GetSystemError();
auto [err_no, err_msg] = GetErrnoInfo();
LOGS_DEFAULT(ERROR) << "munmap failed. error code: " << err_no << " error msg: " << err_msg;
}
}
Expand All @@ -104,8 +76,9 @@ struct FileDescriptorTraits {
static Handle GetInvalidHandleValue() { return -1; }
static void CleanUp(Handle h) {
if (close(h) == -1) {
auto [err_no, err_msg] = GetSystemError();
LOGS_DEFAULT(ERROR) << "Failed to close file descriptor " << h << " - error code: " << err_no << " error msg: " << err_msg;
auto [err_no, err_msg] = GetErrnoInfo();
LOGS_DEFAULT(ERROR) << "Failed to close file descriptor " << h << " - error code: " << err_no
<< " error msg: " << err_msg;
}
}
};
Expand All @@ -131,7 +104,7 @@ int nftw_remove(
int /*typeflag*/, struct FTW* /*ftwbuf*/) {
const auto result = remove(fpath);
if (result != 0) {
auto [err_no, err_msg] = GetSystemError();
auto [err_no, err_msg] = GetErrnoInfo();
LOGS_DEFAULT(WARNING) << "remove() failed. Error code: " << err_no << " error msg: " << err_msg
<< ", path: " << fpath;
}
Expand Down Expand Up @@ -188,22 +161,22 @@ class PosixThread : public EnvThread {
pthread_attr_t attr;
int s = pthread_attr_init(&attr);
if (s != 0) {
auto [err_no, err_msg] = GetSystemError();
auto [err_no, err_msg] = GetErrnoInfo();
ORT_THROW("pthread_attr_init failed, error code: ", err_no, " error msg: ", err_msg);
}

size_t stack_size = thread_options.stack_size;
if (stack_size > 0) {
s = pthread_attr_setstacksize(&attr, stack_size);
if (s != 0) {
auto [err_no, err_msg] = GetSystemError();
auto [err_no, err_msg] = GetErrnoInfo();
ORT_THROW("pthread_attr_setstacksize failed, error code: ", err_no, " error msg: ", err_msg);
}
}

s = pthread_create(&hThread, &attr, ThreadMain, param_ptr.get());
if (s != 0) {
auto [err_no, err_msg] = GetSystemError();
auto [err_no, err_msg] = GetErrnoInfo();
ORT_THROW("pthread_create failed, error code: ", err_no, " error msg: ", err_msg);
}
param_ptr.release();
Expand Down Expand Up @@ -249,7 +222,8 @@ class PosixThread : public EnvThread {
<< ", index: " << p->index
<< ", mask: " << *p->affinity;
} else {
auto [err_no, err_msg] = GetSystemError(ret);
errno = ret;
auto [err_no, err_msg] = GetErrnoInfo();
#if !defined(USE_MIGRAPHX)
LOGS_DEFAULT(ERROR) << "pthread_setaffinity_np failed for thread: " << syscall(SYS_gettid)
<< ", index: " << p->index
Expand Down Expand Up @@ -461,7 +435,7 @@ class PosixEnv : public Env {
}

static common::Status ReportSystemError(const char* operation_name, const std::string& path) {
auto [err_no, err_msg] = GetSystemError();
auto [err_no, err_msg] = GetErrnoInfo();
std::ostringstream oss;
oss << operation_name << " file \"" << path << "\" failed: " << err_msg;
return common::Status(common::SYSTEM, err_no, oss.str());
Expand Down
7 changes: 3 additions & 4 deletions onnxruntime/core/platform/windows/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,10 @@ class WindowsThread : public EnvThread {
local_param.get(), 0,
&threadID);
if (th_handle == 0) {
auto err = errno;
auto dos_error = _doserrno;
char message_buf[256];
strerror_s(message_buf, sizeof(message_buf), err);
ORT_THROW("WindowThread:_beginthreadex failed with message: ", message_buf, " doserrno: ", dos_error);
auto [err, msg] = GetErrnoInfo();
ORT_THROW("WindowThread:_beginthreadex failed with errno:", err, " message:", msg,
" doserrno:", dos_error);
}
local_param.release();
hThread.reset(reinterpret_cast<HANDLE>(th_handle));
Expand Down
20 changes: 20 additions & 0 deletions onnxruntime/test/platform/env_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,25 @@ TEST(PlatformEnvTest, DirectoryCreationAndDeletion) {
ASSERT_FALSE(env.FolderExists(root_dir));
}

TEST(PlatformEnvTest, GetErrnoInfo) {
// command that should generate an errno error
std::ifstream file("non_existent_file");
ASSERT_TRUE(file.fail());
auto [err, msg] = GetErrnoInfo();
ASSERT_EQ(err, ENOENT);

#if defined(_WIN32)
#pragma warning(push)
#pragma warning(disable : 4996)
#endif

// GetErrnoInfo uses strerror_r or strerror_s depending on the platform. use the unsafe std::sterror to get the
// expected value given this is a unit test so doesn't have to be as robust.
ASSERT_EQ(msg, std::strerror(ENOENT));

#if defined(_WIN32)
#pragma warning(pop)
#endif
}
} // namespace test
} // namespace onnxruntime
Loading