Skip to content

Commit 07714b4

Browse files
committed
tracing: Handle old buffer mappings for event strings and functions
Use the saved text_delta and data_delta of a persistent memory mapped ring buffer that was saved from a previous boot, and use the delta in the trace event print output so that strings and functions show up normally. That is, for an event like trace_kmalloc() that prints the callsite via "%pS", if it used the address saved in the ring buffer it will not match the function that was saved in the previous boot if the kernel remaps itself between boots. For RCU events that point to saved static strings where only the address of the string is saved in the ring buffer, it too will be adjusted to point to where the string is on the current boot. Link: https://lkml.kernel.org/r/[email protected] Cc: Masami Hiramatsu <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Mathieu Desnoyers <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Vincent Donnefort <[email protected]> Cc: Joel Fernandes <[email protected]> Cc: Daniel Bristot de Oliveira <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Vineeth Pillai <[email protected]> Cc: Youssef Esmat <[email protected]> Cc: Beau Belgrave <[email protected]> Cc: Alexander Graf <[email protected]> Cc: Baoquan He <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: "Paul E. McKenney" <[email protected]> Cc: David Howells <[email protected]> Cc: Mike Rapoport <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Tony Luck <[email protected]> Cc: Guenter Roeck <[email protected]> Cc: Ross Zwisler <[email protected]> Cc: Kees Cook <[email protected]> Signed-off-by: Steven Rostedt (Google) <[email protected]>
1 parent 7a1d1e4 commit 07714b4

File tree

1 file changed

+39
-3
lines changed

1 file changed

+39
-3
lines changed

kernel/trace/trace.c

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3671,8 +3671,11 @@ static void test_can_verify(void)
36713671
void trace_check_vprintf(struct trace_iterator *iter, const char *fmt,
36723672
va_list ap)
36733673
{
3674+
long text_delta = iter->tr->text_delta;
3675+
long data_delta = iter->tr->data_delta;
36743676
const char *p = fmt;
36753677
const char *str;
3678+
bool good;
36763679
int i, j;
36773680

36783681
if (WARN_ON_ONCE(!fmt))
@@ -3691,7 +3694,10 @@ void trace_check_vprintf(struct trace_iterator *iter, const char *fmt,
36913694

36923695
j = 0;
36933696

3694-
/* We only care about %s and variants */
3697+
/*
3698+
* We only care about %s and variants
3699+
* as well as %p[sS] if delta is non-zero
3700+
*/
36953701
for (i = 0; p[i]; i++) {
36963702
if (i + 1 >= iter->fmt_size) {
36973703
/*
@@ -3720,6 +3726,11 @@ void trace_check_vprintf(struct trace_iterator *iter, const char *fmt,
37203726
}
37213727
if (p[i+j] == 's')
37223728
break;
3729+
3730+
if (text_delta && p[i+1] == 'p' &&
3731+
((p[i+2] == 's' || p[i+2] == 'S')))
3732+
break;
3733+
37233734
star = false;
37243735
}
37253736
j = 0;
@@ -3733,6 +3744,24 @@ void trace_check_vprintf(struct trace_iterator *iter, const char *fmt,
37333744
iter->fmt[i] = '\0';
37343745
trace_seq_vprintf(&iter->seq, iter->fmt, ap);
37353746

3747+
/* Add delta to %pS pointers */
3748+
if (p[i+1] == 'p') {
3749+
unsigned long addr;
3750+
char fmt[4];
3751+
3752+
fmt[0] = '%';
3753+
fmt[1] = 'p';
3754+
fmt[2] = p[i+2]; /* Either %ps or %pS */
3755+
fmt[3] = '\0';
3756+
3757+
addr = va_arg(ap, unsigned long);
3758+
addr += text_delta;
3759+
trace_seq_printf(&iter->seq, fmt, (void *)addr);
3760+
3761+
p += i + 3;
3762+
continue;
3763+
}
3764+
37363765
/*
37373766
* If iter->seq is full, the above call no longer guarantees
37383767
* that ap is in sync with fmt processing, and further calls
@@ -3751,6 +3780,14 @@ void trace_check_vprintf(struct trace_iterator *iter, const char *fmt,
37513780
/* The ap now points to the string data of the %s */
37523781
str = va_arg(ap, const char *);
37533782

3783+
good = trace_safe_str(iter, str, star, len);
3784+
3785+
/* Could be from the last boot */
3786+
if (data_delta && !good) {
3787+
str += data_delta;
3788+
good = trace_safe_str(iter, str, star, len);
3789+
}
3790+
37543791
/*
37553792
* If you hit this warning, it is likely that the
37563793
* trace event in question used %s on a string that
@@ -3760,8 +3797,7 @@ void trace_check_vprintf(struct trace_iterator *iter, const char *fmt,
37603797
* instead. See samples/trace_events/trace-events-sample.h
37613798
* for reference.
37623799
*/
3763-
if (WARN_ONCE(!trace_safe_str(iter, str, star, len),
3764-
"fmt: '%s' current_buffer: '%s'",
3800+
if (WARN_ONCE(!good, "fmt: '%s' current_buffer: '%s'",
37653801
fmt, seq_buf_str(&iter->seq.seq))) {
37663802
int ret;
37673803

0 commit comments

Comments
 (0)