From c98f9709c42464bda4742306f51d37749f635fb3 Mon Sep 17 00:00:00 2001 From: Elliot Levin Date: Wed, 30 Apr 2025 05:17:44 +0000 Subject: [PATCH 1/3] remove async-signal-unsafe code from signal handler Signed-off-by: Elliot Levin --- src/fluent-bit.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/fluent-bit.c b/src/fluent-bit.c index a97ebb13857..bb45122f051 100644 --- a/src/fluent-bit.c +++ b/src/fluent-bit.c @@ -579,24 +579,9 @@ static void flb_signal_exit(int signal) static void flb_signal_handler_status_line(struct flb_cf *cf_opts) { - int len; - char ts[32]; char s[] = "[engine] caught signal ("; - time_t now; - struct tm *cur; - - now = time(NULL); - cur = localtime(&now); - len = snprintf(ts, sizeof(ts) - 1, "[%i/%02i/%02i %02i:%02i:%02i] ", - cur->tm_year + 1900, - cur->tm_mon + 1, - cur->tm_mday, - cur->tm_hour, - cur->tm_min, - cur->tm_sec); /* write signal number */ - write(STDERR_FILENO, ts, len); write(STDERR_FILENO, s, sizeof(s) - 1); } From cd29f1bb2640ad9b4e685d94af78dae867929322 Mon Sep 17 00:00:00 2001 From: Elliot Levin Date: Fri, 9 May 2025 00:16:19 +0000 Subject: [PATCH 2/3] replace async-signal-unsafe code with safe equivalents Signed-off-by: Elliot Levin --- include/fluent-bit/flb_utils.h | 2 ++ src/flb_utils.c | 38 ++++++++++++++++++++++++++++++++++ src/fluent-bit.c | 28 +++++++++++++++++++++++++ 3 files changed, 68 insertions(+) diff --git a/include/fluent-bit/flb_utils.h b/include/fluent-bit/flb_utils.h index 56f286f6738..95e92803d6f 100644 --- a/include/fluent-bit/flb_utils.h +++ b/include/fluent-bit/flb_utils.h @@ -77,5 +77,7 @@ void flb_utils_set_plugin_string_property(const char *name, int flb_utils_mkdir(const char *dir, int perms); int flb_utils_url_split_sds(const flb_sds_t in_url, flb_sds_t *out_protocol, flb_sds_t *out_host, flb_sds_t *out_port, flb_sds_t *out_uri); +void flb_civil_from_days(int z, uint *year, uint *month, uint *day); +int flb_write_uint(char *buf, int size, uint value); #endif diff --git a/src/flb_utils.c b/src/flb_utils.c index 2b562041790..b963dd184cd 100644 --- a/src/flb_utils.c +++ b/src/flb_utils.c @@ -1880,3 +1880,41 @@ int flb_utils_mkdir(const char *dir, int perms) { return _mkdir(tmp, perms); } + + +/* credit to https://howardhinnant.github.io/date_algorithms.html#civil_from_days */ +void flb_civil_from_days(int z, uint *year, uint *month, uint *day) +{ + z += 719468; + const int era = (z >= 0 ? z : z - 146096) / 146097; + const unsigned doe = (unsigned)(z - era * 146097); // [0, 146096] + const unsigned yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365; // [0, 399] + const int y = (int)(yoe) + era * 400; + const unsigned doy = doe - (365 * yoe + yoe / 4 - yoe / 100); // [0, 365] + const unsigned mp = (5 * doy + 2) / 153; // [0, 11] + const unsigned d = doy - (153 * mp + 2) / 5 + 1; // [1, 31] + const unsigned m = mp + (mp < 10 ? 3 : -9); // [1, 12] + + *year = y + (m <= 2); + *month = m; + *day = d; +} + +int flb_write_uint(char *buf, int size, uint value) +{ + /* write in reverse digit order with right zero padding */ + for (int i = 0; i < size; i++) { + buf[i] = (char) ((value % 10) + '0'); + value /= 10; + } + /* reverse into correct order */ + for (int j = 0; j < size / 2; j++) { + char tmp = buf[j]; + char tmp2 = buf[size - j - 1]; + + buf[size - j - 1] = tmp; + buf[j] = tmp2; + } + + return size; +} \ No newline at end of file diff --git a/src/fluent-bit.c b/src/fluent-bit.c index bb45122f051..e7bc144118e 100644 --- a/src/fluent-bit.c +++ b/src/fluent-bit.c @@ -580,8 +580,36 @@ static void flb_signal_exit(int signal) static void flb_signal_handler_status_line(struct flb_cf *cf_opts) { char s[] = "[engine] caught signal ("; + struct timespec ts; + char tsbuf[32]; + int tspos = 0; + + if (clock_gettime(CLOCK_REALTIME, &ts) == 0) { + uint year, month, day, hh, mm, ss; + + flb_civil_from_days(ts.tv_sec / 86400, &year, &month, &day); + hh = (uint) ((ts.tv_sec % 86400) / 3600); + mm = (uint) ((ts.tv_sec % 3600) / 60); + ss = (uint) (ts.tv_sec % 60); + + tsbuf[tspos++] = '['; + tspos += flb_write_uint(tsbuf + tspos, 4, year); + tsbuf[tspos++] = '/'; + tspos += flb_write_uint(tsbuf + tspos, 2, month); + tsbuf[tspos++] = '/'; + tspos += flb_write_uint(tsbuf + tspos, 2, day); + tsbuf[tspos++] = ' '; + tspos += flb_write_uint(tsbuf + tspos, 2, hh); + tsbuf[tspos++] = ':'; + tspos += flb_write_uint(tsbuf + tspos, 2, mm); + tsbuf[tspos++] = ':'; + tspos += flb_write_uint(tsbuf + tspos, 2, ss); + tsbuf[tspos++] = ']'; + tsbuf[tspos++] = ' '; + } /* write signal number */ + write(STDERR_FILENO, tsbuf, tspos - 1); write(STDERR_FILENO, s, sizeof(s) - 1); } From 2e068d176d7260e1e94872192fb15348e2047f18 Mon Sep 17 00:00:00 2001 From: Elliot Levin Date: Sat, 10 May 2025 01:30:59 +0000 Subject: [PATCH 3/3] store signals in a small ring buffer and process on the main thread Signed-off-by: Elliot Levin --- include/fluent-bit/flb_utils.h | 2 - src/flb_utils.c | 38 ------------ src/fluent-bit.c | 110 ++++++++++++--------------------- 3 files changed, 38 insertions(+), 112 deletions(-) diff --git a/include/fluent-bit/flb_utils.h b/include/fluent-bit/flb_utils.h index 95e92803d6f..56f286f6738 100644 --- a/include/fluent-bit/flb_utils.h +++ b/include/fluent-bit/flb_utils.h @@ -77,7 +77,5 @@ void flb_utils_set_plugin_string_property(const char *name, int flb_utils_mkdir(const char *dir, int perms); int flb_utils_url_split_sds(const flb_sds_t in_url, flb_sds_t *out_protocol, flb_sds_t *out_host, flb_sds_t *out_port, flb_sds_t *out_uri); -void flb_civil_from_days(int z, uint *year, uint *month, uint *day); -int flb_write_uint(char *buf, int size, uint value); #endif diff --git a/src/flb_utils.c b/src/flb_utils.c index b963dd184cd..2b562041790 100644 --- a/src/flb_utils.c +++ b/src/flb_utils.c @@ -1880,41 +1880,3 @@ int flb_utils_mkdir(const char *dir, int perms) { return _mkdir(tmp, perms); } - - -/* credit to https://howardhinnant.github.io/date_algorithms.html#civil_from_days */ -void flb_civil_from_days(int z, uint *year, uint *month, uint *day) -{ - z += 719468; - const int era = (z >= 0 ? z : z - 146096) / 146097; - const unsigned doe = (unsigned)(z - era * 146097); // [0, 146096] - const unsigned yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365; // [0, 399] - const int y = (int)(yoe) + era * 400; - const unsigned doy = doe - (365 * yoe + yoe / 4 - yoe / 100); // [0, 365] - const unsigned mp = (5 * doy + 2) / 153; // [0, 11] - const unsigned d = doy - (153 * mp + 2) / 5 + 1; // [1, 31] - const unsigned m = mp + (mp < 10 ? 3 : -9); // [1, 12] - - *year = y + (m <= 2); - *month = m; - *day = d; -} - -int flb_write_uint(char *buf, int size, uint value) -{ - /* write in reverse digit order with right zero padding */ - for (int i = 0; i < size; i++) { - buf[i] = (char) ((value % 10) + '0'); - value /= 10; - } - /* reverse into correct order */ - for (int j = 0; j < size / 2; j++) { - char tmp = buf[j]; - char tmp2 = buf[size - j - 1]; - - buf[size - j - 1] = tmp; - buf[j] = tmp2; - } - - return size; -} \ No newline at end of file diff --git a/src/fluent-bit.c b/src/fluent-bit.c index e7bc144118e..93c35a54c6b 100644 --- a/src/fluent-bit.c +++ b/src/fluent-bit.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -72,6 +73,10 @@ extern void win32_started(void); flb_ctx_t *ctx; struct flb_config *config; volatile sig_atomic_t exit_signal = 0; +#define FLB_MAX_SIGNALS 32 +volatile sig_atomic_t caught_signals[FLB_MAX_SIGNALS] = {0}; +volatile atomic_uchar caught_signals_write = 0; +volatile atomic_uchar caught_signals_read = 0; volatile sig_atomic_t flb_bin_restarting = FLB_RELOAD_IDLE; #ifdef FLB_HAVE_LIBBACKTRACE @@ -544,7 +549,7 @@ static void flb_signal_handler_break_loop(int signal) exit_signal = signal; } -static void flb_signal_exit(int signal) +static void flb_print_caught_signal(int signal) { int len; char ts[32]; @@ -577,60 +582,10 @@ static void flb_signal_exit(int signal) }; } -static void flb_signal_handler_status_line(struct flb_cf *cf_opts) -{ - char s[] = "[engine] caught signal ("; - struct timespec ts; - char tsbuf[32]; - int tspos = 0; - - if (clock_gettime(CLOCK_REALTIME, &ts) == 0) { - uint year, month, day, hh, mm, ss; - - flb_civil_from_days(ts.tv_sec / 86400, &year, &month, &day); - hh = (uint) ((ts.tv_sec % 86400) / 3600); - mm = (uint) ((ts.tv_sec % 3600) / 60); - ss = (uint) (ts.tv_sec % 60); - - tsbuf[tspos++] = '['; - tspos += flb_write_uint(tsbuf + tspos, 4, year); - tsbuf[tspos++] = '/'; - tspos += flb_write_uint(tsbuf + tspos, 2, month); - tsbuf[tspos++] = '/'; - tspos += flb_write_uint(tsbuf + tspos, 2, day); - tsbuf[tspos++] = ' '; - tspos += flb_write_uint(tsbuf + tspos, 2, hh); - tsbuf[tspos++] = ':'; - tspos += flb_write_uint(tsbuf + tspos, 2, mm); - tsbuf[tspos++] = ':'; - tspos += flb_write_uint(tsbuf + tspos, 2, ss); - tsbuf[tspos++] = ']'; - tsbuf[tspos++] = ' '; - } - - /* write signal number */ - write(STDERR_FILENO, tsbuf, tspos - 1); - write(STDERR_FILENO, s, sizeof(s) - 1); -} - static void flb_signal_handler(int signal) { - struct flb_cf *cf_opts = flb_cf_context_get(); - flb_signal_handler_status_line(cf_opts); - - switch (signal) { - flb_print_signal(SIGINT); -#ifndef FLB_SYSTEM_WINDOWS - flb_print_signal(SIGQUIT); - flb_print_signal(SIGHUP); - flb_print_signal(SIGCONT); -#endif - flb_print_signal(SIGTERM); - flb_print_signal(SIGSEGV); - flb_print_signal(SIGFPE); - }; - - flb_signal_init(); + unsigned char cs_write = __atomic_fetch_add(&caught_signals_write, 1, __ATOMIC_SEQ_CST) % FLB_MAX_SIGNALS; + caught_signals[cs_write] = signal; switch(signal) { case SIGSEGV: @@ -640,21 +595,6 @@ static void flb_signal_handler(int signal) flb_stacktrace_print(&flb_st); #endif abort(); -#ifndef FLB_SYSTEM_WINDOWS - case SIGCONT: - flb_dump(ctx->config); - break; -#ifndef FLB_HAVE_STATIC_CONF - case SIGHUP: - if (flb_bin_restarting == FLB_RELOAD_IDLE) { - flb_bin_restarting = FLB_RELOAD_IN_PROGRESS; - } - else { - flb_utils_error(FLB_ERR_RELOADING_IN_PROGRESS); - } - break; -#endif -#endif } } @@ -677,9 +617,8 @@ static BOOL WINAPI flb_console_handler(DWORD evType) switch(evType) { case 0 /* CTRL_C_EVENT_0 */: - cf_opts = flb_cf_context_get(); - flb_signal_handler_status_line(cf_opts); - write (STDERR_FILENO, "SIGINT)\n", sizeof("SIGINT)\n")-1); + unsigned char cs_write = __atomic_fetch_add(&caught_signals_write, 1, __ATOMIC_SEQ_CST) % FLB_MAX_SIGNALS; + caught_signals[cs_write] = SIGINT; /* signal the main loop to execute reload even if CTRL_C event. * This is necessary because all signal handlers in win32 * are executed on their own thread. @@ -1474,10 +1413,37 @@ int flb_main(int argc, char **argv) sleep(1); flb_bin_restarting = FLB_RELOAD_IDLE; } + + unsigned char cs_write = __atomic_load_n(&caught_signals_write, __ATOMIC_SEQ_CST); + unsigned char cs_read = __atomic_load_n(&caught_signals_read, __ATOMIC_SEQ_CST); + while (cs_read != cs_write) { + int signal = caught_signals[cs_read % FLB_MAX_SIGNALS]; + flb_print_caught_signal(signal); + + switch (signal) { + #ifndef FLB_SYSTEM_WINDOWS + case SIGCONT: + flb_dump(ctx->config); + break; + #ifndef FLB_HAVE_STATIC_CONF + case SIGHUP: + if (flb_bin_restarting == FLB_RELOAD_IDLE) { + flb_bin_restarting = FLB_RELOAD_IN_PROGRESS; + } + else { + flb_utils_error(FLB_ERR_RELOADING_IN_PROGRESS); + } + break; + #endif + #endif + } + + cs_read = __atomic_fetch_add(&caught_signals_read, 1, __ATOMIC_SEQ_CST) + 1; + } } if (exit_signal) { - flb_signal_exit(exit_signal); + flb_print_caught_signal(exit_signal); } if (flb_bin_restarting != FLB_RELOAD_ABORTED) { ret = ctx->config->exit_status_code;