Skip to content

Commit d80b11e

Browse files
jeffhostetlerdscho
authored andcommitted
Merge pull request #28 from jeffhostetler/gvfs-trace2-v1
(Experimental) Trace2 base plus GVFS extensions
2 parents 5881100 + e943105 commit d80b11e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+3620
-24
lines changed

Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,7 @@ TEST_BUILTINS_OBJS += test-submodule-config.o
741741
TEST_BUILTINS_OBJS += test-subprocess.o
742742
TEST_BUILTINS_OBJS += test-urlmatch-normalization.o
743743
TEST_BUILTINS_OBJS += test-wildmatch.o
744+
TEST_BUILTINS_OBJS += test-windows-named-pipe.o
744745
TEST_BUILTINS_OBJS += test-write-cache.o
745746

746747
TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
@@ -980,6 +981,15 @@ LIB_OBJS += tag.o
980981
LIB_OBJS += tempfile.o
981982
LIB_OBJS += tmp-objdir.o
982983
LIB_OBJS += trace.o
984+
LIB_OBJS += trace2.o
985+
LIB_OBJS += trace2/tr2_cfg.o
986+
LIB_OBJS += trace2/tr2_dst.o
987+
LIB_OBJS += trace2/tr2_sid.o
988+
LIB_OBJS += trace2/tr2_tbuf.o
989+
LIB_OBJS += trace2/tr2_tgt_event.o
990+
LIB_OBJS += trace2/tr2_tgt_normal.o
991+
LIB_OBJS += trace2/tr2_tgt_perf.o
992+
LIB_OBJS += trace2/tr2_tls.o
983993
LIB_OBJS += trailer.o
984994
LIB_OBJS += transport.o
985995
LIB_OBJS += transport-helper.o

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "gettext.h"
1010
#include "convert.h"
1111
#include "trace.h"
12+
#include "trace2.h"
1213
#include "string-list.h"
1314
#include "pack-revindex.h"
1415
#include "hash.h"

common-main.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ int main(int argc, const char **argv)
3131
* onto stdin/stdout/stderr in the child processes we spawn.
3232
*/
3333
sanitize_stdfds();
34+
restore_sigpipe_to_default();
35+
36+
trace2_initialize(argv);
3437

3538
git_resolve_executable_dir(argv[0]);
3639

@@ -40,7 +43,5 @@ int main(int argc, const char **argv)
4043

4144
attr_start();
4245

43-
restore_sigpipe_to_default();
44-
4546
return cmd_main(argc, argv);
4647
}

compat/mingw.c

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,19 @@ int mingw_mkdir(const char *path, int mode)
557557
return ret;
558558
}
559559

560+
/*
561+
* Calling CreateFile() using FILE_APPEND_DATA and without FILE_WRITE_DATA
562+
* is documented in [1] as opening a writable file handle in append mode.
563+
* (It is believed that) this is atomic since it is maintained by the
564+
* kernel unlike the O_APPEND flag which is racily maintained by the CRT.
565+
*
566+
* [1] https://docs.microsoft.com/en-us/windows/desktop/fileio/file-access-rights-constants
567+
*
568+
* This trick does not appear to work for named pipes. Instead it creates
569+
* a named pipe client handle that cannot be written to. Callers should
570+
* just use the regular _wopen() for them. (And since client handle gets
571+
* bound to a unique server handle, it isn't really an issue.)
572+
*/
560573
static int mingw_open_append(wchar_t const *wfilename, int oflags, ...)
561574
{
562575
HANDLE handle;
@@ -576,17 +589,36 @@ static int mingw_open_append(wchar_t const *wfilename, int oflags, ...)
576589
NULL, create, FILE_ATTRIBUTE_NORMAL, NULL);
577590
if (handle == INVALID_HANDLE_VALUE)
578591
return errno = err_win_to_posix(GetLastError()), -1;
592+
579593
/*
580594
* No O_APPEND here, because the CRT uses it only to reset the
581-
* file pointer to EOF on write(); but that is not necessary
582-
* for a file created with FILE_APPEND_DATA.
595+
* file pointer to EOF before each write(); but that is not
596+
* necessary (and may lead to races) for a file created with
597+
* FILE_APPEND_DATA.
583598
*/
584599
fd = _open_osfhandle((intptr_t)handle, O_BINARY);
585600
if (fd < 0)
586601
CloseHandle(handle);
587602
return fd;
588603
}
589604

