From: Steven Rostedt <rost...@goodmis.org>

The TP_printk() of a TRACE_EVENT() is a generic printf format that any
developer can create for their event. It may include pointers to strings
and such. A boot mapped buffer may contain data from a previous kernel
where the strings addresses are different.

One solution is to copy the event content and update the pointers by the
recorded delta, but a simpler solution (for now) is to just use the
print_fields() function to print these events. The print_fields() function
just iterates the fields and prints them according to what type they are,
and ignores the TP_printk() format from the event itself.

To understand the difference, when printing via TP_printk() the output
looks like this:

  4582.696626: kmem_cache_alloc: call_site=getname_flags+0x47/0x1f0 
ptr=00000000e70e10e0 bytes_req=4096 bytes_alloc=4096 gfp_flags=GFP_KERNEL 
node=-1 accounted=false
  4582.696629: kmem_cache_alloc: call_site=alloc_empty_file+0x6b/0x110 
ptr=0000000095808002 bytes_req=360 bytes_alloc=384 gfp_flags=GFP_KERNEL node=-1 
accounted=false
  4582.696630: kmem_cache_alloc: call_site=security_file_alloc+0x24/0x100 
ptr=00000000576339c3 bytes_req=16 bytes_alloc=16 
gfp_flags=GFP_KERNEL|__GFP_ZERO node=-1 accounted=false
  4582.696653: kmem_cache_free: call_site=do_sys_openat2+0xa7/0xd0 
ptr=00000000e70e10e0 name=names_cache

But when printing via print_fields() (echo 1 > 
/sys/kernel/tracing/options/fields)
the same event output looks like this:

  4582.696626: kmem_cache_alloc: call_site=0xffffffff92d10d97 (-1831793257) 
ptr=0xffff9e0e8571e000 (-107689771147264) bytes_req=0x1000 (4096) 
bytes_alloc=0x1000 (4096) gfp_flags=0xcc0 (3264) node=0xffffffff (-1) 
accounted=(0)
  4582.696629: kmem_cache_alloc: call_site=0xffffffff92d0250b (-1831852789) 
ptr=0xffff9e0e8577f800 (-107689770747904) bytes_req=0x168 (360) 
bytes_alloc=0x180 (384) gfp_flags=0xcc0 (3264) node=0xffffffff (-1) 
accounted=(0)
  4582.696630: kmem_cache_alloc: call_site=0xffffffff92efca74 (-1829778828) 
ptr=0xffff9e0e8d35d3b0 (-107689640864848) bytes_req=0x10 (16) bytes_alloc=0x10 
(16) gfp_flags=0xdc0 (3520) node=0xffffffff (-1) accounted=(0)
  4582.696653: kmem_cache_free: call_site=0xffffffff92cfbea7 (-1831879001) 
ptr=0xffff9e0e8571e000 (-107689771147264) name=names_cache

Cc: sta...@vger.kernel.org
Fixes: 07714b4bb3f98 ("tracing: Handle old buffer mappings for event strings 
and functions")
Signed-off-by: Steven Rostedt (Google) <rost...@goodmis.org>
---
Changes since v1: 
https://lore.kernel.org/all/20241217173520.658174...@goodmis.org/

- Do not update print_field() with text_delta offset.

 kernel/trace/trace.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index be62f0ea1814..6581cb2bc67f 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -4353,6 +4353,15 @@ static enum print_line_t print_trace_fmt(struct 
trace_iterator *iter)
        if (event) {
                if (tr->trace_flags & TRACE_ITER_FIELDS)
                        return print_event_fields(iter, event);
+               /*
+                * For TRACE_EVENT() events, the print_fmt is not
+                * safe to use if the array has delta offsets
+                * Force printing via the fields.
+                */
+               if ((tr->text_delta || tr->data_delta) &&
+                   event->type > __TRACE_LAST_TYPE)
+                       return print_event_fields(iter, event);
+
                return event->funcs->trace(iter, sym_flags, event);
        }
 
-- 
2.45.2


Reply via email to