On Fri, 22 Feb 2019 20:05:33 +0200 Slavomir Kaslev <kaslevs@xxxxxxxxxx> wrote: > +static void agent_serve(unsigned int port) > +{ > + int sd, cd, nr_cpus; > + pid_t pid; > + > + signal(SIGCHLD, handle_sigchld); > + > + nr_cpus = count_cpus(); > + page_size = getpagesize(); > + > + sd = make_vsock(port); > + if (sd < 0) > + die("Failed to open vsocket"); > + > + for (;;) { > + cd = accept(sd, NULL, NULL); > + if (cd < 0) { > + if (errno == EINTR) > + continue; > + die("accept"); > + } > + > + if (handler_pid) > + goto busy; > + > + pid = fork(); Also, for debugging purposes, I add a --debug option that prevents forking, and the process is handled directly. The patch below is sorta the idea. This way we can run both the agent and host under gdb and step through the communication, without having to deal with "set follow-fork" modes. -- Steve > + if (pid == 0) { > + close(sd); > + signal(SIGCHLD, SIG_DFL); > + agent_handle(cd, nr_cpus, page_size); > + } > + if (pid > 0) > + handler_pid = pid; > + > +busy: > + close(cd); > + } > +} > + diff --git a/tracecmd/trace-agent.c b/tracecmd/trace-agent.c index 02dda47..da6ff12 100644 --- a/tracecmd/trace-agent.c +++ b/tracecmd/trace-agent.c @@ -170,6 +170,15 @@ static void handle_sigchld(int sig) } } +static pid_t do_fork() +{ + /* in debug mode, we do not fork off children */ + if (debug) + return 0; + + return fork(); +} + static void agent_serve(unsigned int port) { int sd, cd, nr_cpus; @@ -195,7 +204,7 @@ static void agent_serve(unsigned int port) if (handler_pid) goto busy; - pid = fork(); + pid = do_fork(); if (pid == 0) { close(sd); signal(SIGCHLD, SIG_DFL); @@ -209,6 +218,10 @@ busy: } } +enum { + DO_DEBUG = 255 +}; + void trace_agent(int argc, char **argv) { bool do_daemon = false; @@ -225,6 +238,7 @@ void trace_agent(int argc, char **argv) static struct option long_options[] = { {"port", required_argument, NULL, 'p'}, {"help", no_argument, NULL, '?'}, + {"debug", no_argument, NULL, DO_DEBUG}, {NULL, 0, NULL, 0} }; @@ -242,6 +256,9 @@ void trace_agent(int argc, char **argv) case 'D': do_daemon = true; break; + case DO_DEBUG: + debug = true; + break; default: usage(argv); }