605+
#define IS_SBS(ch) (((ch) == '/') || ((ch) == '\\'))
606+
/*
607+
* Does the pathname map to the local named pipe filesystem?
608+
* That is, does it have a "//./pipe/" prefix?
609+
*/
610+
static int mingw_is_local_named_pipe_path(const char *filename)
611+
{
612+
return (IS_SBS(filename[0]) &&
613+
IS_SBS(filename[1]) &&
614+
filename[2] == '.' &&
615+
IS_SBS(filename[3]) &&
616+
!strncasecmp(filename+4, "pipe", 4) &&
617+
IS_SBS(filename[8]) &&
618+
filename[9]);
619+
}
620+
#undef IS_SBS
621+
590622
int mingw_open (const char *filename, int oflags, ...)
591623
{
592624
typedef int (*open_fn_t)(wchar_t const *wfilename, int oflags, ...);
@@ -603,7 +635,7 @@ int mingw_open (const char *filename, int oflags, ...)
603635
if (filename && !strcmp(filename, "/dev/null"))
604636
filename = "nul";
605637

606-
if (oflags & O_APPEND)
638+
if ((oflags & O_APPEND) && !mingw_is_local_named_pipe_path(filename))
607639
open_fn = mingw_open_append;
608640
else
609641
open_fn = _wopen;
@@ -1939,6 +1971,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
19391971
int status;
19401972
if (waitpid(pid, &status, 0) < 0)
19411973
status = 255;
1974+
trace2_exec_result(status);
19421975
exit(status);
19431976
}
19441977
pid = 1; /* indicate that we tried but failed */
@@ -1959,6 +1992,7 @@ int mingw_execv(const char *cmd, char *const *argv)
19591992
return -1;
19601993
if (waitpid(pid, &status, 0) < 0)
19611994
status = 255;
1995+
trace2_exec_result(status);
19621996
exit(status);
19631997
}
19641998
return -1;

compat/mingw.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,7 @@ static inline int fcntl(int fd, int cmd, ...)
146146
errno = EINVAL;
147147
return -1;
148148
}
149-
/* bash cannot reliably detect negative return codes as failure */
150-
#define exit(code) exit((code) & 0xff)
149+
151150
#define sigemptyset(x) (void)0
152151
static inline int sigaddset(sigset_t *set, int signum)
153152
{ return 0; }

config.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2682,6 +2682,8 @@ int git_config_set_gently(const char *key, const char *value)
26822682
void git_config_set(const char *key, const char *value)
26832683
{
26842684
git_config_set_multivar(key, value, NULL, 0);
2685+
2686+
trace2_cmd_set_config(key, value);
26852687
}
26862688

26872689
/*

connect.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,7 @@ struct child_process *git_connect(int fd[2], const char *url,
12551255
conn = NULL;
12561256
} else if (protocol == PROTO_GIT) {
12571257
conn = git_connect_git(fd, hostandport, path, prog, version, flags);
1258+
conn->trace2_child_class = "transport/git";
12581259
} else {
12591260
struct strbuf cmd = STRBUF_INIT;
12601261
const char *const *var;
@@ -1297,9 +1298,11 @@ struct child_process *git_connect(int fd[2], const char *url,
12971298
strbuf_release(&cmd);
12981299
return NULL;
12991300
}
1301+
conn->trace2_child_class = "transport/ssh";
13001302
fill_ssh_args(conn, ssh_host, port, version, flags);
13011303
} else {
13021304
transport_check_allowed("file");
1305+
conn->trace2_child_class = "transport/file";
13031306
if (version > 0) {
13041307
argv_array_pushf(&conn->env_array, GIT_PROTOCOL_ENVIRONMENT "=version=%d",
13051308
version);

editor.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ static int launch_specified_editor(const char *editor, const char *path,
7878
p.argv = args;
7979
p.env = env;
8080
p.use_shell = 1;
81+
p.trace2_child_class = "editor";
8182
if (start_command(&p) < 0)
8283
return error("unable to start editor '%s'", editor);
8384

exec-cmd.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ static int git_get_exec_path(struct strbuf *buf, const char *argv0)
209209
return -1;
210210
}
211211

212+
trace2_cmd_path(buf->buf);
213+
212214
return 0;
213215
}
214216

@@ -328,16 +330,22 @@ const char **prepare_git_cmd(struct argv_array *out, const char **argv)
328330
int execv_git_cmd(const char **argv)
329331
{
330332
struct argv_array nargv = ARGV_ARRAY_INIT;
333+
int err;
331334

332335
prepare_git_cmd(&nargv, argv);
333336
trace_argv_printf(nargv.argv, "trace: exec:");
337+
trace2_exec("git", (const char **)nargv.argv);
334338

335339
/* execvp() can only ever return if it fails */
336340
sane_execvp("git", (char **)nargv.argv);
337341

338-
trace_printf("trace: exec failed: %s\n", strerror(errno));
342+
err = errno;
343+
trace_printf("trace: exec failed: %s\n", strerror(err));
344+
trace2_exec_result(err);
339345

340346
argv_array_clear(&nargv);
347+
348+
errno = err;
341349
return -1;
342350
}
343351

git-compat-util.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,13 @@ static inline int is_missing_file_error(int errno_)
12961296

12971297
extern int cmd_main(int, const char **);
12981298

1299+
/*
1300+
* Intercept all calls to exit() and route them to trace2 to
1301+
* optionally emit a message before calling the real exit().
1302+
*/
1303+
int trace2_cmd_exit_fl(const char *file, int line, int code);
1304+
#define exit(code) exit(trace2_cmd_exit_fl(__FILE__, __LINE__, (code)))
1305+
12991306
/*
13001307
* You can mark a stack variable with UNLEAK(var) to avoid it being
13011308
* reported as a leak by tools like LSAN or valgrind. The argument

0 commit comments

Comments
 (0)