Skip to content

Commit

Permalink
add packet tracing debug code
Browse files Browse the repository at this point in the history
This shows a trace of all packets coming in or out of a given
program. This can help with debugging object negotiation or
other protocol issues.

To keep the code changes simple, we operate at the lowest
level, meaning we don't necessarily understand what's in the
packets. The one exception is a packet starting with "PACK",
which causes us to skip that packet and turn off tracing
(since the gigantic pack data will not be interesting to
read, at least not in the trace format).

We show both written and read packets. In the local case,
this may mean you will see packets twice (written by the
sender and read by the receiver). However, for cases where
the other end is remote, this allows you to see the full
conversation.

Packet tracing can be enabled with GIT_TRACE_PACKET=<foo>,
where <foo> takes the same arguments as GIT_TRACE.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Jeff King authored and Junio C Hamano committed Mar 8, 2011
1 parent 94b3b37 commit bbc30f9
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 1 deletion.
1 change: 1 addition & 0 deletions builtin/clone.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)

junk_pid = getpid();

packet_trace_identity("clone");
argc = parse_options(argc, argv, prefix, builtin_clone_options,
builtin_clone_usage, 0);

Expand Down
2 changes: 2 additions & 0 deletions builtin/fetch-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,8 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
char **pack_lockfile_ptr = NULL;
struct child_process *conn;

packet_trace_identity("fetch-pack");

nr_heads = 0;
heads = NULL;
for (i = 1; i < argc; i++) {
Expand Down
2 changes: 2 additions & 0 deletions builtin/fetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
struct remote *remote;
int result = 0;

packet_trace_identity("fetch");

/* Record the command line for the reflog */
strbuf_addstr(&default_rla, "fetch");
for (i = 1; i < argc; i++)
Expand Down
1 change: 1 addition & 0 deletions builtin/push.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
OPT_END()
};

packet_trace_identity("push");
git_config(git_default_config, NULL);
argc = parse_options(argc, argv, prefix, options, push_usage, 0);

Expand Down
2 changes: 2 additions & 0 deletions builtin/receive-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,8 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
char *dir = NULL;
struct command *commands;

packet_trace_identity("receive-pack");

argv++;
for (i = 1; i < argc; i++) {
const char *arg = *argv++;
Expand Down
2 changes: 2 additions & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -1074,6 +1074,8 @@ extern void trace_repo_setup(const char *prefix);
extern int trace_want(const char *key);
extern void trace_strbuf(const char *key, const struct strbuf *buf);

void packet_trace_identity(const char *prog);

/* convert.c */
/* returns 1 if *dst was used */
extern int convert_to_git(const char *path, const char *src, size_t len,
Expand Down
55 changes: 54 additions & 1 deletion pkt-line.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,51 @@
#include "cache.h"
#include "pkt-line.h"

const char *packet_trace_prefix = "git";
static const char trace_key[] = "GIT_TRACE_PACKET";

void packet_trace_identity(const char *prog)
{
packet_trace_prefix = xstrdup(prog);
}

static void packet_trace(const char *buf, unsigned int len, int write)
{
int i;
struct strbuf out;

if (!trace_want(trace_key))
return;

/* +32 is just a guess for header + quoting */
strbuf_init(&out, len+32);

strbuf_addf(&out, "packet: %12s%c ",
packet_trace_prefix, write ? '>' : '<');

if ((len >= 4 && !prefixcmp(buf, "PACK")) ||
(len >= 5 && !prefixcmp(buf+1, "PACK"))) {
strbuf_addstr(&out, "PACK ...");
unsetenv(trace_key);
}
else {
/* XXX we should really handle printable utf8 */
for (i = 0; i < len; i++) {
/* suppress newlines */
if (buf[i] == '\n')
continue;
if (buf[i] >= 0x20 && buf[i] <= 0x7e)
strbuf_addch(&out, buf[i]);
else
strbuf_addf(&out, "\\%o", buf[i]);
}
}

strbuf_addch(&out, '\n');
trace_strbuf(trace_key, &out);
strbuf_release(&out);
}

/*
* Write a packetized stream, where each line is preceded by
* its length (including the header) as a 4-byte hex number.
Expand Down Expand Up @@ -39,11 +84,13 @@ ssize_t safe_write(int fd, const void *buf, ssize_t n)
*/
void packet_flush(int fd)
{
packet_trace("0000", 4, 1);
safe_write(fd, "0000", 4);
}

void packet_buf_flush(struct strbuf *buf)
{
packet_trace("0000", 4, 1);
strbuf_add(buf, "0000", 4);
}

Expand All @@ -62,6 +109,7 @@ static unsigned format_packet(const char *fmt, va_list args)
buffer[1] = hex(n >> 8);
buffer[2] = hex(n >> 4);
buffer[3] = hex(n);
packet_trace(buffer+4, n-4, 1);
return n;
}

Expand Down Expand Up @@ -130,13 +178,16 @@ int packet_read_line(int fd, char *buffer, unsigned size)
len = packet_length(linelen);
if (len < 0)
die("protocol error: bad line length character: %.4s", linelen);
if (!len)
if (!len) {
packet_trace("0000", 4, 0);
return 0;
}
len -= 4;
if (len >= size)
die("protocol error: bad line length %d", len);
safe_read(fd, buffer, len);
buffer[len] = 0;
packet_trace(buffer, len, 0);
return len;
}

Expand All @@ -153,6 +204,7 @@ int packet_get_line(struct strbuf *out,
if (!len) {
*src_buf += 4;
*src_len -= 4;
packet_trace("0000", 4, 0);
return 0;
}
if (*src_len < len)
Expand All @@ -165,5 +217,6 @@ int packet_get_line(struct strbuf *out,
strbuf_add(out, *src_buf, len);
*src_buf += len;
*src_len -= len;
packet_trace(out->buf, out->len, 0);
return len;
}
1 change: 1 addition & 0 deletions upload-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,7 @@ int main(int argc, char **argv)
int i;
int strict = 0;

packet_trace_identity("upload-pack");
git_extract_argv0_path(argv[0]);
read_replace_refs = 0;

Expand Down

0 comments on commit bbc30f9

Please sign in to comment.