PT_BLK_SYNC_FORWARD(3)

πŸ“¦ version 2.1.2, in fedora 43, fedora 44

πŸ’… PT_BLK_SYNC_FORWARD β€” bestie edition

okay so real talk, we're looking at the pt_blk_sync_forward, pt_blk_sync_backward and pt_blk_sync_set functions from the Intel(R) PT block decoder family β€” this whole page lives in section 3 of the manual and it's literally just "how do I get my block decoder back in sync with the trace". Let's get into it 🫢


✨ NAME ✨

pt_blk_sync_forward, pt_blk_sync_backward, pt_blk_sync_set β€” synchronize an Intel(R) Processor Trace block decoder. no cap, that's the whole job.


πŸŽ€ SYNOPSIS πŸŽ€

#include <intel-pt.h>
int pt_blk_sync_forward(struct pt_block_decoder *decoder);
int pt_blk_sync_backward(struct pt_block_decoder *decoder);
int pt_blk_sync_set(struct pt_block_decoder *decoder,
                    uint64_t offset);

Link with -lipt.
heads up bestie: don't forget the Link with -lipt β€” that's the vibe check that makes it actually link.

πŸ’– DESCRIPTION πŸ’–

So these three functions synchronize an Intel Processor Trace (Intel PT) block decoder β€” the one pointed to by decoder β€” onto the trace stream sitting in decoder's trace buffer. it's giving "get this decoder oriented" energy.

What they do: they go hunt for a Packet Stream Boundary (PSB) packet in the trace stream, and if they find one, they set decoder's current position and synchronization position to that packet, then start processing packets. and for the synchronization to be successfull (yes, the original page spells it like that, iconic), there must be a full PSB+ header in the trace stream. no full PSB+ header, no slay. 😭

  • pt_blk_sync_forward() β€” searches in the forward direction, from decoder's current position towards the end of the trace buffer. and if decoder has been newly allocated and hasn't been synchronized yet? the search starts from the beginning of the trace. cute.
  • pt_blk_sync_backward() β€” searches in the backward direction, from decoder's current position towards the beginning of the trace buffer. and if decoder has been newly allocated and hasn't been synchronized yet, the search starts from the end of the trace. mirrored, we love to see it.
  • pt_blk_sync_set() β€” searches at offset bytes from the beginning of its trace buffer. that's it, that's the whole thing, main character energy.

🌟 RETURN VALUE 🌟

All of the synchronization functions return zero or a positive value on success, or a negative pt_error_code enumeration constant if something went wrong. πŸ’€

On success, you get back a bit-vector of pt_status_flag enumeration constants. and the pt_status_flag enumeration is declared like this, verbatim, no edits:

/** Decoder status flags. */
enum pt_status_flag {
    /** There is an event pending. */
    pts_event_pending    = 1 << 0,

    /** The address has been suppressed. */
    pts_ip_suppressed    = 1 << 1,

    /** There is no more trace data available. */
    pts_eos              = 1 << 2
};

The pts_event_pending flag means one or more events are pending. bestie, use pt_blk_event(3) to process pending events before you call pt_blk_next(3). order matters, periodt.

The pt_eos flag means the information contained in the Intel PT stream has been consumed. Calls to pt_blk_next() will still hand you blocks for instructions for as long as the instruction's addresses can be determined without further trace. ✨


πŸ”₯ ERRORS πŸ”₯

  • pte_invalid β€” the decoder argument is NULL. yeah. that one.
  • pte_eos β€” there is no (further) PSB+ header in the trace stream (pt_blk_sync_forward() and pt_blk_sync_backward()) or at offset bytes into the trace buffer (pt_blk_sync_set()).
  • pte_nosync β€” there is no PSB packet at offset bytes from the beginning of the trace (pt_blk_sync_set() only).
  • pte_bad_opc β€” the decoder encountered an unsupported Intel PT packet opcode. 😡
  • pte_bad_packet β€” the decoder encountered an unsupported Intel PT packet payload.

πŸ¦‹ EXAMPLE πŸ¦‹

here's the glow-up moment: this example re-synchronizes an Intel PT block decoder after decode errors. copy it exactly, i'm not kidding:

int foo(struct pt_block_decoder *decoder) {
    for (;;) {
        int errcode;

        errcode = pt_blk_sync_forward(decoder);
        if (errcode < 0)
            return errcode;

        do {
            errcode = decode(decoder);
        } while (errcode >= 0);
    }
}

🌈 SEE ALSO 🌈

go read these next, i'm obsessed:


and that's the whole page bestie πŸ’œ this one's from the PT_BLK_SYNC_FORWARD(3) manual, section 3, footer says PT_BLK_SYNC_FORWARD(3) too β€” go off, synchronize responsibly, and remember: full PSB+ header or it didn't happen πŸŽ€βœ¨

πŸ“¦ where this page comes from