Closed wkozaczuk closed 1 year ago
Tracepoints are explicitly designed for having near-zero performance impact when not enabled (add a single nop instruction). I don't remember how much they increase the kernel size - I don't think it's much but you can try adding 150 silly tracepoint calls. You can also make it perhaps just one tracepoint called in 150 different places.
Putting aside any impact on kernel size, one issue I have with tracepoints is one cannot easily see the results they capture as things happen which I can do with strace
. One has to connect with gdb to see things after the fact. In which case some tracepoints may be gone because I understand they use some sort of ring buffer and new tracepoints at some point would roll over the old ones, no?
It would be nice to enhance tracepoints to maybe add a thread that could print them to the standard out as they happen and flush they right away.
The idea with tracepoints is that they let you do three things efficiently:
A buffer of the last events is especially useful when debugging a crash, so the last events are probably (maybe) the ones that caused the crash.
Though I admit that for fairly rare events, adding an strace-like command can be useful.
By the way, in case you haven't noticed it (I think that you did, but just in case...) the script I mentioned above is scripts/freq.py
, which uses the REST API (not gdb) to connect to OSv and get the frequency of certain tracepoints. For example - get the number of context switches per second, number of system calls per second, and so on. It's fine that these numbers are huge (e.g., 1 million per second) - it's still very efficient. The script enables counting on the requested tracepoints, and then periodically reads those counts.
We also have in the REST API (see modules/httpserver-api/api-doc/listings/trace.json) the ability to enable full/random/backtraced tracing of events and retrieve the full trace buffer - so if the http server is included in the image, you don't need to use gdb. I think (?) we have in scripts/trace.py code to parse the content of this buffer (I think you yourself documented this script, in https://github.com/cloudius-systems/osv/wiki/Trace-analysis-using-trace.py).
With upcoming changes to OSv to support running statically linked executables or dynamically linked executables bootstrapped by Linux dynamic linker, it would be nice to have a mechanism to enable logging of what syscalls are called and with what parameters and what result they return.
This could be as simple as what this patch fragment does:
Ideally, we should make it so it does not affect the syscall performance if syscall logging is disabled. Maybe logging would be only compiled based on some
#ifdef
variable instead of being dynamically enabled by a new kernel flag.Another alternative would to be use tracepoints, but I am afraid adding ~150 new tracepoints (or 300 including the
*_ret
ones) will increase kernel size significantly and affect the performance.