Re: [RFC PATCH v3 4/5] perf data: Add --to-trace-dat option for converting perf.data tracepoint events into trace.dat format
[email protected] Mon, 03 Aug 2026 15:13:39 +0000
| Newsgroups | org.kernel.vger.linux-perf-users |
|---|---|
| Message-ID | <[email protected]> |
Thank you for your contribution! Sashiko AI review found 4 potential issue(= s) to consider: - [Medium] Memory leak of page_records and page_rec_sizes arrays when exten= d allocation fails. - [Medium] The --to-trace-dat conversion silently ignores the --time filter= ing option. - [Low] Missing explicit POSIX header inclusions in trace-dat.h and data-co= nvert-trace.c causes build failures on musl libc. - [Low] Missing dummy inline stub for trace_convert__perf2dat when HAVE_LIB= TRACEEVENT is absent. -- --- Patch [4]: [RFC PATCH v3 4/5] perf data: Add --to-trace-dat option for = converting perf.data tracepoint events into trace.dat format --- commit 3f0a7b06f263871cd1c6bbd15fd1c2bd5d454bae Author: Tanushree Shah <[email protected]> perf data: Add --to-trace-dat option for converting perf.data tracepoint ev= ents into trace.dat format This commit adds a new command-line option to perf data convert for generat= ing trace.dat output files. It provides a trace_convert__perf2dat function to handle tracepoint events and write them in a format compatible with trace-c= md and KernelShark. > diff --git a/tools/perf/util/data-convert-trace.c b/tools/perf/util/data-= convert-trace.c > new file mode 100644 > index 0000000000000..8dbdb2c9caa4f > --- /dev/null > +++ b/tools/perf/util/data-convert-trace.c > @@ -0,0 +1,241 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* > + * Copyright 2026, IBM Corporation > + * Author: Tanushree Shah <[email protected]> > + * > + * data-convert-trace.c > + * > + * Implements perf.data to trace.dat format conversion for tracepoint ev= ents. > + */ > + > +#include <errno.h> > +#include <inttypes.h> > +#include <fcntl.h> > +#include <string.h> > +#include <unistd.h> > +#include <linux/compiler.h> > +#include <linux/err.h> > + > +#include "data-convert.h" [ ... ] > +/* Convert perf.data tracepoint events to trace.dat format */ > +int trace_convert__perf2dat(const char *input, const char *to_trace, > + struct perf_data_convert_opts *opts) > +{ > + struct perf_session *session; [Severity: Medium] Does this function ignore the opts->time_str filtering option? In other for= mat conversions, the time parameter is parsed to filter samples within the spec= ified time ranges, but it appears to be unused here when converting to trace.dat. > + struct trace_convert tc =3D { > + .events_count =3D 0, > + }; [ ... ] > + if (!opts->force) { > + int fd =3D open(to_trace, O_WRONLY | O_CREAT | O_EXCL, 0644); > + > + if (fd < 0) { > + if (errno =3D=3D EEXIST) > + pr_err("Output file '%s' already exists. Use --force to overwrite.\n= ", > + to_trace); > + else > + pr_err("Failed to open output file '%s': %s\n", > + to_trace, strerror(errno)); > + return -errno; > + } > + trace_dat_fp =3D fdopen(fd, "wb"); [Severity: Low] Should <stdio.h> be explicitly included at the top of this file? Standard I= /O functions like fdopen() and fopen() are used here, which could cause build failures on musl libc without the direct header inclusion. > diff --git a/tools/perf/util/data-convert.h b/tools/perf/util/data-conver= t.h > index a96240f156712..f041c23252263 100644 > --- a/tools/perf/util/data-convert.h > +++ b/tools/perf/util/data-convert.h > @@ -19,4 +19,8 @@ int bt_convert__perf2ctf(const char *input_name, const = char *to_ctf, > int bt_convert__perf2json(const char *input_name, const char *to_ctf, > struct perf_data_convert_opts *opts); > =20 > +#ifdef HAVE_LIBTRACEEVENT > +int trace_convert__perf2dat(const char *input, const char *to_trace, > + struct perf_data_convert_opts *opts); > +#endif /* HAVE_LIBTRACEEVENT */ [Severity: Low] Is a dummy inline stub needed here for when HAVE_LIBTRACEEVENT is disabled? Without an #else block providing a fallback stub, it could cause future bui= ld failures if new callers are added that aren't guarded by the feature macro. > diff --git a/tools/perf/util/trace-dat.c b/tools/perf/util/trace-dat.c > new file mode 100644 > index 0000000000000..5598496c9a61c > --- /dev/null > +++ b/tools/perf/util/trace-dat.c [ ... ] > +static int trace_dat__write_cpu_dat(FILE *fp, struct tep_handle *pevent, > + int cpu, unsigned long long *file_offset_out) > +{ > + struct cpu_events *cpu_events =3D &trace_cpu_data[cpu]; [ ... ] > + for (i =3D 0; i < cpu_events->count; i++) { > + struct cpu_event *event =3D &cpu_events->events[i]; [ ... ] > + /* Emit TIME_EXTEND when delta does not fit in 27 bits */ > + if (time_delta > TRACE_DAT_RECORD_TIME_MASK) { > + unsigned int extend_hdr; > + unsigned int delta_upper; > + > + extend_size =3D TRACE_DAT_RECORD_TIME_EXTEND_SIZE; > + extend =3D calloc(1, extend_size); > + if (!extend) > + return -ENOMEM; [Severity: Medium] Can this early return cause a memory leak? If the allocation for extend fai= ls, returning -ENOMEM directly skips the out_free label at the end of the funct= ion, which is responsible for freeing the dynamically resized page_records and page_rec_sizes arrays. > diff --git a/tools/perf/util/trace-dat.h b/tools/perf/util/trace-dat.h > new file mode 100644 > index 0000000000000..b63d4e8c1e2d7 > --- /dev/null > +++ b/tools/perf/util/trace-dat.h > @@ -0,0 +1,113 @@ > +/* SPDX-License-Identifier: GPL-2.0-or-later */ [ ... ] > +#include <stdio.h> > +#include <stdbool.h> > +#include <event-parse.h> > +#include <byteswap.h> > +#include "util.h" > + > +/* trace.dat file format version */ > +#define TRACE_DAT_VERSION "7" [ ... ] > +static inline uint16_t to_file_u16(struct tep_handle *pevent, uint16_t v= al) > +{ > + return tep_read_number(pevent, &val, 2); > +} [Severity: Low] Does this file need to explicitly include <stdint.h> to ensure compatibility when compiling with musl libc? Fixed-width integer types like uint16_t are = used here but the standard POSIX header for them is missing. --=20 Sashiko AI review =C2=B7 https://sashiko.dev/#/patchset/20260803145958.2999= [email protected]?part=3D4