koute / not-perf

A sampling CPU profiler for Linux
Apache License 2.0
871 stars 41 forks source link

profiling process startup / specify command to run and profile #27

Open JohannesSchilling opened 2 years ago

JohannesSchilling commented 2 years ago

i'm trying to profile the startup of my application, which should be done in the 100ms that we're waiting between attempts at finding the process; would there be interest in such a feature? maybe some guidance on where to start/add that? i.e. i'd be willing to help implementing, just making sure i didn't get the docs wrong and it already exists, and/or avoid putting in time and effort and the feature being not implemented on purpose.

koute commented 2 years ago

The feature would be nice to have; it was not implement just because I had no need for it.

As for how to exactly implement it, from the top of my head I'm not entirely sure. We'd need to spawn the target process in an already stopped state, and only let it run once the profiling is set up. Probably using ptrace; quoting the manpage:

A process can initiate a trace by calling fork(2) and having the resulting child do a PTRACE_TRACEME, followed (typically) by an execve(2). Alternatively, one process may commence tracing another process using PTRACE_ATTACH or PTRACE_SEIZE.

While being traced, the tracee will stop each time a signal is delivered, even if the signal is being ignored. (An exception is SIGKILL, which has its usual effect.) The tracer will be notified at its next call to waitpid(2) (or one of the related "wait" system calls); that call will return a status value containing information that indicates the cause of the stop in the tracee. While the tracee is stopped, the tracer can use various ptrace requests to inspect and modify the tracee. The tracer then causes the tracee to continue, optionally ignoring the delivered signal (or even delivering a different signal instead).

If the PTRACE_O_TRACEEXEC option is not in effect, all successful calls to execve(2) by the traced process will cause it to be sent a SIGTRAP signal, giving the parent a chance to gain control before the new program begins execution.

So, something like this maybe:

There might also be alternative ways to implement this.