diff options
author | Steven Rostedt <srostedt@redhat.com> | 2009-03-16 19:20:15 -0400 |
---|---|---|
committer | Steven Rostedt <srostedt@redhat.com> | 2009-03-16 23:27:06 -0400 |
commit | 4ca530852346be239b7c19e7bec5d2b78855bebe (patch) | |
tree | 96e5252faaf362115a96ed6df7c4e4f698a027dc /kernel/trace/trace_output.c | |
parent | 03303549b1695dc024d4a653cc16bd79f78f9750 (diff) |
tracing: protect reader of cmdline output
Impact: fix to one cause of incorrect comm outputs in trace
The spinlock only protected the creation of a comm <=> pid pair.
But it was possible that a reader could look up a pid, and get the
wrong comm because it had no locking.
This also required changing trace_find_cmdline to copy the comm cache
and not just send back a pointer to it.
Signed-off-by: Steven Rostedt <srostedt@redhat.com>
Diffstat (limited to 'kernel/trace/trace_output.c')
-rw-r--r-- | kernel/trace/trace_output.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index ea9d3b410c7a..6a4c9dea191e 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c | |||
@@ -309,9 +309,9 @@ static int | |||
309 | lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu) | 309 | lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu) |
310 | { | 310 | { |
311 | int hardirq, softirq; | 311 | int hardirq, softirq; |
312 | char *comm; | 312 | char comm[TASK_COMM_LEN]; |
313 | 313 | ||
314 | comm = trace_find_cmdline(entry->pid); | 314 | trace_find_cmdline(entry->pid, comm); |
315 | hardirq = entry->flags & TRACE_FLAG_HARDIRQ; | 315 | hardirq = entry->flags & TRACE_FLAG_HARDIRQ; |
316 | softirq = entry->flags & TRACE_FLAG_SOFTIRQ; | 316 | softirq = entry->flags & TRACE_FLAG_SOFTIRQ; |
317 | 317 | ||
@@ -346,10 +346,12 @@ int trace_print_context(struct trace_iterator *iter) | |||
346 | { | 346 | { |
347 | struct trace_seq *s = &iter->seq; | 347 | struct trace_seq *s = &iter->seq; |
348 | struct trace_entry *entry = iter->ent; | 348 | struct trace_entry *entry = iter->ent; |
349 | char *comm = trace_find_cmdline(entry->pid); | ||
350 | unsigned long long t = ns2usecs(iter->ts); | 349 | unsigned long long t = ns2usecs(iter->ts); |
351 | unsigned long usec_rem = do_div(t, USEC_PER_SEC); | 350 | unsigned long usec_rem = do_div(t, USEC_PER_SEC); |
352 | unsigned long secs = (unsigned long)t; | 351 | unsigned long secs = (unsigned long)t; |
352 | char comm[TASK_COMM_LEN]; | ||
353 | |||
354 | trace_find_cmdline(entry->pid, comm); | ||
353 | 355 | ||
354 | return trace_seq_printf(s, "%16s-%-5d [%03d] %5lu.%06lu: ", | 356 | return trace_seq_printf(s, "%16s-%-5d [%03d] %5lu.%06lu: ", |
355 | comm, entry->pid, iter->cpu, secs, usec_rem); | 357 | comm, entry->pid, iter->cpu, secs, usec_rem); |
@@ -372,7 +374,10 @@ int trace_print_lat_context(struct trace_iterator *iter) | |||
372 | rel_usecs = ns2usecs(next_ts - iter->ts); | 374 | rel_usecs = ns2usecs(next_ts - iter->ts); |
373 | 375 | ||
374 | if (verbose) { | 376 | if (verbose) { |
375 | char *comm = trace_find_cmdline(entry->pid); | 377 | char comm[TASK_COMM_LEN]; |
378 | |||
379 | trace_find_cmdline(entry->pid, comm); | ||
380 | |||
376 | ret = trace_seq_printf(s, "%16s %5d %3d %d %08x %08lx [%08lx]" | 381 | ret = trace_seq_printf(s, "%16s %5d %3d %d %08x %08lx [%08lx]" |
377 | " %ld.%03ldms (+%ld.%03ldms): ", comm, | 382 | " %ld.%03ldms (+%ld.%03ldms): ", comm, |
378 | entry->pid, iter->cpu, entry->flags, | 383 | entry->pid, iter->cpu, entry->flags, |
@@ -577,14 +582,15 @@ static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter, | |||
577 | char *delim) | 582 | char *delim) |
578 | { | 583 | { |
579 | struct ctx_switch_entry *field; | 584 | struct ctx_switch_entry *field; |
580 | char *comm; | 585 | char comm[TASK_COMM_LEN]; |
581 | int S, T; | 586 | int S, T; |
582 | 587 | ||
588 | |||
583 | trace_assign_type(field, iter->ent); | 589 | trace_assign_type(field, iter->ent); |
584 | 590 | ||
585 | T = task_state_char(field->next_state); | 591 | T = task_state_char(field->next_state); |
586 | S = task_state_char(field->prev_state); | 592 | S = task_state_char(field->prev_state); |
587 | comm = trace_find_cmdline(field->next_pid); | 593 | trace_find_cmdline(field->next_pid, comm); |
588 | if (!trace_seq_printf(&iter->seq, | 594 | if (!trace_seq_printf(&iter->seq, |
589 | " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n", | 595 | " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n", |
590 | field->prev_pid, | 596 | field->prev_pid, |