Skip to content

Commit

Permalink
Merge pull request #100 from jeffhostetler/gvfs-trace2-v3
Browse files Browse the repository at this point in the history
Trace2 V3 (squash/fixup of V1+V2)
  • Loading branch information
jeffhostetler authored Jan 4, 2019
2 parents ab10b47 + f4e9264 commit 534dbe1
Show file tree
Hide file tree
Showing 45 changed files with 1,852 additions and 88 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,7 @@ TEST_BUILTINS_OBJS += test-string-list.o
TEST_BUILTINS_OBJS += test-submodule-config.o
TEST_BUILTINS_OBJS += test-submodule-nested-repo-config.o
TEST_BUILTINS_OBJS += test-subprocess.o
TEST_BUILTINS_OBJS += test-trace2.o
TEST_BUILTINS_OBJS += test-urlmatch-normalization.o
TEST_BUILTINS_OBJS += test-wildmatch.o
TEST_BUILTINS_OBJS += test-windows-named-pipe.o
Expand Down Expand Up @@ -1009,6 +1010,7 @@ LIB_OBJS += trace2/tr2_tgt_event.o
LIB_OBJS += trace2/tr2_tgt_normal.o
LIB_OBJS += trace2/tr2_tgt_perf.o
LIB_OBJS += trace2/tr2_tls.o
LIB_OBJS += trace2/tr2_verb.o
LIB_OBJS += trailer.o
LIB_OBJS += transport.o
LIB_OBJS += transport-helper.o
Expand Down
1 change: 1 addition & 0 deletions builtin/am.c
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,7 @@ static int run_post_rewrite_hook(const struct am_state *state)

cp.in = xopen(am_path(state, "rewritten"), O_RDONLY);
cp.stdout_to_stderr = 1;
cp.trace2_hook_name = "post-rewrite";

ret = run_command(&cp);

Expand Down
7 changes: 7 additions & 0 deletions builtin/checkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,8 @@ static int checkout_paths(const struct checkout_opts *opts,
int errs = 0;
struct lock_file lock_file = LOCK_INIT;

trace2_cmd_subverb(opts->patch_mode ? "patch" : "path");

if (opts->track != BRANCH_TRACK_UNSPECIFIED)
die(_("'%s' cannot be used with updating paths"), "--track");

Expand Down Expand Up @@ -930,6 +932,9 @@ static int switch_branches(const struct checkout_opts *opts,
void *path_to_free;
struct object_id rev;
int flag, writeout_error = 0;

trace2_cmd_subverb("branch");

memset(&old_branch_info, 0, sizeof(old_branch_info));
old_branch_info.path = path_to_free = resolve_refdup("HEAD", 0, &rev, &flag);
if (old_branch_info.path)
Expand Down Expand Up @@ -1159,6 +1164,8 @@ static int switch_unborn_to_new_branch(const struct checkout_opts *opts)
int status;
struct strbuf branch_ref = STRBUF_INIT;

trace2_cmd_subverb("unborn");

if (!opts->new_branch)
die(_("You are on a branch yet to be born"));
strbuf_addf(&branch_ref, "refs/heads/%s", opts->new_branch);
Expand Down
19 changes: 18 additions & 1 deletion builtin/commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ static int opt_parse_porcelain(const struct option *opt, const char *arg, int un
static int do_serialize = 0;
static char *serialize_path = NULL;

static int reject_implicit = 0;
static int do_implicit_deserialize = 0;
static int do_explicit_deserialize = 0;
static char *deserialize_path = NULL;
Expand Down Expand Up @@ -202,7 +203,7 @@ static int opt_parse_deserialize(const struct option *opt, const char *arg, int
if (arg) /* override config or stdin */
deserialize_path = xstrdup(arg);
if (deserialize_path && *deserialize_path
&& (access(deserialize_path, R_OK) != 0))
&& (wt_status_deserialize_access(deserialize_path, R_OK) != 0))
die("cannot find serialization file '%s'",
deserialize_path);

Expand Down Expand Up @@ -1396,6 +1397,8 @@ static int git_status_config(const char *k, const char *v, void *cb)
if (v && *v && access(v, R_OK) == 0) {
do_implicit_deserialize = 1;
deserialize_path = xstrdup(v);
} else {
reject_implicit = 1;
}
return 0;
}
Expand Down Expand Up @@ -1552,6 +1555,17 @@ int cmd_status(int argc, const char **argv, const char *prefix)
(do_implicit_deserialize || do_explicit_deserialize));
if (try_deserialize)
goto skip_init;
/*
* If we implicitly received a status cache pathname from the config
* and the file does not exist, we silently reject it and do the normal
* status "collect". Fake up some trace2 messages to reflect this and
* assist post-processors know this case is different.
*/
if (!do_serialize && reject_implicit) {
trace2_cmd_subverb("implicit-deserialize");
trace2_data_string("status", the_repository, "deserialize/reject",
"status-cache/access");
}

enable_fscache(0);
if (status_format != STATUS_FORMAT_PORCELAIN &&
Expand Down Expand Up @@ -1595,6 +1609,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
if (s.relative_paths)
s.prefix = prefix;

trace2_cmd_subverb("deserialize");
result = wt_status_deserialize(&s, deserialize_path, dw);
if (result == DESERIALIZE_OK)
return 0;
Expand All @@ -1612,6 +1627,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
fd = -1;
}

trace2_cmd_subverb("collect");
wt_status_collect(&s);

if (0 <= fd)
Expand All @@ -1626,6 +1642,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
if (fd_serialize < 0)
die_errno(_("could not serialize to '%s'"),
serialize_path);
trace2_cmd_subverb("serialize");
wt_status_serialize_v1(fd_serialize, &s);
close(fd_serialize);
}
Expand Down
19 changes: 19 additions & 0 deletions builtin/rebase.c
Original file line number Diff line number Diff line change
Expand Up @@ -1009,6 +1009,16 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
ACTION_EDIT_TODO,
ACTION_SHOW_CURRENT_PATCH,
} action = NO_ACTION;
static const char *action_names[] = {
N_("undefined"),
N_("continue"),
N_("skip"),
N_("abort"),
N_("quit"),
N_("edit_todo"),
N_("show_current_patch"),
NULL
};
const char *gpg_sign = NULL;
struct string_list exec = STRING_LIST_INIT_NODUP;
const char *rebase_merges = NULL;
Expand Down Expand Up @@ -1195,6 +1205,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
die(_("The --edit-todo action can only be used during "
"interactive rebase."));

