PT_INSN_SYNC_FORWARD(3)

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

πŸ’– PT_INSN_SYNC_FORWARD(3) β€” bestie's guide to syncing your Intel PT insn decoder πŸ’–

okay so. you're in section 3 of the manual, and the star of the show is pt_insn_sync_forward(3), but she brought her two besties pt_insn_sync_backward(3) and pt_insn_sync_set(3). it's giving ✨ decoder glow-up ✨. let's go.


🌸 NAME 🌸

pt_insn_sync_forward, pt_insn_sync_backward, pt_insn_sync_set β€” synchronize an Intel(R) Processor Trace instruction flow decoder πŸŽ€


πŸ¦‹ SYNOPSIS πŸ¦‹

#include <intel-pt.h>
int pt_insn_sync_forward(struct pt_insn_decoder *decoder);
int pt_insn_sync_backward(struct pt_insn_decoder *decoder);
int pt_insn_sync_set(struct pt_insn_decoder *decoder,
                     uint64_t offset);

Link with -lipt.


✨ DESCRIPTION ✨

so these three functions do the vibe check on an Intel Processor Trace (Intel PT) instruction flow decoder β€” the one pointed to by decoder β€” and get it synchronized onto the trace stream sitting in decoder's trace buffer. lowkey iconic behavior.

what they actually do: they go looking 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 and start processing packets. but listen β€” for synchronization to be successfull (yes bestie, the typo is canon, it's in the original, we don't fix it, we respect it πŸ’…), there must be a full PSB+ header in the trace stream. no full header, no sync. periodt.

  • pt_insn_sync_forward() β€” searches in the forward direction, from decoder's current position towards the end of the trace buffer. if decoder was newly allocated and has never been synchronized yet, the search starts from the beginning of the trace. baby's first sync 🍼
  • pt_insn_sync_backward() β€” searches in the backward direction, from decoder's current position towards the beginning of the trace buffer. if decoder was newly allocated and has never been synchronized yet, the search starts from the end of the trace. she walks backwards, she doesn't care πŸšΆβ™€οΈβ¬…οΈ
  • pt_insn_sync_set() β€” searches at offset bytes from the beginning of its trace buffer. that's it. that's the whole vibe. pinpoint accuracy 🎯

πŸ‘‘ RETURN VALUE πŸ‘‘

all 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. the pt_status_flag enumeration is declared like this:

/** 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. use pt_insn_event(3) to process pending events before calling pt_insn_next(3). order matters bestie, don't skip ahead πŸ™ˆ

the pt_eos flag means the information contained in the Intel PT stream has been consumed. calls to pt_insn_next() will provide instructions as long as the instruction's address can be determined without trace. so like, it keeps going, but only on vibes and address math ✨

ngl there's a bit of naming chaos here β€” the description calls the flag pt_eos, but the enum declares pts_eos. that's the original's energy, we're not touching it πŸ’€

πŸ”₯ ERRORS πŸ”₯

  • pte_invalid β€” the decoder argument is NULL. bestie. you passed nothing. 😭
  • pte_eos β€” there is no (further) PSB+ header in the trace stream (pt_insn_sync_forward() and pt_insn_sync_backward()) or at offset bytes into the trace buffer (pt_insn_sync_set()).
  • pte_nosync β€” there is no PSB packet at offset bytes from the beginning of the trace (pt_insn_sync_set() only). forward and backward girlies, this one's not for you πŸ’…
  • 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 πŸŽ€

the following example re-synchronizes an Intel PT instruction flow decoder after decode errors β€” it's giving main character recovers from heartbreak energy:

int foo(struct pt_insn_decoder *decoder) {
    for (;;) {
        int status;

        status = pt_insn_sync_forward(decoder);
        if (status < 0)
            return status;

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

🌈 SEE ALSO 🌈

pt_insn_alloc_decoder(3), pt_insn_free_decoder(3), pt_insn_get_offset(3), pt_insn_get_sync_offset(3), pt_insn_get_config(3), pt_insn_time(3), pt_insn_core_bus_ratio(3), pt_insn_next(3), pt_insn_event(3)


and that's the whole page, bestie 🫢 go forth and synchronize. this was PT_INSN_SYNC_FORWARD(3) β€” same name up top, same name at the bottom, we love a symmetrical queen πŸ‘‘βœ¨πŸ’–

πŸ“¦ where this page comes from