@matheusbsbs / matheus-bagliano / commits / bbc30f9963
Fork 0

add packet tracing debug code

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>

Jeff King committed Feb 24, 2011 at 09:30 UTC bbc30f996380eacd71ca061675d5d0c5f21c45d2
8 files changed +65 -1
builtin/clone.c
+1
@@ -383,6 +383,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
383
384 junk_pid = getpid();
385
386 + packet_trace_identity("clone");
387 argc = parse_options(argc, argv, prefix, builtin_clone_options,
388 builtin_clone_usage, 0);
389
builtin/fetch-pack.c
+2
@@ -804,6 +804,8 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
804 char **pack_lockfile_ptr = NULL;
805 struct child_process *conn;
806
807 + packet_trace_identity("fetch-pack");
808 +
809 nr_heads = 0;
810 heads = NULL;
811 for (i = 1; i < argc; i++) {
builtin/fetch.c
+2
@@ -906,6 +906,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
906 struct remote *remote;
907 int result = 0;
908
909 + packet_trace_identity("fetch");
910 +
911 /* Record the command line for the reflog */
912 strbuf_addstr(&default_rla, "fetch");
913 for (i = 1; i < argc; i++)
builtin/push.c
+1
@@ -228,6 +228,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
228 OPT_END()
229 };
230
231 + packet_trace_identity("push");
232 git_config(git_default_config, NULL);
233 argc = parse_options(argc, argv, prefix, options, push_usage, 0);
234
builtin/receive-pack.c
+2
@@ -778,6 +778,8 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
778 char *dir = NULL;
779 struct command *commands;
780
781 + packet_trace_identity("receive-pack");
782 +
783 argv++;
784 for (i = 1; i < argc; i++) {
785 const char *arg = *argv++;
cache.h
+2
@@ -1074,6 +1074,8 @@ extern void trace_repo_setup(const char *prefix);
1074 extern int trace_want(const char *key);
1075 extern void trace_strbuf(const char *key, const struct strbuf *buf);
1076
1077 +void packet_trace_identity(const char *prog);
1078 +
1079 /* convert.c */
1080 /* returns 1 if *dst was used */
1081 extern int convert_to_git(const char *path, const char *src, size_t len,
pkt-line.c
+54 -1
@@ -1,6 +1,51 @@
1 #include "cache.h"
2 #include "pkt-line.h"
3
4 +const char *packet_trace_prefix = "git";
5 +static const char trace_key[] = "GIT_TRACE_PACKET";
6 +
7 +void packet_trace_identity(const char *prog)
8 +{
9 + packet_trace_prefix = xstrdup(prog);
10 +}
11 +
12 +static void packet_trace(const char *buf, unsigned int len, int write)
13 +{
14 + int i;
15 + struct strbuf out;
16 +
17 + if (!trace_want(trace_key))
18 + return;
19 +
20 + /* +32 is just a guess for header + quoting */
21 + strbuf_init(&out, len+32);
22 +
23 + strbuf_addf(&out, "packet: %12s%c ",
24 + packet_trace_prefix, write ? '>' : '<');
25 +
26 + if ((len >= 4 && !prefixcmp(buf, "PACK")) ||
27 + (len >= 5 && !prefixcmp(buf+1, "PACK"))) {
28 + strbuf_addstr(&out, "PACK ...");
29 + unsetenv(trace_key);
30 + }
31 + else {
32 + /* XXX we should really handle printable utf8 */
33 + for (i = 0; i < len; i++) {
34 + /* suppress newlines */
35 + if (buf[i] == '\n')
36 + continue;
37 + if (buf[i] >= 0x20 && buf[i] <= 0x7e)
38 + strbuf_addch(&out, buf[i]);
39 + else
40 + strbuf_addf(&out, "\\%o", buf[i]);
41 + }
42 + }
43 +
44 + strbuf_addch(&out, '\n');
45 + trace_strbuf(trace_key, &out);
46 + strbuf_release(&out);
47 +}
48 +
49 /*
50 * Write a packetized stream, where each line is preceded by
51 * its length (including the header) as a 4-byte hex number.
@@ -39,11 +84,13 @@ ssize_t safe_write(int fd, const void *buf, ssize_t n)
84 */
85 void packet_flush(int fd)
86 {
87 + packet_trace("0000", 4, 1);
88 safe_write(fd, "0000", 4);
89 }
90
91 void packet_buf_flush(struct strbuf *buf)
92 {
93 + packet_trace("0000", 4, 1);
94 strbuf_add(buf, "0000", 4);
95 }
96
@@ -62,6 +109,7 @@ static unsigned format_packet(const char *fmt, va_list args)
109 buffer[1] = hex(n >> 8);
110 buffer[2] = hex(n >> 4);
111 buffer[3] = hex(n);
112 + packet_trace(buffer+4, n-4, 1);
113 return n;
114 }
115
@@ -130,13 +178,16 @@ int packet_read_line(int fd, char *buffer, unsigned size)
178 len = packet_length(linelen);
179 if (len < 0)
180 die("protocol error: bad line length character: %.4s", linelen);
133 - if (!len)
181 + if (!len) {
182 + packet_trace("0000", 4, 0);
183 return 0;
184 + }
185 len -= 4;
186 if (len >= size)
187 die("protocol error: bad line length %d", len);
188 safe_read(fd, buffer, len);
189 buffer[len] = 0;
190 + packet_trace(buffer, len, 0);
191 return len;
192 }
193
@@ -153,6 +204,7 @@ int packet_get_line(struct strbuf *out,
204 if (!len) {
205 *src_buf += 4;
206 *src_len -= 4;
207 + packet_trace("0000", 4, 0);
208 return 0;
209 }
210 if (*src_len < len)
@@ -165,5 +217,6 @@ int packet_get_line(struct strbuf *out,
217 strbuf_add(out, *src_buf, len);
218 *src_buf += len;
219 *src_len -= len;
220 + packet_trace(out->buf, out->len, 0);
221 return len;
222 }
upload-pack.c
+1
@@ -682,6 +682,7 @@ int main(int argc, char **argv)
682 int i;
683 int strict = 0;
684
685 + packet_trace_identity("upload-pack");
686 git_extract_argv0_path(argv[0]);
687 read_replace_refs = 0;
688