зеркало из https://github.com/microsoft/git.git
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:
Родитель
67dc598ec4
Коммит
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 "
|
||||
"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, ...)
|
|||
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
2
trace.h
|
@ -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 */
|
||||
|
|
Загрузка…
Ссылка в новой задаче