Merge branch 'jk/pkt-log-pack'
Enhance packet tracing machinery to allow capturing an incoming pack data to a file for debugging. * jk/pkt-log-pack: pkt-line: support tracing verbatim pack contents pkt-line: tighten sideband PACK check when tracing pkt-line: simplify starts_with checks in packet tracing
This commit is contained in:
commit
0b9ce18ede
@ -1009,9 +1009,20 @@ Unsetting the variable, or setting it to empty, "0" or
|
|||||||
Enables trace messages for all packets coming in or out of a
|
Enables trace messages for all packets coming in or out of a
|
||||||
given program. This can help with debugging object negotiation
|
given program. This can help with debugging object negotiation
|
||||||
or other protocol issues. Tracing is turned off at a packet
|
or other protocol issues. Tracing is turned off at a packet
|
||||||
starting with "PACK".
|
starting with "PACK" (but see 'GIT_TRACE_PACKFILE' below).
|
||||||
See 'GIT_TRACE' for available trace output options.
|
See 'GIT_TRACE' for available trace output options.
|
||||||
|
|
||||||
|
'GIT_TRACE_PACKFILE'::
|
||||||
|
Enables tracing of packfiles sent or received by a
|
||||||
|
given program. Unlike other trace output, this trace is
|
||||||
|
verbatim: no headers, and no quoting of binary data. You almost
|
||||||
|
certainly want to direct into a file (e.g.,
|
||||||
|
`GIT_TRACE_PACKFILE=/tmp/my.pack`) rather than displaying it on
|
||||||
|
the terminal or mixing it with other trace output.
|
||||||
|
+
|
||||||
|
Note that this is currently only implemented for the client side
|
||||||
|
of clones and fetches.
|
||||||
|
|
||||||
'GIT_TRACE_PERFORMANCE'::
|
'GIT_TRACE_PERFORMANCE'::
|
||||||
Enables performance related trace messages, e.g. total execution
|
Enables performance related trace messages, e.g. total execution
|
||||||
time of each Git command.
|
time of each Git command.
|
||||||
|
60
pkt-line.c
60
pkt-line.c
@ -4,16 +4,51 @@
|
|||||||
char packet_buffer[LARGE_PACKET_MAX];
|
char packet_buffer[LARGE_PACKET_MAX];
|
||||||
static const char *packet_trace_prefix = "git";
|
static const char *packet_trace_prefix = "git";
|
||||||
static struct trace_key trace_packet = TRACE_KEY_INIT(PACKET);
|
static struct trace_key trace_packet = TRACE_KEY_INIT(PACKET);
|
||||||
|
static struct trace_key trace_pack = TRACE_KEY_INIT(PACKFILE);
|
||||||
|
|
||||||
void packet_trace_identity(const char *prog)
|
void packet_trace_identity(const char *prog)
|
||||||
{
|
{
|
||||||
packet_trace_prefix = xstrdup(prog);
|
packet_trace_prefix = xstrdup(prog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int packet_trace_pack(const char *buf, unsigned int len, int sideband)
|
||||||
|
{
|
||||||
|
if (!sideband) {
|
||||||
|
trace_verbatim(&trace_pack, buf, len);
|
||||||
|
return 1;
|
||||||
|
} else if (len && *buf == '\1') {
|
||||||
|
trace_verbatim(&trace_pack, buf + 1, len - 1);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
/* it's another non-pack sideband */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void packet_trace(const char *buf, unsigned int len, int write)
|
static void packet_trace(const char *buf, unsigned int len, int write)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct strbuf out;
|
struct strbuf out;
|
||||||
|
static int in_pack, sideband;
|
||||||
|
|
||||||
|
if (!trace_want(&trace_packet) && !trace_want(&trace_pack))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (in_pack) {
|
||||||
|
if (packet_trace_pack(buf, len, sideband))
|
||||||
|
return;
|
||||||
|
} else if (starts_with(buf, "PACK") || starts_with(buf, "\1PACK")) {
|
||||||
|
in_pack = 1;
|
||||||
|
sideband = *buf == '\1';
|
||||||
|
packet_trace_pack(buf, len, sideband);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make a note in the human-readable trace that the pack data
|
||||||
|
* started.
|
||||||
|
*/
|
||||||
|
buf = "PACK ...";
|
||||||
|
len = strlen(buf);
|
||||||
|
}
|
||||||
|
|
||||||
if (!trace_want(&trace_packet))
|
if (!trace_want(&trace_packet))
|
||||||
return;
|
return;
|
||||||
@ -24,22 +59,15 @@ static void packet_trace(const char *buf, unsigned int len, int write)
|
|||||||
strbuf_addf(&out, "packet: %12s%c ",
|
strbuf_addf(&out, "packet: %12s%c ",
|
||||||
packet_trace_prefix, write ? '>' : '<');
|
packet_trace_prefix, write ? '>' : '<');
|
||||||
|
|
||||||
if ((len >= 4 && starts_with(buf, "PACK")) ||
|
/* XXX we should really handle printable utf8 */
|
||||||
(len >= 5 && starts_with(buf+1, "PACK"))) {
|
for (i = 0; i < len; i++) {
|
||||||
strbuf_addstr(&out, "PACK ...");
|
/* suppress newlines */
|
||||||
trace_disable(&trace_packet);
|
if (buf[i] == '\n')
|
||||||
}
|
continue;
|
||||||
else {
|
if (buf[i] >= 0x20 && buf[i] <= 0x7e)
|
||||||
/* XXX we should really handle printable utf8 */
|
strbuf_addch(&out, buf[i]);
|
||||||
for (i = 0; i < len; i++) {
|
else
|
||||||
/* suppress newlines */
|
strbuf_addf(&out, "\\%o", buf[i]);
|
||||||
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');
|
strbuf_addch(&out, '\n');
|
||||||
|
@ -496,4 +496,11 @@ test_expect_success 'shallow clone locally' '
|
|||||||
( cd ddsstt && git fsck )
|
( cd ddsstt && git fsck )
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'GIT_TRACE_PACKFILE produces a usable pack' '
|
||||||
|
rm -rf dst.git &&
|
||||||
|
GIT_TRACE_PACKFILE=$PWD/tmp.pack git clone --no-local --bare src dst.git &&
|
||||||
|
git init --bare replay.git &&
|
||||||
|
git -C replay.git index-pack -v --stdin <tmp.pack
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
7
trace.c
7
trace.c
@ -120,6 +120,13 @@ static int prepare_trace_line(const char *file, int line,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void trace_verbatim(struct trace_key *key, const void *buf, unsigned len)
|
||||||
|
{
|
||||||
|
if (!trace_want(key))
|
||||||
|
return;
|
||||||
|
write_or_whine_pipe(get_trace_fd(key), buf, len, err_msg);
|
||||||
|
}
|
||||||
|
|
||||||
static void print_trace_line(struct trace_key *key, struct strbuf *buf)
|
static void print_trace_line(struct trace_key *key, struct strbuf *buf)
|
||||||
{
|
{
|
||||||
strbuf_complete_line(buf);
|
strbuf_complete_line(buf);
|
||||||
|
1
trace.h
1
trace.h
@ -18,6 +18,7 @@ extern int trace_want(struct trace_key *key);
|
|||||||
extern void trace_disable(struct trace_key *key);
|
extern void trace_disable(struct trace_key *key);
|
||||||
extern uint64_t getnanotime(void);
|
extern uint64_t getnanotime(void);
|
||||||
extern void trace_command_performance(const char **argv);
|
extern void trace_command_performance(const char **argv);
|
||||||
|
extern void trace_verbatim(struct trace_key *key, const void *buf, unsigned len);
|
||||||
|
|
||||||
#ifndef HAVE_VARIADIC_MACROS
|
#ifndef HAVE_VARIADIC_MACROS
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user