Skip to content

Commit

Permalink
sysdeps: Add support for vfprintf() logging
Browse files Browse the repository at this point in the history
Introduce a build flag to make logging calls (avb_{debug,error,fatal})
use vfprintf(3) instead of printf(3), which greatly improves the
probability of the call resulting in a single write(2), as opposed to
our current implementation of avb_printv(), which calls fprintf(3) once
per received argument.

This is useful when stderr points to a file that is shared and/or format
entries per write(2) call, such as /dev/kmsg. Note that client code
passing the now deprecated NULL sentinel to the logging macros
avb_{debug,error,fatal}() must NOT enable this feature.

Test: -
Reported-by: JeongHyeon Lee <[email protected]>
Change-Id: I0f30d21939fca7ceb9e96ac7d443512fe7c301d9
  • Loading branch information
ptosi authored and openvela-robot committed Nov 20, 2024
1 parent 2421c10 commit 592e186
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 0 deletions.
7 changes: 7 additions & 0 deletions libavb/avb_sysdeps.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ extern "C" {
*/
#define AVB_ATTR_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#define AVB_ATTR_PACKED __attribute__((packed))
#define AVB_ATTR_PRINTF(x, y) __attribute__((format(printf, x, y)))
#define AVB_ATTR_NO_RETURN __attribute__((noreturn))
#define AVB_ATTR_SENTINEL __attribute__((__sentinel__))

Expand Down Expand Up @@ -99,6 +100,12 @@ void avb_print(const char* message);
*/
void avb_printv(const char* message, ...) AVB_ATTR_SENTINEL;

/* Prints out a formatted string.
*
* Replaces avb_printv when AVB_USE_PRINTF_LOGS is enabled.
*/
void avb_printf(const char* fmt, ...) AVB_ATTR_PRINTF(1, 2);

/* Aborts the program or reboots the device. */
void avb_abort(void) AVB_ATTR_NO_RETURN;

Expand Down
7 changes: 7 additions & 0 deletions libavb/avb_sysdeps_posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ void avb_abort(void) {
abort();
}

void avb_printf(const char* fmt, ...) {
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}

void avb_print(const char* message) {
fprintf(stderr, "%s", message);
}
Expand Down
28 changes: 28 additions & 0 deletions libavb/avb_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,34 @@
extern "C" {
#endif

#define AVB_CONCAT(x, y) x##y
#define AVB_STRINGIFY(x) #x
#define AVB_TO_STRING(x) AVB_STRINGIFY(x)

#define AVB__COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, x, ...) x
#define AVB_COUNT_ARGS(...) \
AVB__COUNT_ARGS(, ##__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0)

#define AVB__REPEAT0(x)
#define AVB__REPEAT1(x) x
#define AVB__REPEAT2(x) AVB__REPEAT1(x) x
#define AVB__REPEAT3(x) AVB__REPEAT2(x) x
#define AVB__REPEAT4(x) AVB__REPEAT3(x) x
#define AVB__REPEAT5(x) AVB__REPEAT4(x) x
#define AVB__REPEAT6(x) AVB__REPEAT5(x) x
#define AVB__REPEAT7(x) AVB__REPEAT6(x) x
#define AVB__REPEAT(n, x) AVB_CONCAT(AVB__REPEAT, n)(x)
#define AVB_REPEAT(n, x) AVB__REPEAT(n, x)

#ifdef AVB_USE_PRINTF_LOGS
#define AVB_LOG(level, message, ...) \
avb_printf("%s:%d: " level \
": " AVB_REPEAT(AVB_COUNT_ARGS(message, ##__VA_ARGS__), "%s"), \
avb_basename(__FILE__), \
__LINE__, \
message, \
##__VA_ARGS__)
#else
#define AVB_LOG(level, message, ...) \
avb_printv(avb_basename(__FILE__), \
":", \
Expand All @@ -46,6 +71,7 @@ extern "C" {
message, \
##__VA_ARGS__, \
NULL)
#endif

#ifdef AVB_ENABLE_DEBUG
/* Aborts the program if |expr| is false.
Expand Down Expand Up @@ -105,11 +131,13 @@ extern "C" {
avb_abort(); \
} while (0)

#ifndef AVB_USE_PRINTF_LOGS
/* Deprecated legacy logging functions -- kept for client compatibility.
*/
#define avb_debugv(message, ...) avb_debug(message, ##__VA_ARGS__)
#define avb_errorv(message, ...) avb_error(message, ##__VA_ARGS__)
#define avb_fatalv(message, ...) avb_fatal(message, ##__VA_ARGS__)
#endif

/* Converts a 16-bit unsigned integer from big-endian to host byte order. */
uint16_t avb_be16toh(uint16_t in) AVB_ATTR_WARN_UNUSED_RESULT;
Expand Down
7 changes: 7 additions & 0 deletions test/avb_sysdeps_posix_testing.cc
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ void avb_printv(const char* message, ...) {
va_end(ap);
}

void avb_printf(const char* fmt, ...) {
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}

typedef struct {
size_t size;
base::debug::StackTrace stack_trace;
Expand Down

0 comments on commit 592e186

Please sign in to comment.