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, |