if (trace2_is_enabled()) {
if (is_interactive(&options))
trace2_cmd_subverb("interactive");
else if (exec.nr)
trace2_cmd_subverb("interactive-exec");
else
trace2_cmd_subverb(action_names[action]);
}

switch (action) {
case ACTION_CONTINUE: {
struct object_id head;
Expand Down
4 changes: 4 additions & 0 deletions builtin/receive-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,8 @@ static int run_and_feed_hook(const char *hook_name, feed_fn feed,
proc.argv = argv;
proc.in = -1;
proc.stdout_to_stderr = 1;
proc.trace2_hook_name = hook_name;

if (feed_state->push_options) {
int i;
for (i = 0; i < feed_state->push_options->nr; i++)
Expand Down Expand Up @@ -807,6 +809,7 @@ static int run_update_hook(struct command *cmd)
proc.stdout_to_stderr = 1;
proc.err = use_sideband ? -1 : 0;
proc.argv = argv;
proc.trace2_hook_name = "update";

code = start_command(&proc);
if (code)
Expand Down Expand Up @@ -1190,6 +1193,7 @@ static void run_update_post_hook(struct command *commands)
proc.no_stdin = 1;
proc.stdout_to_stderr = 1;
proc.err = use_sideband ? -1 : 0;
proc.trace2_hook_name = "post-update";

if (!start_command(&proc)) {
if (use_sideband)
Expand Down
8 changes: 8 additions & 0 deletions builtin/reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
if (patch_mode) {
if (reset_type != NONE)
die(_("--patch is incompatible with --{hard,mixed,soft}"));
trace2_cmd_subverb("patch-interactive");
return run_add_interactive(rev, "--patch=reset", &pathspec);
}

Expand All @@ -435,6 +436,13 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
if (reset_type == NONE)
reset_type = MIXED; /* by default */

if (read_from_stdin)
trace2_cmd_subverb("path-stdin");
else if (pathspec.nr)
trace2_cmd_subverb("path");
else
trace2_cmd_subverb(reset_type_names[reset_type]);

if (reset_type != SOFT && (reset_type != MIXED || get_git_work_tree()))
setup_work_tree();

Expand Down
1 change: 1 addition & 0 deletions builtin/worktree.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ static int add_worktree(const char *path, const char *refname,
cp.dir = path;
cp.env = env;
cp.argv = NULL;
cp.trace2_hook_name = "post-checkout";
argv_array_pushl(&cp.args, absolute_path(hook),
oid_to_hex(&null_oid),
oid_to_hex(&commit->object.oid),
Expand Down
12 changes: 10 additions & 2 deletions common-main.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ static void restore_sigpipe_to_default(void)

int main(int argc, const char **argv)
{
int result;

/*
* Always open file descriptors 0/1/2 to avoid clobbering files
* in die(). It also avoids messing up when the pipes are dup'ed
Expand All @@ -33,7 +35,9 @@ int main(int argc, const char **argv)
sanitize_stdfds();
restore_sigpipe_to_default();

trace2_initialize(argv);
trace2_initialize();
trace2_cmd_start(argv);
trace2_collect_process_info();

git_resolve_executable_dir(argv[0]);

Expand All @@ -43,5 +47,9 @@ int main(int argc, const char **argv)

attr_start();

return cmd_main(argc, argv);
result = cmd_main(argc, argv);

trace2_cmd_exit(result);

return result;
}
13 changes: 10 additions & 3 deletions compat/mingw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1945,6 +1945,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
return 0;
prog = path_lookup(interpr, 1);
if (prog) {
int exec_id;
int argc = 0;
#ifndef _MSC_VER
const
Expand All @@ -1954,14 +1955,16 @@ static int try_shell_exec(const char *cmd, char *const *argv)
ALLOC_ARRAY(argv2, argc + 1);
argv2[0] = (char *)cmd; /* full path to the script file */
memcpy(&argv2[1], &argv[1], sizeof(*argv) * argc);
exec_id = trace2_exec(prog, argv2);
pid = mingw_spawnv(prog, argv2, interpr);
if (pid >= 0) {
int status;
if (waitpid(pid, &status, 0) < 0)
status = 255;
trace2_exec_result(status);
trace2_exec_result(exec_id, status);
exit(status);
}
trace2_exec_result(exec_id, -1);
pid = 1; /* indicate that we tried but failed */
free(prog);
free(argv2);
Expand All @@ -1974,13 +1977,17 @@ int mingw_execv(const char *cmd, char *const *argv)
/* check if git_command is a shell script */
if (!try_shell_exec(cmd, argv)) {
int pid, status;
int exec_id;

exec_id = trace2_exec(cmd, (const char **)argv);
pid = mingw_spawnv(cmd, (const char **)argv, NULL);
if (pid < 0)
if (pid < 0) {
trace2_exec_result(exec_id, -1);
return -1;
}
if (waitpid(pid, &status, 0) < 0)
status = 255;
trace2_exec_result(status);
trace2_exec_result(exec_id, status);
exit(status);
}
return -1;
Expand Down
102 changes: 102 additions & 0 deletions compat/win32/ancestry.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#include "../../cache.h"
#include "../../json-writer.h"
#include <Psapi.h>
#include <tlHelp32.h>

/*
* Find the process data for the given PID in the given snapshot
* and update the PROCESSENTRY32 data.
*/
static int find_pid(DWORD pid, HANDLE hSnapshot, PROCESSENTRY32 *pe32)
{
pe32->dwSize = sizeof(PROCESSENTRY32);

if (Process32First(hSnapshot, pe32)) {
do {
if (pe32->th32ProcessID == pid)
return 1;
} while (Process32Next(hSnapshot, pe32));
}
return 0;
}

/*
* Accumulate JSON array:
* [
* exe-name-parent,
* exe-name-grand-parent,
* ...
* ]
*
* Note: we only report the filename of the process executable; the
* only way to get its full pathname is to use OpenProcess()
* and GetModuleFileNameEx() or QueryfullProcessImageName()
* and that seems rather expensive (on top of the cost of
* getting the snapshot).
*/
static void get_processes(struct json_writer *jw, HANDLE hSnapshot)
{
PROCESSENTRY32 pe32;
DWORD pid;

pid = GetCurrentProcessId();

/* We only want parent processes, so skip self. */
if (!find_pid(pid, hSnapshot, &pe32))
return;
pid = pe32.th32ParentProcessID;

while (find_pid(pid, hSnapshot, &pe32)) {

jw_array_string(jw, pe32.szExeFile);

pid = pe32.th32ParentProcessID;
}
}

/*
* Emit JSON data for the current and parent processes. Individual
* trace2 targets can decide how to actually print it.
*/
static void get_ancestry(void)
{
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if (hSnapshot != INVALID_HANDLE_VALUE) {
struct json_writer jw = JSON_WRITER_INIT;

jw_array_begin(&jw, 0);
get_processes(&jw, hSnapshot);
jw_end(&jw);

trace2_data_json("process", the_repository,
"windows/ancestry", &jw);

jw_release(&jw);
CloseHandle(hSnapshot);
}
}

/*
* Is a debugger attached to the current process?
*
* This will catch debug runs (where the debugger started the process).
* This is the normal case. Since this code is called during our startup,
* it will not report instances where a debugger is attached dynamically
* to a running git process, but that is relatively rare.
*/
static void get_is_being_debugged(void)
{
if (IsDebuggerPresent())
trace2_data_intmax("process", the_repository,
"windows/debugger_present", 1);
}

void trace2_collect_process_info(void)
{
if (!trace2_is_enabled())
return;

get_is_being_debugged();
get_ancestry();
}
Loading

0 comments on commit 534dbe1

Please sign in to comment.