Re: [PATCH v2 2/2] libtracecmd: Support changing /proc/kallsyms
Steven Rostedt <[email protected]> Tue, 8 Jul 2025 14:24:27 -0400
| Newsgroups | org.kernel.vger.linux-trace-devel |
|---|---|
| Message-ID | <[email protected]> |
Sorry for the late reply, been way too busy on the kernel side. On Mon, 2 Jun 2025 22:38:33 +0100 Ilya Leoshkevich <[email protected]> wrote: > Running BPF selftests under trace-cmd intermittently fails with: > > error in size of file '/proc/kallsyms' > > This is because these selftests load and unload BPF programs. > bpf_prog_put() uses workqueues and RCU, so these programs disappear > from /proc/kallsyms after a delay. > > trace-cmd reads /proc/kallsyms twice: the first time to compute its > size, and the second time to copy it into the trace file. If the > resulting sizes don't match, which is what happens in this case, > recording fails. > > Fix by updating the size. This will work even for sending trace data > over the network thanks to trace_msg_cache. I'm perfectly fine with the logic, just some nits about the patch. Could you send a v3? Comments below. > > Signed-off-by: Ilya Leoshkevich <[email protected]> > --- > lib/trace-cmd/trace-output.c | 26 +++++++++++++++++++++++++- > 1 file changed, 25 insertions(+), 1 deletion(-) > > diff --git a/lib/trace-cmd/trace-output.c b/lib/trace-cmd/trace-output.c > index 00b87a19..e9ec8f51 100644 > --- a/lib/trace-cmd/trace-output.c > +++ b/lib/trace-cmd/trace-output.c > @@ -577,6 +577,27 @@ __hidden int tcmd_out_update_section_header(struct tracecmd_output *handle, tsiz > return 0; > } > Needs a comment here: /* * For files that can change while reading it (like /proc/kallsyms) the * normal "size != check_size" can fail. That's because from the time * the file size is read to write in the size to the time it is read to copy * it into the file, it can change. In this case, the size that was stored * in the file needs to be updated. */ > +static int tcmd_out_update_endian_4(struct tracecmd_output *handle, > + off_t offset, int val) This is a static function, it doesn't need the "tcmd_" prefix. That should be reserved for global functions that are "__hidden". > +{ > + tsize_t current; > + int endian4; > + > + if (offset == (off_t)-1) > + return -1; Add newline here. > + current = do_lseek(handle, 0, SEEK_CUR); > + if (current == (off_t)-1) > + return -1; And here. > + if (do_lseek(handle, offset, SEEK_SET) == (off_t)-1) > + return -1; And here. > + endian4 = convert_endian_4(handle, val); > + if (tcmd_do_write_check(handle, &endian4, 4)) > + return -1; And here. > + if (do_lseek(handle, current, SEEK_SET) == (off_t)-1) > + return -1; And here. Other than that, looks good. -- Steve > + return 0; > +} > + > static int save_string_section(struct tracecmd_output *handle, bool compress) > { > enum tracecmd_section_flags flags = 0; > @@ -1134,6 +1155,7 @@ static int read_proc_kallsyms(struct tracecmd_output *handle, bool compress) > enum tracecmd_section_flags flags = 0; > unsigned int size, check_size, endian4; > const char *path = "/proc/kallsyms"; > + off_t size_offset; > tsize_t offset; > struct stat st; > int ret; > @@ -1165,13 +1187,15 @@ static int read_proc_kallsyms(struct tracecmd_output *handle, bool compress) > } > size = get_size(path); > endian4 = convert_endian_4(handle, size); > + size_offset = do_lseek(handle, 0, SEEK_CUR); > ret = tcmd_do_write_check(handle, &endian4, 4); > if (ret) > goto out; > > set_proc_kptr_restrict(0); > check_size = copy_file(handle, path); > - if (size != check_size) { > + if (size != check_size && > + tcmd_out_update_endian_4(handle, size_offset, check_size)) { > errno = EINVAL; > tracecmd_warning("error in size of file '%s'", path); > set_proc_kptr_restrict(1);