Browse Source

trace: add infrastructure to augment trace output with additional info

To be able to add a common prefix or suffix to all trace output (e.g.
a timestamp or file:line of the caller), factor out common setup and
cleanup tasks of the trace* functions.

When adding a common prefix, it makes sense that the output of each trace
call starts on a new line. Add '\n' in case the caller forgot.

Note that this explicitly limits trace output to line-by-line, it is no
longer possible to trace-print just part of a line. Until now, this was
just an implicit assumption (trace-printing part of a line worked, but
messed up the trace file if multiple threads or processes were involved).

Thread-safety / inter-process-safety is also the reason why we need to do
the prefixing and suffixing in memory rather than issuing multiple write()
calls. Write_or_whine_pipe() / xwrite() is atomic unless the size exceeds
MAX_IO_SIZE (8MB, see wrapper.c). In case of trace_strbuf, this costs an
additional string copy (which should be irrelevant for performance in light
of actual file IO).

While we're at it, rename trace_strbuf's 'buf' argument, which suggests
that the function is modifying the buffer. Trace_strbuf() currently is the
only trace API that can print arbitrary binary data (without barfing on
'%' or stopping at '\0'), so 'data' seems more appropriate.

Signed-off-by: Karsten Blees <blees@dcon.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Karsten Blees 11 years ago committed by Junio C Hamano
parent
commit
c69dfd24db
  1. 47
      trace.c
  2. 2
      trace.h

47
trace.c

@ -85,17 +85,37 @@ void trace_disable(struct trace_key *key) @@ -85,17 +85,37 @@ void trace_disable(struct trace_key *key)
static const char err_msg[] = "Could not trace into fd given by "
"GIT_TRACE environment variable";

static int prepare_trace_line(struct trace_key *key, struct strbuf *buf)
{
if (!trace_want(key))
return 0;

set_try_to_free_routine(NULL); /* is never reset */

/* add line prefix here */

return 1;
}

static void print_trace_line(struct trace_key *key, struct strbuf *buf)
{
/* append newline if missing */
if (buf->len && buf->buf[buf->len - 1] != '\n')
strbuf_addch(buf, '\n');

write_or_whine_pipe(get_trace_fd(key), buf->buf, buf->len, err_msg);
strbuf_release(buf);
}

static void trace_vprintf(struct trace_key *key, const char *format, va_list ap)
{
struct strbuf buf = STRBUF_INIT;

if (!trace_want(key))
if (!prepare_trace_line(key, &buf))
return;

set_try_to_free_routine(NULL); /* is never reset */
strbuf_vaddf(&buf, format, ap);
trace_strbuf(key, &buf);
strbuf_release(&buf);
print_trace_line(key, &buf);
}

void trace_printf_key(struct trace_key *key, const char *format, ...)
@ -114,32 +134,31 @@ void trace_printf(const char *format, ...) @@ -114,32 +134,31 @@ void trace_printf(const char *format, ...)
va_end(ap);
}

void trace_strbuf(struct trace_key *key, const struct strbuf *buf)
void trace_strbuf(struct trace_key *key, const struct strbuf *data)
{
int fd = get_trace_fd(key);
if (!fd)
struct strbuf buf = STRBUF_INIT;

if (!prepare_trace_line(key, &buf))
return;

write_or_whine_pipe(fd, buf->buf, buf->len, err_msg);
strbuf_addbuf(&buf, data);
print_trace_line(key, &buf);
}

void trace_argv_printf(const char **argv, const char *format, ...)
{
struct strbuf buf = STRBUF_INIT;
va_list ap;
int fd = get_trace_fd(NULL);
if (!fd)

if (!prepare_trace_line(NULL, &buf))
return;

set_try_to_free_routine(NULL); /* is never reset */
va_start(ap, format);
strbuf_vaddf(&buf, format, ap);
va_end(ap);

sq_quote_argv(&buf, argv, 0);
strbuf_addch(&buf, '\n');
write_or_whine_pipe(fd, buf.buf, buf.len, err_msg);
strbuf_release(&buf);
print_trace_line(NULL, &buf);
}

static const char *quote_crnl(const char *path)

2
trace.h

@ -22,6 +22,6 @@ extern int trace_want(struct trace_key *key); @@ -22,6 +22,6 @@ extern int trace_want(struct trace_key *key);
extern void trace_disable(struct trace_key *key);
__attribute__((format (printf, 2, 3)))
extern void trace_printf_key(struct trace_key *key, const char *format, ...);
extern void trace_strbuf(struct trace_key *key, const struct strbuf *buf);
extern void trace_strbuf(struct trace_key *key, const struct strbuf *data);

#endif /* TRACE_H */

Loading…
Cancel
Save