I am struggling to find an elegant way of doing the following:
I want a makefile rule which:
trace-XXXXX
where XXXXX
is the PID of QEMU when it ran../qemu ... & echo $!
and put this in some variable (where the scope of the variable is within the rule)Currently I have the following:
trace:
./qemu/build/qemu-riscv64 -d plugin,nochain --trace "exec_tb" -plugin ./test_plugin.so ./test_qemu & export TRACE_PID=$$!; \
echo Trace PID is $$TRACE_PID; \
wait $$TRACE_PID; \
python3 ./qemu/scripts/simpletrace.py ./qemu/build/trace/trace-events-all trace-$$TRACE_PID
But it doesn't seem to work. I see the "Trace PID is " but then get a command not found on line 1
which I think could be due to the stdout of qemu breaking things.
Is there a clean and elegant way to do this?
Captures this PID when qemu is invoked, ie
./qemu ... & echo $!
The &
causes your qemu
to run in the background, but this is counter-productive because you want to wait for it to complete.
The only real reason to capture the PID seems to be to compute the name of the trace file. If qemu supports it, the best approach would be to choose the name for the trace file yourself, and tell qemu
to write there. Then you could just run qemu
in the foreground (no wait
), and analyze the file afterward. The mktemp
command would serve to create a new file with a distinct name, if you need that.
If you have no way to control the trace file name up front, then you could still do a little better (IMO) by keeping everything in the foreground, something like this:
trace:
TRACE_PID=$$(/bin/sh -c 'echo $$$$; exec ./qemu/build/qemu-riscv64 -d plugin,nochain --trace "exec_tb" -plugin ./test_plugin.so ./test_qemu >qemu.out 2>&1'); \
echo Trace PID is $$TRACE_PID; \
python3 ./qemu/scripts/simpletrace.py ./qemu/build/trace/trace-events-all trace-$$TRACE_PID
Notes:
the shell will execute the contents of the command substitution $(...)
in a subshell, but that's not necessarily running in a different process. We do want a different process for this, so from the subshell we start a separate shell process.
the shell running in that separate process reports its PID via an echo
command, which the top-level shell will capture. It uses exec
to run qemu
in the same process, so the PID already reported will be correct for qemu
.
The qemu
command's standard output is redirected to a file to prevent it being captured, too. Its standard error is redirected to the same file for tidiness, and a bit to avoid potential confusion.
There is no need to wait
for anything because no background jobs have been started. The echo Trace PID ...
command does not start until after qemu
has finished.
There does not appear to be a need to export TRACE_PID
, as it appears only to be used in the current shell process, not in any child processes.
Neither this version nor yours responds to a qemu
failure. This version could more easily be adapted to do that, and probably should be so adapted.
You might want to provide a full path to the python3
executable. You might even want to create a make
variable for it.