kcov icon indicating copy to clipboard operation
kcov copied to clipboard

kcov doesn't exit if an instrumented bash script spawns a daemon process

Open dciabrin opened this issue 5 years ago • 2 comments

I want to run kcov on bash scripts that act as agents in a cluster manager [1]. Those scripts are in charge of starting daemon services such as e.g. mysql, and exit right after, leaving the deamon running.

When running the agent script via kcov, I noticed that kcov never returns. This is because currently, kcov only detects the instrumented bash script exited after all data from the pipe used as the bash xtrace fd has been read.

Unfortunately, in my case, the bash scripts forks/exec a daemon process that keeps running in background. This means the xtrace file descriptor is leaked into this daemon process. Consequently, the write side of the pipe is not closed when the bash script exits, so kcov is stuck in reading and cannot detect the bash script ended and exit successfully.

One can replicate the issue with the following bash script:

#!/bin/sh
sleep infinity &
echo main script ended

[1] https://github.com/ClusterLabs/resource-agents/ for the record

dciabrin avatar May 06 '20 09:05 dciabrin

Some food for thought,

I couldn't find an easy way to fix this issue... I believe we want to read the trace fd until it's closed to make sure we don't lose any location info. So I assume we want to ensure the write part of the pipe can always be closed.

At some point I wondered if we should implement a strategy like "if the child process to be exec'd is not a bash script, close our the trace fd we inherited". But then, my original problem would persist if the bash agent needs to run a daemon process that is a shell script.

So I settled for a strategy like "do not clone the tracefd when forking". But as a side effect, one can't trace spawn processes if they are shell scripts. So I proposed to make that an optional behaviour.

Also, I couldn't find a simple bash-ism to configure a file descriptor with fcntl in a running script. So I had to settle for the same clever LD_PRELOAD trick that is used in option --bash-handle-sh-invocation. The drawback is that it only works for Linux. But at least getting coverage for my use case works on Linux, which looks reasonable to me.

Up for discussion, thanks!

dciabrin avatar May 06 '20 09:05 dciabrin

Yes, I think this sounds reasonable. Since it's an option, I think Linux-only is OK (probably 95% of the users anyway).

As an alternative, perhaps the --exit-first-process could be piggy-backed to LD_PRELOAD your new library? It might not quite describe all of your problem though, so perhaps it's best to go with a specific option.

Thanks again for the detailed descriptions and good work!

SimonKagstrom avatar May 06 '20 10:05 SimonKagstrom