From d4a4de9055783b1c2dcd9e5e2cf130e023e2906f Mon Sep 17 00:00:00 2001 From: Melissa Kilby Date: Wed, 4 Oct 2023 04:24:34 +0000 Subject: [PATCH] fix(userspace/falco): timer_delete() workaround due to bug in older GLIBC Workaround for older GLIBC versions (< 2.35), where calling timer_delete() with an invalid timer ID not returned by timer_create() causes a segfault because of a bug in GLIBC (https://sourceware.org/bugzilla/show_bug.cgi?id=28257). Signed-off-by: Melissa Kilby --- userspace/falco/stats_writer.cpp | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/userspace/falco/stats_writer.cpp b/userspace/falco/stats_writer.cpp index b7194b91..8153bc85 100644 --- a/userspace/falco/stats_writer.cpp +++ b/userspace/falco/stats_writer.cpp @@ -34,6 +34,10 @@ limitations under the License. // check that this value changed since their last observation. static std::atomic s_timer((stats_writer::ticker_t) 0); static timer_t s_timerid; +// note: Workaround for older GLIBC versions (< 2.35), where calling timer_delete() +// with an invalid timer ID not returned by timer_create() causes a segfault because of +// a bug in GLIBC (https://sourceware.org/bugzilla/show_bug.cgi?id=28257). +bool s_timerid_exists = false; static void timer_handler(int signum) { @@ -60,18 +64,31 @@ bool stats_writer::init_ticker(uint32_t interval_msec, std::string &err) sev.sigev_value.sival_ptr = &s_timerid; #ifndef __EMSCRIPTEN__ // delete any previously set timer - timer_delete(s_timerid); - if (timer_create(CLOCK_MONOTONIC, &sev, &s_timerid) == -1) { + if (s_timerid_exists) + { + if (timer_delete(s_timerid) == -1) + { + err = std::string("Could not delete previous timer: ") + strerror(errno); + return false; + } + s_timerid_exists = false; + } + + if (timer_create(CLOCK_MONOTONIC, &sev, &s_timerid) == -1) + { err = std::string("Could not create periodic timer: ") + strerror(errno); return false; } + s_timerid_exists = true; + #endif timer.it_value.tv_sec = interval_msec / 1000; timer.it_value.tv_nsec = (interval_msec % 1000) * 1000 * 1000; timer.it_interval = timer.it_value; #ifndef __EMSCRIPTEN__ - if (timer_settime(s_timerid, 0, &timer, NULL) == -1) { + if (timer_settime(s_timerid, 0, &timer, NULL) == -1) + { err = std::string("Could not set up periodic timer: ") + strerror(errno); return false; } @@ -134,7 +151,10 @@ stats_writer::~stats_writer() } // delete timerID and reset timer #ifndef __EMSCRIPTEN__ - timer_delete(s_timerid); + if (s_timerid_exists) + { + timer_delete(s_timerid); + } #endif } }