1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
//! # linux-perf-event-reader
//!
//! This crate lets you parse Linux perf events and associated structures.
//!
//! ## Example
//!
//! ```rust
//! use std::io::Cursor;
//!
//! use linux_perf_event_reader::{PerfEventAttr, PerfEventHeader, RawData, RecordType};
//! use linux_perf_event_reader::records::{CommOrExecRecord, ParsedRecord, RawRecord, RecordParseInfo};
//!
//! # fn it_works() {
//! // Read the perf_event_attr data.
//! let attr_data = vec![
//!     0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, 3, 0, 0, 0, 0, 0, 0, 47, 177, 0,
//!     0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 183, 215, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
//!     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 15,
//!     255, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
//!     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 128, 0,
//!     0, 0, 0, 0, 0, 0,
//! ];
//! let mut attr_reader = Cursor::new(&attr_data);
//! let attr =
//!     PerfEventAttr::parse::<_, byteorder::LittleEndian>(&mut attr_reader, None).unwrap();
//! let parse_info = RecordParseInfo::from_attr(&attr);
//!
//! // Read the event record.
//! let header = PerfEventHeader {
//!     type_: 3,
//!     misc: 8192,
//!     size: 48,
//! };
//! let body = vec![
//!     108, 71, 8, 0, 108, 71, 8, 0, 100, 117, 109, 112, 95, 115, 121, 109, 115, 0, 0, 0, 0,
//!     0, 0, 0, 108, 71, 8, 0, 108, 71, 8, 0, 56, 27, 248, 24, 104, 88, 4, 0,
//! ];
//! let body_raw_data = RawData::from(&body[..]);
//! let raw_record = RawRecord::new(RecordType(header.type_), header.misc, body_raw_data);
//! let parsed_record = raw_record
//!     .parse::<byteorder::LittleEndian>(&parse_info)
//!     .unwrap();
//!
//! assert_eq!(
//!     parsed_record,
//!     ParsedRecord::Comm(CommOrExecRecord {
//!         pid: 542572,
//!         tid: 542572,
//!         name: RawData::Single(b"dump_syms"),
//!         is_execve: true
//!     })
//! );
//! # }
//! ```
pub mod consts;
mod perf_event;
mod raw_data;
pub mod records;
mod types;
mod utils;
pub use perf_event::*;
pub use raw_data::*;
pub use types::*;
#[cfg(test)]
mod test {
    use std::io::Cursor;
    use crate::{
        records::{CommOrExecRecord, ParsedRecord, RawRecord, RecordParseInfo},
        PerfEventAttr, PerfEventHeader, RawData, RecordType,
    };
    #[test]
    fn it_works() {
        // Read the perf_event_attr data.
        let attr_data = vec![
            0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, 3, 0, 0, 0, 0, 0, 0, 47, 177, 0,
            0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 183, 215, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 15,
            255, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 128, 0,
            0, 0, 0, 0, 0, 0,
        ];
        let mut attr_reader = Cursor::new(&attr_data);
        let attr =
            PerfEventAttr::parse::<_, byteorder::LittleEndian>(&mut attr_reader, None).unwrap();
        let parse_info = RecordParseInfo::from_attr(&attr);
        let header = PerfEventHeader {
            type_: 3,
            misc: 8192,
            size: 48,
        };
        let body = vec![
            108, 71, 8, 0, 108, 71, 8, 0, 100, 117, 109, 112, 95, 115, 121, 109, 115, 0, 0, 0, 0,
            0, 0, 0, 108, 71, 8, 0, 108, 71, 8, 0, 56, 27, 248, 24, 104, 88, 4, 0,
        ];
        let body_raw_data = RawData::from(&body[..]);
        let raw_record = RawRecord::new(RecordType(header.type_), header.misc, body_raw_data);
        let parsed_record = raw_record
            .parse::<byteorder::LittleEndian>(&parse_info)
            .unwrap();
        assert_eq!(
            parsed_record,
            ParsedRecord::Comm(CommOrExecRecord {
                pid: 542572,
                tid: 542572,
                name: RawData::Single(b"dump_syms"),
                is_execve: true
            })
        )
    }
}