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>
This commit is contained in:
parent
67dc598ec4
commit
c69dfd24db
47
trace.c
47
trace.c
@ -85,17 +85,37 @@ void trace_disable(struct trace_key *key)
|
|||||||
static const char err_msg[] = "Could not trace into fd given by "
|
static const char err_msg[] = "Could not trace into fd given by "
|
||||||
"GIT_TRACE environment variable";
|
"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)
|
static void trace_vprintf(struct trace_key *key, const char *format, va_list ap)
|
||||||
{
|
{
|
||||||
struct strbuf buf = STRBUF_INIT;
|
struct strbuf buf = STRBUF_INIT;
|
||||||
|
|
||||||
if (!trace_want(key))
|
if (!prepare_trace_line(key, &buf))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
set_try_to_free_routine(NULL); /* is never reset */
|
|
||||||
strbuf_vaddf(&buf, format, ap);
|
strbuf_vaddf(&buf, format, ap);
|
||||||
trace_strbuf(key, &buf);
|
print_trace_line(key, &buf);
|
||||||
strbuf_release(&buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void trace_printf_key(struct trace_key *key, const char *format, ...)
|
void trace_printf_key(struct trace_key *key, const char *format, ...)
|
||||||
@ -114,32 +134,31 @@ void trace_printf(const char *format, ...)
|
|||||||
va_end(ap);
|
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);
|
struct strbuf buf = STRBUF_INIT;
|
||||||
if (!fd)
|
|
||||||
|
if (!prepare_trace_line(key, &buf))
|
||||||
return;
|
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, ...)
|
void trace_argv_printf(const char **argv, const char *format, ...)
|
||||||
{
|
{
|
||||||
struct strbuf buf = STRBUF_INIT;
|
struct strbuf buf = STRBUF_INIT;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
int fd = get_trace_fd(NULL);
|
|
||||||
if (!fd)
|
if (!prepare_trace_line(NULL, &buf))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
set_try_to_free_routine(NULL); /* is never reset */
|
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
strbuf_vaddf(&buf, format, ap);
|
strbuf_vaddf(&buf, format, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
sq_quote_argv(&buf, argv, 0);
|
sq_quote_argv(&buf, argv, 0);
|
||||||
strbuf_addch(&buf, '\n');
|
print_trace_line(NULL, &buf);
|
||||||
write_or_whine_pipe(fd, buf.buf, buf.len, err_msg);
|
|
||||||
strbuf_release(&buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *quote_crnl(const char *path)
|
static const char *quote_crnl(const char *path)
|
||||||
|
2
trace.h
2
trace.h
@ -22,6 +22,6 @@ extern int trace_want(struct trace_key *key);
|
|||||||
extern void trace_disable(struct trace_key *key);
|
extern void trace_disable(struct trace_key *key);
|
||||||
__attribute__((format (printf, 2, 3)))
|
__attribute__((format (printf, 2, 3)))
|
||||||
extern void trace_printf_key(struct trace_key *key, const char *format, ...);
|
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 */
|
#endif /* TRACE_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user