Skip to content

Commit

Permalink
BUG/MEDIUM: stream: don't use localtime in dumps from a signal handler
Browse files Browse the repository at this point in the history
In issue haproxy#2861, Jarosaw Rzeszótko reported another issue with
"show threads", this time in relation with the conversion of a stream's
accept date to local time. Indeed, if the libc was interrupted in this
same function, it could have been interrupted with a lock held, then
it's no longer possible to dump the date, and we face a deadlock.
This is easy to reproduce with logging enabled.

Let's detect we come from a signal handler and do not try to resolve
the time to localtime in this case.
  • Loading branch information
wtarreau committed Feb 24, 2025
1 parent fb7874c commit 2e0bac9
Showing 1 changed file with 19 additions and 8 deletions.
27 changes: 19 additions & 8 deletions src/stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -3272,14 +3272,25 @@ static void __strm_dump_to_buffer(struct buffer *buf, const struct show_sess_ctx

pfx = pfx ? pfx : "";

get_localtime(strm->logs.accept_date.tv_sec, &tm);
chunk_appendf(buf,
"%p: [%02d/%s/%04d:%02d:%02d:%02d.%06d] id=%u proto=%s",
strm,
tm.tm_mday, monthname[tm.tm_mon], tm.tm_year+1900,
tm.tm_hour, tm.tm_min, tm.tm_sec, (int)(strm->logs.accept_date.tv_usec),
strm->uniq_id,
strm_li(strm) ? strm_li(strm)->rx.proto->name : "?");
if (th_ctx->flags & TH_FL_IN_ANY_HANDLER) {
/* avoid calling localtime_r() to avoid a risk of deadlock if we
* interrupted libc for example, cf
* https://github.com/haproxy/haproxy/issues/2861#issuecomment-2677761037
*/
chunk_appendf(buf, "%p: [%lu.%06lu]", strm,
(ulong)strm->logs.accept_date.tv_sec,
(ulong)strm->logs.accept_date.tv_usec);
} else {
get_localtime(strm->logs.accept_date.tv_sec, &tm);
chunk_appendf(buf,
"%p: [%02d/%s/%04d:%02d:%02d:%02d.%06lu]",
strm,
tm.tm_mday, monthname[tm.tm_mon], tm.tm_year+1900,
tm.tm_hour, tm.tm_min, tm.tm_sec, (ulong)strm->logs.accept_date.tv_usec);
}

chunk_appendf(buf, " id=%u proto=%s",
strm->uniq_id, strm_li(strm) ? strm_li(strm)->rx.proto->name : "?");

conn = objt_conn(strm_orig(strm));

Expand Down

0 comments on commit 2e0bac9

Please sign in to comment.