| 1 | Patch-Source: https://github.com/oneapi-src/level-zero/pull/493
|
| 2 | --
|
| 3 | From c3ae2c4b50aecd00687e9c914c87b1b24a7febe2 Mon Sep 17 00:00:00 2001
|
| 4 | From: Russell McGuire <[email protected]>
|
| 5 | Date: Tue, 7 Jul 2026 13:00:31 -0700
|
| 6 | Subject: [PATCH] Fix incompatible strerror_r for non-gnu/windows libc
|
| 7 |
|
| 8 | Signed-off-by: Russell McGuire <[email protected]>
|
| 9 | ---
|
| 10 | source/utils/ze_logger.cpp | 37 +++++++++++++++++++++++++++++--------
|
| 11 | 1 file changed, 29 insertions(+), 8 deletions(-)
|
| 12 |
|
| 13 | diff --git a/source/utils/ze_logger.cpp b/source/utils/ze_logger.cpp
|
| 14 | index 76d22c90..1049dd6e 100644
|
| 15 | |
| 16 | |
| 17 | @@ -105,20 +105,41 @@ const char *levelColor(LogLevel l) {
|
| 18 | }
|
| 19 |
|
| 20 | // Thread-safe, portable errno-to-string conversion.
|
| 21 | -// MSVC deprecates strerror() in favour of strerror_s(); POSIX provides strerror_r().
|
| 22 | +// strerror_r has two incompatible POSIX signatures depending on libc:
|
| 23 | +// - GNU: char *strerror_r(int, char *, size_t) (glibc with _GNU_SOURCE)
|
| 24 | +// - XSI: int strerror_r(int, char *, size_t) (musl, Bionic, uClibc, POSIX)
|
| 25 | +// _GNU_SOURCE is not a reliable discriminator — it requests GNU extensions but
|
| 26 | +// only glibc honours it for strerror_r. We let overload resolution pick the
|
| 27 | +// right handler based on the actual return type the compiler sees, so the
|
| 28 | +// code is correct under any libc without preprocessor guesswork.
|
| 29 | +// MSVC uses strerror_s.
|
| 30 | +#ifndef _WIN32
|
| 31 | +// Mark both overloads as "may be unused" — only one matches strerror_r's
|
| 32 | +// signature for any given libc, so the other is intentionally dead code.
|
| 33 | +#if defined(__GNUC__) || defined(__clang__)
|
| 34 | +#define ZE_LOGGER_MAYBE_UNUSED __attribute__((unused))
|
| 35 | +#else
|
| 36 | +#define ZE_LOGGER_MAYBE_UNUSED
|
| 37 | +#endif
|
| 38 | +// XSI variant: returns int (0 on success); message is in `buf`.
|
| 39 | +static ZE_LOGGER_MAYBE_UNUSED std::string strerrorRDispatch(int /*ret*/, char *buf) {
|
| 40 | + return std::string(buf);
|
| 41 | +}
|
| 42 | +// GNU variant: returns char* that may or may not point at `buf`.
|
| 43 | +static ZE_LOGGER_MAYBE_UNUSED std::string strerrorRDispatch(char *ret, char *buf) {
|
| 44 | + return ret ? std::string(ret) : std::string(buf);
|
| 45 | +}
|
| 46 | +#undef ZE_LOGGER_MAYBE_UNUSED
|
| 47 | +#endif
|
| 48 | +
|
| 49 | static std::string errnoToString(int err) {
|
| 50 | char buf[256];
|
| 51 | + buf[0] = '\0';
|
| 52 | #ifdef _WIN32
|
| 53 | strerror_s(buf, sizeof(buf), err);
|
| 54 | return buf;
|
| 55 | -#elif defined(_GNU_SOURCE)
|
| 56 | - // GNU strerror_r returns char* (may or may not use buf)
|
| 57 | - const char *result = strerror_r(err, buf, sizeof(buf));
|
| 58 | - return result ? result : buf;
|
| 59 | #else
|
| 60 | - // XSI-compliant strerror_r returns int
|
| 61 | - strerror_r(err, buf, sizeof(buf));
|
| 62 | - return buf;
|
| 63 | + return strerrorRDispatch(strerror_r(err, buf, sizeof(buf)), buf);
|
| 64 | #endif
|
| 65 | }
|
| 66 |
|