Raw logging should not allocate memory

PiperOrigin-RevId: 374396461
Change-Id: I709103c7834d4803a26a0b292f342a3d629d332c
This commit is contained in:
Wiktor Garbacz 2021-05-18 05:37:10 -07:00 committed by Copybara-Service
parent 2d3a040f64
commit a986278550
6 changed files with 43 additions and 22 deletions

View File

@ -227,7 +227,7 @@ cc_library(
copts = sapi_platform_copts(), copts = sapi_platform_copts(),
deps = [ deps = [
"@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format",
], ],
) )

View File

@ -138,7 +138,7 @@ add_library(sapi_util_strerror ${SAPI_LIB_TYPE}
) )
add_library(sapi::strerror ALIAS sapi_util_strerror) add_library(sapi::strerror ALIAS sapi_util_strerror)
target_link_libraries(sapi_util_strerror PRIVATE target_link_libraries(sapi_util_strerror PRIVATE
absl::strings absl::str_format
sapi::base sapi::base
) )

View File

@ -56,8 +56,6 @@ inline static bool VADoRawLog(char** buf, int* size, const char* format,
return result; return result;
} }
static constexpr int kLogBufSize = 3000;
namespace { namespace {
// CAVEAT: vsnprintf called from *DoRawLog below has some (exotic) code paths // CAVEAT: vsnprintf called from *DoRawLog below has some (exotic) code paths
@ -83,7 +81,7 @@ void RawLogVA(absl::LogSeverity severity, const char* file, int line,
const char* format, va_list ap) ABSL_PRINTF_ATTRIBUTE(4, 0); const char* format, va_list ap) ABSL_PRINTF_ATTRIBUTE(4, 0);
void RawLogVA(absl::LogSeverity severity, const char* file, int line, void RawLogVA(absl::LogSeverity severity, const char* file, int line,
const char* format, va_list ap) { const char* format, va_list ap) {
char buffer[kLogBufSize]; char buffer[sapi::raw_logging_internal::kLogBufSize];
char* buf = buffer; char* buf = buffer;
int size = sizeof(buffer); int size = sizeof(buffer);

View File

@ -95,11 +95,17 @@
// Like SAPI_RAW_LOG(), but also logs the current value of errno and its // Like SAPI_RAW_LOG(), but also logs the current value of errno and its
// corresponding error message. // corresponding error message.
#define SAPI_RAW_PLOG(severity, format, ...) \ #define SAPI_RAW_PLOG(severity, format, ...) \
do { \ do { \
const auto message = absl::StrFormat((format), ##__VA_ARGS__); \ char sapi_raw_plog_errno_buffer[100]; \
SAPI_RAW_LOG(severity, "%s: %s [%d]", message.c_str(), \ const char* sapi_raw_plog_errno_str = \
::sapi::StrError(errno).c_str(), errno); \ ::sapi::RawStrError(errno, sapi_raw_plog_errno_buffer, \
sizeof(sapi_raw_plog_errno_buffer)); \
char sapi_raw_plog_buffer[::sapi::raw_logging_internal::kLogBufSize]; \
absl::SNPrintF(sapi_raw_plog_buffer, sizeof(sapi_raw_plog_buffer), \
(format), ##__VA_ARGS__); \
SAPI_RAW_LOG(severity, "%s: %s [%d]", sapi_raw_plog_buffer, \
sapi_raw_plog_errno_str, errno); \
} while (0) } while (0)
// If verbose logging is enabled, uses SAPI_RAW_LOG() to log. // If verbose logging is enabled, uses SAPI_RAW_LOG() to log.
@ -110,17 +116,25 @@
// Like SAPI_RAW_CHECK(), but also logs errno and a message (similar to // Like SAPI_RAW_CHECK(), but also logs errno and a message (similar to
// SAPI_RAW_PLOG()). // SAPI_RAW_PLOG()).
#define SAPI_RAW_PCHECK(condition, format, ...) \ #define SAPI_RAW_PCHECK(condition, format, ...) \
do { \ do { \
const auto message = absl::StrFormat((format), ##__VA_ARGS__); \ if (ABSL_PREDICT_FALSE(!(condition))) { \
if (ABSL_PREDICT_FALSE(!(condition))) { \ char sapi_raw_plog_errno_buffer[100]; \
SAPI_RAW_LOG(FATAL, "Check %s failed: %s: %s [%d]", #condition, \ const char* sapi_raw_plog_errno_str = \
message.c_str(), ::sapi::StrError(errno).c_str(), errno); \ ::sapi::RawStrError(errno, sapi_raw_plog_errno_buffer, \
} \ sizeof(sapi_raw_plog_errno_buffer)); \
char sapi_raw_plog_buffer[::sapi::raw_logging_internal::kLogBufSize]; \
absl::SNPrintF(sapi_raw_plog_buffer, sizeof(sapi_raw_plog_buffer), \
(format), ##__VA_ARGS__); \
SAPI_RAW_LOG(FATAL, "Check %s failed: %s: %s [%d]", #condition, \
sapi_raw_plog_buffer, sapi_raw_plog_errno_str, errno); \
} \
} while (0) } while (0)
namespace sapi::raw_logging_internal { namespace sapi::raw_logging_internal {
constexpr int kLogBufSize = 3000;
// Helper function to implement ABSL_RAW_LOG // Helper function to implement ABSL_RAW_LOG
// Logs format... at "severity" level, reporting it // Logs format... at "severity" level, reporting it
// as called from file:line. // as called from file:line.

View File

@ -20,7 +20,7 @@
#include <cstddef> #include <cstddef>
#include "absl/base/attributes.h" #include "absl/base/attributes.h"
#include "absl/strings/str_cat.h" #include "absl/strings/str_format.h"
namespace sapi { namespace sapi {
namespace { namespace {
@ -48,15 +48,20 @@ ABSL_ATTRIBUTE_UNUSED const char* StrErrorR(int (*strerror_r)(int, char*,
} // namespace } // namespace
std::string StrError(int errnum) { const char* RawStrError(int errnum, char* buf, size_t buflen) {
const int saved_errno = errno; const int saved_errno = errno;
char buf[100]; const char* str = StrErrorR(strerror_r, errnum, buf, buflen);
const char* str = StrErrorR(strerror_r, errnum, buf, sizeof(buf));
if (*str == '\0') { if (*str == '\0') {
return absl::StrCat("Unknown error ", errnum); absl::SNPrintF(buf, buflen, "Unknown error %d", errnum);
str = buf;
} }
errno = saved_errno; errno = saved_errno;
return str; return str;
} }
std::string StrError(int errnum) {
char buf[100];
return RawStrError(errnum, buf, sizeof(buf));
}
} // namespace sapi } // namespace sapi

View File

@ -25,6 +25,10 @@ namespace sapi {
// modified by this call. This function is thread-safe. // modified by this call. This function is thread-safe.
std::string StrError(int errnum); std::string StrError(int errnum);
// Same as StrError but uses provided buffer (does not allocate memory).
// Might use and return a static immutable buffer instead of buf.
const char* RawStrError(int errnum, char* buf, size_t buflen);
} // namespace sapi } // namespace sapi
#endif // SANDBOXED_API_STRERROR_H_ #endif // SANDBOXED_API_STRERROR_H_