diff --git a/.github/workflows/cargo.yml b/.github/workflows/cargo.yml index a4c0ff8..97c03f2 100644 --- a/.github/workflows/cargo.yml +++ b/.github/workflows/cargo.yml @@ -19,7 +19,7 @@ jobs: - name: cargo test shell: bash - run: cargo test + run: cargo test --all-features rustfmt: runs-on: ubuntu-latest diff --git a/src/config.rs b/src/config.rs index 8d623de..857e247 100644 --- a/src/config.rs +++ b/src/config.rs @@ -138,6 +138,13 @@ impl ParseConfig { self } + #[allow(dead_code)] + /// Used for testing, please open an issue if you need this. + pub(crate) fn with_read_format(mut self, read_format: ReadFormat) -> Self { + self.config.config_flags.set_read_format(read_format); + self + } + pub(crate) fn with_misc(mut self, misc: u16) -> Self { self.config.config_flags.set_misc(misc); self diff --git a/src/records/sample.rs b/src/records/sample.rs index b7f24d4..2ee1717 100644 --- a/src/records/sample.rs +++ b/src/records/sample.rs @@ -47,6 +47,7 @@ mod sample_impl { #[debug(with = crate::util::fmt::HexAddr)] pub phys_addr: u64, pub aux: Cow<'a, [u8]>, + pub cgroup: u64, pub data_page_size: u64, pub code_page_size: u64 } @@ -152,6 +153,10 @@ impl<'a> Sample<'a> { self.0.aux().map(|cow| &**cow) } + pub fn cgroup(&self) -> Option { + self.0.cgroup().copied() + } + pub fn data_page_size(&self) -> Option { self.0.data_page_size().copied() } @@ -246,12 +251,13 @@ impl<'p> Parse<'p> for Sample<'p> { Registers::parse_intr(p) })?; let phys_addr = p.parse_if(sty.contains(SampleFlags::PHYS_ADDR))?; + let cgroup = p.parse_if(sty.contains(SampleFlags::CGROUP))?; + let data_page_size = p.parse_if(sty.contains(SampleFlags::DATA_PAGE_SIZE))?; + let code_page_size = p.parse_if(sty.contains(SampleFlags::CODE_PAGE_SIZE))?; let aux = p.parse_if_with(sty.contains(SampleFlags::AUX), |p| { let size = p.parse_u64()? as usize; p.parse_bytes(size) })?; - let data_page_size = p.parse_if(sty.contains(SampleFlags::DATA_PAGE_SIZE))?; - let code_page_size = p.parse_if(sty.contains(SampleFlags::CODE_PAGE_SIZE))?; Ok(Self(sample_impl::Sample::new( ip, @@ -276,6 +282,7 @@ impl<'p> Parse<'p> for Sample<'p> { regs_intr, phys_addr, aux, + cgroup, data_page_size, code_page_size, ))) @@ -762,4 +769,42 @@ mod tests { assert_eq!(sample.cpu(), None); assert_eq!(sample.time(), None); } + + #[test] + fn parse_sample_with_cgroup() { + #[rustfmt::skip] + let data: &[u8] = &[ + 0xd4, 0x08, 0x00, 0x00, 0xd4, 0x08, 0x00, 0x00, + 0xc9, 0x77, 0x8e, 0xa1, 0x3a, 0xa4, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xd0, 0xbe, 0xc0, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xac, 0x79, 0xc0, 0x28, 0x00, 0x00, 0x00, 0x00, + 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]; + + let config: ParseConfig = ParseConfig::default() + .with_sample_type( + SampleFlags::TID + | SampleFlags::CGROUP + | SampleFlags::READ + | SampleFlags::TIME + | SampleFlags::CPU, + ) + .with_read_format(ReadFormat::GROUP | ReadFormat::TOTAL_TIME_ENABLED); + let sample: Sample = Parser::new(data, config).parse().unwrap(); + + assert_eq!(sample.pid(), Some(0x08d4)); + assert_eq!(sample.tid(), Some(0x08d4)); + assert_eq!(sample.time(), Some(0xA43AA18E77C9)); + assert_eq!(sample.cpu(), Some(0)); + + let group = sample.values().unwrap(); + assert_eq!(group.len(), 2); + + assert_eq!(sample.cgroup(), Some(1)); + } }