Uh oh!
There was an error while loading. Please reload this page.
Soften POSIX signal for termination of perf - #384
Conversation
Replace the default SIGKILL signal sent to perf to "request" its termination by a SIGINT, allowing it to handle the signal by cleaning up before exit. This should address issues regarding corrupted perf.data output files.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
setrofim
commented
May 7, 2019
I have this feeling that there may have some reason. But at the moment, I cannot recall the specific issue. Using the One thing that would need to be checked as part of the switch is that the |
Context
A
SIGKILLis, by definition, not allowed to be handled by a process. Therefore, a process receiving this signal isn't able to "clean up" before termination. This is particularly problematic in the case of programs that have "buffered" data (to limit filesystem I/O) and/or that are supposed to output their result when returning.Typically,
perfis used with a target command (e.g.sleepin theCOMMAND_TEMPLATES). It collects samples (or does something else depending on the command and flags) until that command returns at which point, it writes back its result (perf.data, output tostdout, ...) before its own termination.However, if a
SIGKILL(or other similar signal) is sent toperf, this can't happen for the reason detailed above and its results are (at least partially) lost. Furthermore, in this case, the target command is still alive after this has happened as it is not a child of theperfprocess.Finally, if a
SIGINT(or other similar signal) is sent toperf, it handles it by "properly" outputting its results (AFAIK) before returning; it ignores the target command, which stays alive.Therefore, we can trigger the "clean" reporting from
perfand have a "clean exit" (no target command alive) by sendingSIGKILLto the target command but nothing prevents us from sendingSIGINTtoperfbefore that! By doing so, we guarantee "cleanperfresults" which adds robustness to the code.Issue
I am worried that the current implementation might send
SIGKILLtoperf, depending on the output format ofps(typically native to the device and varying between models):.killall()(which sendsSIGKILL, by default, to a list of processes) calls.get_pids_of()which finds the list by runningpsand keeping the linesinwhich the passed keyword (sleep, here) can be found [*];ps, itsCOMMAND/CMDcolumn could output the arguments of the call (along with the command itself): in such a case, the previously described "grep" would pick all lines containing'sleep'which includes the ones such as'perf stat -a sleep 100';COMMAND/CMD,.killall()ends up sendingSIGKILLtoperf;This PR is motivated by comments on #382 and I believe that what I'm addressing here might be the cause. But, as this is an idea that came up from reading the code, I would really appreciate if it was tested on devices that currently report "corrupted" outputs from
perf.psThe lack of (single) standard behaviour for
psis pretty clear in its Ubuntumanpage:and formats exist with and without arguments:
I particularly like the following acknowledgement ("
most"):So, depending on what the version of
psavailable on the device implements (and on which defaults it uses), its output is likely to vary between devices. For comparison:Comments
On top of this PR, could
.ps()be re-implemented to usepsfrom the pushedbusybox? This would allow a somewhat more standard behaviour or are there reasons why we don't want to do that? From a log, I believe this is not what is being done:[*] : Note that, in the case of
LinuxTarget,.get_pids_of()seems to be somewhat more robust as it uses-C(which uses the command name) and will simply fail if that flag is not supported. Obviously, this is based on the hope that there are no implementations ofpswhere-Cusesargs...