* [PATCH v3 0/2] libtracecmd: Support changing /proc/kallsyms
@ 2025-07-11 13:25 Ilya Leoshkevich
2025-07-11 13:25 ` [PATCH v3 1/2] libtracecmd: Support querying position within a new compressed block Ilya Leoshkevich
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Ilya Leoshkevich @ 2025-07-11 13:25 UTC (permalink / raw)
To: Steven Rostedt
Cc: linux-trace-devel, Heiko Carstens, Vasily Gorbik,
Alexander Gordeev, Ilya Leoshkevich
v2: https://lore.kernel.org/linux-trace-devel/20250602214154.446881-1-iii@linux.ibm.com/
v2 -> v3: Add a comment and some newlines (Steven).
v1: https://lore.kernel.org/linux-trace-devel/20250416231325.14113-1-iii@linux.ibm.com/
v1 -> v2: Rewrite the size instead of reading the file twice (Steven).
Turns out exposing do_lseek() is not necessary, since
everything is in the same C file.
Hi,
this series fixes tracing in presence of frequent BPF or kernel module
loads/unloads. Patch 1 is a small required improvement; patch 2 is the
actual implementation.
The problem can be reproduced like this:
# while true; do rmmod loop; modprobe loop; done &
# while trace-cmd record -p function_graph /bin/true; do :; done
plugin 'function_graph'
libtracecmd: Invalid argument
error in size of file '/proc/kallsyms'
trace-cmd: Invalid argument
Error creating output file
Best regards,
Ilya
Ilya Leoshkevich (2):
libtracecmd: Support querying position within a new compressed block
libtracecmd: Support changing /proc/kallsyms
lib/trace-cmd/trace-compress.c | 5 ++++-
lib/trace-cmd/trace-output.c | 38 +++++++++++++++++++++++++++++++++-
2 files changed, 41 insertions(+), 2 deletions(-)
--
2.50.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v3 1/2] libtracecmd: Support querying position within a new compressed block
2025-07-11 13:25 [PATCH v3 0/2] libtracecmd: Support changing /proc/kallsyms Ilya Leoshkevich
@ 2025-07-11 13:25 ` Ilya Leoshkevich
2025-07-11 13:25 ` [PATCH v3 2/2] libtracecmd: Support changing /proc/kallsyms Ilya Leoshkevich
2025-08-11 8:22 ` [PATCH v3 0/2] " Ilya Leoshkevich
2 siblings, 0 replies; 4+ messages in thread
From: Ilya Leoshkevich @ 2025-07-11 13:25 UTC (permalink / raw)
To: Steven Rostedt
Cc: linux-trace-devel, Heiko Carstens, Vasily Gorbik,
Alexander Gordeev, Ilya Leoshkevich
tracecmd_compress_lseek() refuses to return position within a new
block, because handle->buffer is NULL. Add support for this; do not
implement actually seeking within a new block, because this is not
required at the moment.
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
lib/trace-cmd/trace-compress.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/lib/trace-cmd/trace-compress.c b/lib/trace-cmd/trace-compress.c
index 2a7a3e24..3e10cf5b 100644
--- a/lib/trace-cmd/trace-compress.c
+++ b/lib/trace-cmd/trace-compress.c
@@ -132,9 +132,12 @@ off_t tracecmd_compress_lseek(struct tracecmd_compression *handle, off_t offset,
{
unsigned long p;
- if (!handle || !handle->buffer)
+ if (!handle)
return (off_t)-1;
+ if (!handle->buffer)
+ return (whence == SEEK_CUR && offset == 0) ? 0 : (off_t)-1;
+
switch (whence) {
case SEEK_CUR:
p = handle->pointer + offset;
--
2.50.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v3 2/2] libtracecmd: Support changing /proc/kallsyms
2025-07-11 13:25 [PATCH v3 0/2] libtracecmd: Support changing /proc/kallsyms Ilya Leoshkevich
2025-07-11 13:25 ` [PATCH v3 1/2] libtracecmd: Support querying position within a new compressed block Ilya Leoshkevich
@ 2025-07-11 13:25 ` Ilya Leoshkevich
2025-08-11 8:22 ` [PATCH v3 0/2] " Ilya Leoshkevich
2 siblings, 0 replies; 4+ messages in thread
From: Ilya Leoshkevich @ 2025-07-11 13:25 UTC (permalink / raw)
To: Steven Rostedt
Cc: linux-trace-devel, Heiko Carstens, Vasily Gorbik,
Alexander Gordeev, Ilya Leoshkevich
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.
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
lib/trace-cmd/trace-output.c | 38 +++++++++++++++++++++++++++++++++++-
1 file changed, 37 insertions(+), 1 deletion(-)
diff --git a/lib/trace-cmd/trace-output.c b/lib/trace-cmd/trace-output.c
index c333553e..b981baf3 100644
--- a/lib/trace-cmd/trace-output.c
+++ b/lib/trace-cmd/trace-output.c
@@ -577,6 +577,39 @@ __hidden int tcmd_out_update_section_header(struct tracecmd_output *handle, tsiz
return 0;
}
+/*
+ * For files that can change while reading them (like /proc/kallsyms) the
+ * normal "size != check_size" can fail. That's because from the time the file
+ * size is determined and written into the output to the time the actual data
+ * is copied into the output, the size can change. In this case, the size that
+ * was stored in the output needs to be updated.
+ */
+static int update_endian_4(struct tracecmd_output *handle,
+ off_t offset, int val)
+{
+ tsize_t current;
+ int endian4;
+
+ if (offset == (off_t)-1)
+ return -1;
+
+ current = do_lseek(handle, 0, SEEK_CUR);
+ if (current == (off_t)-1)
+ return -1;
+
+ if (do_lseek(handle, offset, SEEK_SET) == (off_t)-1)
+ return -1;
+
+ endian4 = convert_endian_4(handle, val);
+ if (tcmd_do_write_check(handle, &endian4, 4))
+ return -1;
+
+ if (do_lseek(handle, current, SEEK_SET) == (off_t)-1)
+ return -1;
+
+ return 0;
+}
+
static int save_string_section(struct tracecmd_output *handle, bool compress)
{
enum tracecmd_section_flags flags = 0;
@@ -1135,6 +1168,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;
@@ -1166,13 +1200,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 &&
+ update_endian_4(handle, size_offset, check_size)) {
errno = EINVAL;
tracecmd_warning("error in size of file '%s'", path);
set_proc_kptr_restrict(1);
--
2.50.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v3 0/2] libtracecmd: Support changing /proc/kallsyms
2025-07-11 13:25 [PATCH v3 0/2] libtracecmd: Support changing /proc/kallsyms Ilya Leoshkevich
2025-07-11 13:25 ` [PATCH v3 1/2] libtracecmd: Support querying position within a new compressed block Ilya Leoshkevich
2025-07-11 13:25 ` [PATCH v3 2/2] libtracecmd: Support changing /proc/kallsyms Ilya Leoshkevich
@ 2025-08-11 8:22 ` Ilya Leoshkevich
2 siblings, 0 replies; 4+ messages in thread
From: Ilya Leoshkevich @ 2025-08-11 8:22 UTC (permalink / raw)
To: Steven Rostedt
Cc: linux-trace-devel, Heiko Carstens, Vasily Gorbik,
Alexander Gordeev
On Fri, 2025-07-11 at 15:25 +0200, Ilya Leoshkevich wrote:
> v2:
> https://lore.kernel.org/linux-trace-devel/20250602214154.446881-1-iii@linux.ibm.com/
> v2 -> v3: Add a comment and some newlines (Steven).
>
> v1:
> https://lore.kernel.org/linux-trace-devel/20250416231325.14113-1-iii@linux.ibm.com/
> v1 -> v2: Rewrite the size instead of reading the file twice
> (Steven).
> Turns out exposing do_lseek() is not necessary, since
> everything is in the same C file.
>
> Hi,
>
> this series fixes tracing in presence of frequent BPF or kernel
> module
> loads/unloads. Patch 1 is a small required improvement; patch 2 is
> the
> actual implementation.
>
> The problem can be reproduced like this:
>
> # while true; do rmmod loop; modprobe loop; done &
>
> # while trace-cmd record -p function_graph /bin/true; do :; done
> plugin 'function_graph'
> libtracecmd: Invalid argument
> error in size of file '/proc/kallsyms'
> trace-cmd: Invalid argument
> Error creating output file
>
> Best regards,
> Ilya
>
> Ilya Leoshkevich (2):
> libtracecmd: Support querying position within a new compressed
> block
> libtracecmd: Support changing /proc/kallsyms
>
> lib/trace-cmd/trace-compress.c | 5 ++++-
> lib/trace-cmd/trace-output.c | 38
> +++++++++++++++++++++++++++++++++-
> 2 files changed, 41 insertions(+), 2 deletions(-)
Gentle ping.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-08-11 8:22 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-11 13:25 [PATCH v3 0/2] libtracecmd: Support changing /proc/kallsyms Ilya Leoshkevich
2025-07-11 13:25 ` [PATCH v3 1/2] libtracecmd: Support querying position within a new compressed block Ilya Leoshkevich
2025-07-11 13:25 ` [PATCH v3 2/2] libtracecmd: Support changing /proc/kallsyms Ilya Leoshkevich
2025-08-11 8:22 ` [PATCH v3 0/2] " Ilya Leoshkevich
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).