Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 121187
b: refs/heads/master
c: b54d3de
h: refs/heads/master
i:
  121185: 5e8555c
  121183: 36c8940
v: v3
  • Loading branch information
Török Edwin authored and Ingo Molnar committed Nov 23, 2008
1 parent fb9657b commit ab52367
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 74e2f334f4440cbcb63e9ebbcdcea430d41bdfa3
refs/heads/master: b54d3de9f3b8956653b06f1a32e9f9321c6d9027
13 changes: 12 additions & 1 deletion trunk/Documentation/ftrace.txt
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ output. To see what is available, simply cat the file:

cat /debug/tracing/trace_options
print-parent nosym-offset nosym-addr noverbose noraw nohex nobin \
noblock nostacktrace nosched-tree nouserstacktrace
noblock nostacktrace nosched-tree nouserstacktrace nosym-userobj

To disable one of the options, echo in the option prepended with "no".

Expand Down Expand Up @@ -381,6 +381,17 @@ Here are the available options:
userstacktrace - This option changes the trace.
It records a stacktrace of the current userspace thread.

sym-userobj - when user stacktrace are enabled, look up which object the
address belongs to, and print a relative address
This is especially useful when ASLR is on, otherwise you don't
get a chance to resolve the address to object/file/line after the app is no
longer running

The lookup is performed when you read trace,trace_pipe,latency_trace. Example:

a.out-1623 [000] 40874.465068: /root/a.out[+0x480] <-/root/a.out[+0
x494] <- /root/a.out[+0x4a8] <- /lib/libc-2.7.so[+0x1e1a6]

sched-tree - TBD (any users??)


Expand Down
86 changes: 79 additions & 7 deletions trunk/kernel/trace/trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <linux/gfp.h>
#include <linux/fs.h>
#include <linux/kprobes.h>
#include <linux/seq_file.h>
#include <linux/writeback.h>

#include <linux/stacktrace.h>
Expand Down Expand Up @@ -276,6 +277,7 @@ static const char *trace_options[] = {
"branch",
"annotate",
"userstacktrace",
"sym-userobj",
NULL
};

Expand Down Expand Up @@ -422,6 +424,28 @@ trace_seq_putmem_hex(struct trace_seq *s, void *mem, size_t len)
return trace_seq_putmem(s, hex, j);
}

static int
trace_seq_path(struct trace_seq *s, struct path *path)
{
unsigned char *p;

if (s->len >= (PAGE_SIZE - 1))
return 0;
p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
if (!IS_ERR(p)) {
p = mangle_path(s->buffer + s->len, p, "\n");
if (p) {
s->len = p - s->buffer;
return 1;
}
} else {
s->buffer[s->len++] = '?';
return 1;
}

return 0;
}

static void
trace_seq_reset(struct trace_seq *s)
{
Expand Down Expand Up @@ -802,6 +826,7 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags,

entry->preempt_count = pc & 0xff;
entry->pid = (tsk) ? tsk->pid : 0;
entry->tgid = (tsk) ? tsk->tgid : 0;
entry->flags =
#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
(irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) |
Expand Down Expand Up @@ -1429,28 +1454,73 @@ seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags)
return ret;
}

static inline int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm,
unsigned long ip, unsigned long sym_flags)
{
struct file *file = NULL;
unsigned long vmstart = 0;
int ret = 1;

if (mm) {
const struct vm_area_struct *vma = find_vma(mm, ip);
if (vma) {
file = vma->vm_file;
vmstart = vma->vm_start;
}
}
if (file) {
ret = trace_seq_path(s, &file->f_path);
if (ret)
ret = trace_seq_printf(s, "[+0x%lx]",
ip - vmstart);
}
if (ret && ((sym_flags & TRACE_ITER_SYM_ADDR) || !file))
ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
return ret;
}

static int
seq_print_userip_objs(const struct userstack_entry *entry, struct trace_seq *s,
unsigned long sym_flags)
unsigned long sym_flags)
{
struct mm_struct *mm = NULL;
int ret = 1;
unsigned i;

if (trace_flags & TRACE_ITER_SYM_USEROBJ) {
struct task_struct *task;
/*
* we do the lookup on the thread group leader,
* since individual threads might have already quit!
*/
rcu_read_lock();
task = find_task_by_vpid(entry->ent.tgid);
rcu_read_unlock();

if (task)
mm = get_task_mm(task);
}

for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
unsigned long ip = entry->caller[i];

if (ip == ULONG_MAX || !ret)
break;
if (i)
if (i && ret)
ret = trace_seq_puts(s, " <- ");
if (!ip) {
ret = trace_seq_puts(s, "??");
if (ret)
ret = trace_seq_puts(s, "??");
continue;
}
if (ret /*&& (sym_flags & TRACE_ITER_SYM_ADDR)*/)
ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
if (!ret)
break;
if (ret)
ret = seq_print_user_ip(s, mm, ip, sym_flags);
}

if (mm)
mmput(mm);
return ret;
}

Expand Down Expand Up @@ -1775,8 +1845,7 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu)
trace_assign_type(field, entry);

seq_print_userip_objs(field, s, sym_flags);
if (entry->flags & TRACE_FLAG_CONT)
trace_seq_print_cont(s, iter);
trace_seq_putc(s, '\n');
break;
}
default:
Expand Down Expand Up @@ -3581,6 +3650,9 @@ void ftrace_dump(void)
atomic_inc(&global_trace.data[cpu]->disabled);
}

/* don't look at user memory in panic mode */
trace_flags &= ~TRACE_ITER_SYM_USEROBJ;

printk(KERN_TRACE "Dumping ftrace buffer:\n");

iter.tr = &global_trace;
Expand Down
3 changes: 2 additions & 1 deletion trunk/kernel/trace/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,8 @@ enum trace_iterator_flags {
TRACE_ITER_PREEMPTONLY = 0x800,
TRACE_ITER_BRANCH = 0x1000,
TRACE_ITER_ANNOTATE = 0x2000,
TRACE_ITER_USERSTACKTRACE = 0x4000
TRACE_ITER_USERSTACKTRACE = 0x4000,
TRACE_ITER_SYM_USEROBJ = 0x8000
};

/*
Expand Down

0 comments on commit ab52367

Please sign in to comment.