As I mentioned in an earlier post, I'm writing some Rust code that involves collecting and decoding processor traces. My code calls out to C using `perf_event_open` for collecting, and libipt for the decoding.
I've almost got block decoding working, but there is one outstanding issue. Sometimes if I repeatedly collect short traces, then lilbipt chokes trying to perform the initial block decoder sync. It returns `-pte_eos` indicating that the buffer I passed the decoder didn't contain any synchronisation point. This manifested in a rather hilarious fashion when I realised my example code worked with optimisations turned off, but not with them on. I'm guessing that the optimisations made the trace small enough to trigger this bug :)
The way I trace code is like this:
I have a theory that perhaps `close()` is needed to fully flush the PT buffer, but I can't find any documentation on this. I had been re-using the existing fd as I thought it would be more efficient. A quick hack on my code suggests that closing the fd between tracings does work.
I also tried using `fsync` to manually flush the PT buffer, but it seems like it always returns -1.
Does anyone know anything about this? Is there an explicit way to flush the buffer, or should I be closing the fd after each tracing session?
For anyone reading this, I think the answer is "yes, you can re-use a Perf file descriptor, but you are not guaranteed a `PSB+` packet sequence to synchronise your decoder to".
More information here: