perf_event_data/
lib.rs

1//! Parse data emitted by the linux `perf_event_open` syscall.
2//!
3//! # Important Types
4//! - [`Record`] is an enum that can parse any known record type emitted by
5//!   [`perf_event_open`]. You will likely want to start here.
6//! - The [`parse`] module has the [`Parser`] and [`ParseConfig`] types which
7//!   you will need in order to parse anything.
8//!
9//! [`perf_event_open`]: https://man7.org/linux/man-pages/man2/perf_event_open.2.html
10//!
11//! [mod]: crate::parse
12//! [`Parse`]: crate::parse::Parse
13//! [`Parser`]: crate::parse::Parser
14//! [`ParseConfig`]: crate::parse::ParseConfig
15//!
16//! # Example
17//! Parsing a mmap record directly from its raw byte format.
18//! ```
19//! # fn main() -> perf_event_data::parse::ParseResult<()> {
20//! use perf_event_data::endian::Little;
21//! use perf_event_data::parse::{ParseConfig, Parser};
22//! use perf_event_data::Record;
23//!
24//! let data: &[u8] = &[
25//!     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x16, 0x4C, 0x01, 0x00, 0x17, 0x4C, 0x01,
26//!     0x00, 0x00, 0xA0, 0x48, 0x96, 0x4F, 0x7F, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
27//!     0x00, 0x00, 0x00, 0xA0, 0x48, 0x96, 0x4F, 0x7F, 0x00, 0x00, 0x2F, 0x2F, 0x61, 0x6E, 0x6F,
28//!     0x6E, 0x00, 0x00,
29//! ];
30//!
31//! let config = ParseConfig::<Little>::default();
32//! let mut parser = Parser::new(data, config);
33//! let record: Record = parser.parse()?;
34//!
35//! let mmap = match record {
36//!     Record::Mmap(mmap) => mmap,
37//!     _ => panic!("expected a MMAP record"),
38//! };
39//! # Ok(())
40//! # }
41//! ```
42//!
43//! # Crate Orginization
44//! This crate is organized like this:
45//! - The root contains all the data types that records can be parsed into. This
46//!   includes not only the types corresponding to the perf records but also
47//!   those that make up their fields, and so on.
48//! - The [`parse`][mod] module contains types and traits needed to implement
49//!   parsing support. Most types exposed in the root implement [`Parse`] but to
50//!   actually make use of that you will need the [`Parser`] and [`ParseConfig`]
51//!   types from the [`parse`][mod] module.
52//! - The [`endian`] module contains some types for converting values to the
53//!   native endian. You likely won't have to interact with it other than
54//!   picking one type to use when creating a [`ParseConfig`].
55//!
56//! # Parsing `perf.data` files
57//! This crate doesn't yet have support for this, although it could be used as
58//! part of implementing a larger parser. If you would like to do this please
59//! open an issue!
60
61#![warn(missing_docs)]
62// bitflags generates this all over the place so better to silence it.
63#![allow(clippy::assign_op_pattern)]
64
65// Needs to be first so other modules can see the macros.
66#[macro_use]
67mod macros;
68
69mod config;
70pub mod endian;
71mod error;
72mod flags;
73mod impls;
74pub mod parse;
75mod parsebuf;
76mod records;
77mod util;
78mod visitor;
79
80mod prelude {
81    #[allow(unused_imports)]
82    pub(crate) use crate::config::ParseConfig;
83    pub(crate) use crate::endian::Endian;
84    pub(crate) use crate::error::ErrorKind;
85    pub(crate) use crate::flags::{ReadFormat, SampleFlags};
86    pub(crate) use crate::parse::{Parse, ParseBuf, ParseResult, Parser};
87    pub(crate) use c_enum::c_enum;
88}
89
90pub use crate::flags::*;
91pub use crate::records::*;
92pub use crate::visitor::{RecordMetadata, Visitor};
93
94/// Common data used in doctests.
95///
96/// This way it doesn't need to be repeated multiple times unless we want to
97/// show it as part of the doc test.
98///
99/// It is also used to verify that the examples within the README work.
100#[doc(hidden)]
101pub mod doctest {
102    #[doc = include_str!("../README.md")]
103    pub mod readme {}
104
105    pub const MMAP: &[u8] = &[
106        0x01, 0x00, 0x00, 0x00, // type (MMAP)
107        0x00, 0x00, // misc
108        0x30, 0x00, // size
109        0x16, 0x4C, 0x01, 0x00, // pid
110        0x17, 0x4C, 0x01, 0x00, // tid
111        0x00, 0xA0, 0x48, 0x96, 0x4F, 0x7F, 0x00, 0x00, // addr
112        0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // len
113        0x00, 0xA0, 0x48, 0x96, 0x4F, 0x7F, 0x00, 0x00, // pgoff
114        0x2F, 0x2F, 0x61, 0x6E, 0x6F, 0x6E, 0x00, 0x00, // filename
115    ];
116
117    pub const CUSTOM_SAMPLE: &[u8] = &[
118        0x09, 0x00, 0x00, 0x00, // type (SAMPLE)
119        0x00, 0x00, // misc
120        0x48, 0x00, // size
121        0x10, 0x12, 0x33, 0x48, 0x99, 0x1A, 0x2B, 0x3C, // ip
122        0x02, 0x00, 0x00, 0x00, // pid
123        0x03, 0x00, 0x00, 0x00, // tid
124        0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // nr
125        0x01, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // stack1
126        0x02, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // stack2
127        0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // stack3
128        0x04, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // stack4
129        0xC9, 0x40, 0x65, 0x00, 0x00, 0x65, 0x40, 0xC9, // cgroup
130    ];
131}