From: Stefan Hajnoczi <stefanha@redhat.com>
To: Zhao Liu <zhao1.liu@intel.com>
Cc: "Mads Ynddal" <mads@ynddal.dk>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Peter Maydell" <peter.maydell@linaro.org>,
"Alex Bennée" <alex.bennee@linaro.org>,
"Daniel P . Berrangé" <berrange@redhat.com>,
"Thomas Huth" <thuth@redhat.com>,
"Markus Armbruster" <armbru@redhat.com>,
qemu-devel@nongnu.org
Subject: Re: [RFC 3/6] scripts/simpletrace-rust: Add helpers to parse trace file
Date: Mon, 27 May 2024 16:39:38 -0400 [thread overview]
Message-ID: <20240527203938.GD913874@fedora.redhat.com> (raw)
In-Reply-To: <20240527081421.2258624-4-zhao1.liu@intel.com>
[-- Attachment #1: Type: text/plain, Size: 5323 bytes --]
On Mon, May 27, 2024 at 04:14:18PM +0800, Zhao Liu wrote:
> Refer to scripts/simpletrace.py, add the helpers to read the trace file
> and parse the record type field, record header and log header.
>
> Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
> Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
> ---
> scripts/simpletrace-rust/src/main.rs | 151 +++++++++++++++++++++++++++
> 1 file changed, 151 insertions(+)
>
> diff --git a/scripts/simpletrace-rust/src/main.rs b/scripts/simpletrace-rust/src/main.rs
> index 2d2926b7658d..b3b8baee7c66 100644
> --- a/scripts/simpletrace-rust/src/main.rs
> +++ b/scripts/simpletrace-rust/src/main.rs
> @@ -14,21 +14,172 @@
> mod trace;
>
> use std::env;
> +use std::fs::File;
> +use std::io::Error as IOError;
> +use std::io::ErrorKind;
> +use std::io::Read;
>
> use clap::Arg;
> use clap::Command;
> use thiserror::Error;
> use trace::Event;
>
> +const RECORD_TYPE_MAPPING: u64 = 0;
> +const RECORD_TYPE_EVENT: u64 = 1;
> +
> #[derive(Error, Debug)]
> pub enum Error
> {
> #[error("usage: {0} [--no-header] <trace-events> <trace-file>")]
> CliOptionUnmatch(String),
> + #[error("Failed to read file: {0}")]
> + ReadFile(IOError),
> + #[error("Unknown record type ({0})")]
> + UnknownRecType(u64),
> }
>
> pub type Result<T> = std::result::Result<T, Error>;
>
> +enum RecordType
> +{
> + Empty,
> + Mapping,
> + Event,
> +}
> +
> +#[repr(C)]
> +#[derive(Clone, Copy, Default)]
> +struct RecordRawType
> +{
> + rtype: u64,
> +}
> +
> +impl RecordType
> +{
> + fn read_type(mut fobj: &File) -> Result<RecordType>
> + {
> + let mut tbuf = [0u8; 8];
> + if let Err(e) = fobj.read_exact(&mut tbuf) {
> + if e.kind() == ErrorKind::UnexpectedEof {
> + return Ok(RecordType::Empty);
> + } else {
> + return Err(Error::ReadFile(e));
> + }
> + }
> +
> + /*
> + * Safe because the layout of the trace record requires us to parse
> + * the type first, and then there is a check on the validity of the
> + * record type.
> + */
> + let raw_t =
> + unsafe { std::mem::transmute::<[u8; 8], RecordRawType>(tbuf) };
A safe alternative: https://doc.rust-lang.org/std/primitive.u64.html#method.from_ne_bytes?
> + match raw_t.rtype {
> + RECORD_TYPE_MAPPING => Ok(RecordType::Mapping),
> + RECORD_TYPE_EVENT => Ok(RecordType::Event),
> + _ => Err(Error::UnknownRecType(raw_t.rtype)),
> + }
> + }
> +}
> +
> +trait ReadHeader
> +{
> + fn read_header(fobj: &File) -> Result<Self>
> + where
> + Self: Sized;
> +}
> +
> +#[repr(C)]
> +#[derive(Clone, Copy)]
> +struct LogHeader
> +{
> + event_id: u64,
> + magic: u64,
> + version: u64,
> +}
> +
> +impl ReadHeader for LogHeader
> +{
> + fn read_header(mut fobj: &File) -> Result<Self>
> + {
> + let mut raw_hdr = [0u8; 24];
> + fobj.read_exact(&mut raw_hdr).map_err(Error::ReadFile)?;
> +
> + /*
> + * Safe because the size of log header (struct LogHeader)
> + * is 24 bytes, which is ensured by simple trace backend.
> + */
> + let hdr =
> + unsafe { std::mem::transmute::<[u8; 24], LogHeader>(raw_hdr) };
Or u64::from_ne_bytes() for each field.
> + Ok(hdr)
> + }
> +}
> +
> +#[derive(Default)]
> +struct RecordInfo
> +{
> + event_id: u64,
> + timestamp_ns: u64,
> + record_pid: u32,
> + args_payload: Vec<u8>,
> +}
> +
> +impl RecordInfo
> +{
> + fn new() -> Self
> + {
> + Default::default()
> + }
> +}
> +
> +#[repr(C)]
> +#[derive(Clone, Copy)]
> +struct RecordHeader
> +{
> + event_id: u64,
> + timestamp_ns: u64,
> + record_length: u32,
> + record_pid: u32,
> +}
> +
> +impl RecordHeader
> +{
> + fn extract_record(&self, mut fobj: &File) -> Result<RecordInfo>
> + {
> + let mut info = RecordInfo::new();
> +
> + info.event_id = self.event_id;
> + info.timestamp_ns = self.timestamp_ns;
> + info.record_pid = self.record_pid;
> + info.args_payload = vec![
> + 0u8;
> + self.record_length as usize
> + - std::mem::size_of::<RecordHeader>()
> + ];
> + fobj.read_exact(&mut info.args_payload)
> + .map_err(Error::ReadFile)?;
> +
> + Ok(info)
> + }
> +}
> +
> +impl ReadHeader for RecordHeader
> +{
> + fn read_header(mut fobj: &File) -> Result<Self>
> + {
> + let mut raw_hdr = [0u8; 24];
> + fobj.read_exact(&mut raw_hdr).map_err(Error::ReadFile)?;
> +
> + /*
> + * Safe because the size of record header (struct RecordHeader)
> + * is 24 bytes, which is ensured by simple trace backend.
> + */
> + let hdr: RecordHeader =
> + unsafe { std::mem::transmute::<[u8; 24], RecordHeader>(raw_hdr) };
Or u64::from_ne_bytes() and u32::from_ne_bytes() for all fields.
> + Ok(hdr)
> + }
> +}
> +
> pub struct EventArgPayload {}
>
> trait Analyzer
> --
> 2.34.1
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
next prev parent reply other threads:[~2024-05-27 20:40 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-27 8:14 [RFC 0/6] scripts: Rewrite simpletrace printer in Rust Zhao Liu
2024-05-27 8:14 ` [RFC 1/6] scripts/simpletrace-rust: Add the basic cargo framework Zhao Liu
2024-05-27 20:05 ` Stefan Hajnoczi
2024-05-28 7:53 ` Zhao Liu
2024-05-28 14:14 ` Stefan Hajnoczi
2024-05-29 14:30 ` Zhao Liu
2024-05-29 18:41 ` Stefan Hajnoczi
2024-05-31 12:22 ` Daniel P. Berrangé
2024-05-27 8:14 ` [RFC 2/6] scripts/simpletrace-rust: Support Event & Arguments in trace module Zhao Liu
2024-05-27 20:33 ` Stefan Hajnoczi
2024-05-28 8:32 ` Zhao Liu
2024-05-27 8:14 ` [RFC 3/6] scripts/simpletrace-rust: Add helpers to parse trace file Zhao Liu
2024-05-27 20:39 ` Stefan Hajnoczi [this message]
2024-05-28 8:37 ` Zhao Liu
2024-05-27 8:14 ` [RFC 4/6] scripts/simpletrace-rust: Parse and check trace recode file Zhao Liu
2024-05-27 20:44 ` Stefan Hajnoczi
2024-05-28 9:30 ` Zhao Liu
2024-05-27 8:14 ` [RFC 5/6] scripts/simpletrace-rust: Format simple trace output Zhao Liu
2024-05-27 8:14 ` [RFC 6/6] docs/tracing: Add simpletrace-rust section Zhao Liu
2024-05-27 10:29 ` [RFC 0/6] scripts: Rewrite simpletrace printer in Rust Philippe Mathieu-Daudé
2024-05-27 10:49 ` Mads Ynddal
2024-05-28 6:15 ` Zhao Liu
2024-05-27 19:59 ` Stefan Hajnoczi
2024-05-28 6:48 ` Zhao Liu
2024-05-28 13:05 ` Stefan Hajnoczi
2024-05-29 9:33 ` Mads Ynddal
2024-05-29 14:10 ` Zhao Liu
2024-05-29 18:44 ` Stefan Hajnoczi
2024-05-31 12:27 ` Daniel P. Berrangé
2024-05-31 14:55 ` Alex Bennée
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240527203938.GD913874@fedora.redhat.com \
--to=stefanha@redhat.com \
--cc=alex.bennee@linaro.org \
--cc=armbru@redhat.com \
--cc=berrange@redhat.com \
--cc=mads@ynddal.dk \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=thuth@redhat.com \
--cc=zhao1.liu@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.