Skip to content

Commit 538ac74

Browse files
steadmongitster
authored andcommitted
trace2: disable tr2_dst before warning on write errors
If writing a trace2 message fails, we optionally warn the user of this fact. However, in 0ee10fd (usage: add trace2 entry upon warning(), 2020-11-23), we added a trace entry to the warning() function. This means that we can enter an infinite loop of failing trace2 writes and warnings. Fix this by disabling the failing trace2 destination before issuing the warning. Additionally, trace2 sets a default SIGPIPE handler (tr2main_signal_handler) when it is initialized. This handler generates its own trace2 messages when a signal is received. If a trace2 write fails due to a broken pipe, this handler will run and then cause another failed write. Fix this by temporarily ignoring SIGPIPE while writing trace2 messages. This is safe because the write will still fail, and we will disable the failing destination. Signed-off-by: Josh Steadmon <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 5fbd2fc commit 538ac74

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

trace2/tr2_dst.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "cache.h"
2+
#include "sigchain.h"
23
#include "trace2/tr2_dst.h"
34
#include "trace2/tr2_sid.h"
45
#include "trace2/tr2_sysenv.h"
@@ -360,6 +361,7 @@ int tr2_dst_trace_want(struct tr2_dst *dst)
360361
void tr2_dst_write_line(struct tr2_dst *dst, struct strbuf *buf_line)
361362
{
362363
int fd = tr2_dst_get_trace_fd(dst);
364+
ssize_t bytes;
363365

364366
strbuf_complete_line(buf_line); /* ensure final NL on buffer */
365367

@@ -378,12 +380,15 @@ void tr2_dst_write_line(struct tr2_dst *dst, struct strbuf *buf_line)
378380
*
379381
* If we get an IO error, just close the trace dst.
380382
*/
381-
if (write(fd, buf_line->buf, buf_line->len) >= 0)
383+
sigchain_push(SIGPIPE, SIG_IGN);
384+
bytes = write(fd, buf_line->buf, buf_line->len);
385+
sigchain_pop(SIGPIPE);
386+
if (bytes >= 0)
382387
return;
383388

389+
tr2_dst_trace_disable(dst);
384390
if (tr2_dst_want_warning())
385391
warning("unable to write trace to '%s': %s",
386392
tr2_sysenv_display_name(dst->sysenv_var),
387393
strerror(errno));
388-
tr2_dst_trace_disable(dst);
389394
}

0 commit comments

Comments
 (0)