tracer: add dynamic trigger for freezes
PATCH 4/4 tracer: add dynamic trigger for freezes
Tiny new tracer feature for debugging sessions: If you do something like
echo rthal_timer_request > /proc/ipipe/tracer/trigger
the trace will automagically freeze a trace (if it is running, of course) once it enters the given function via mcount instrumentation. Note that the symbol has to be resolvable when arming the trigger. One can also do
cat /proc/ipipe/tracer/trigger
to dump the currently active trigger.
With this service in place, you can quickly gain insight in code paths that you would like to dissect, maybe in order to find a bug...
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT SE 2 Corporate Competence Center Embedded Linux
--- kernel/ipipe/tracer.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 2 deletions(-)
kernel/ipipe/tracer.c +69 -2
@@ -2,7 +2,7 @@* kernel/ipipe/tracer.c * * Copyright (C) 2005 Luotao Fu. -* 2005, 2006 Jan Kiszka. +* 2005-2007 Jan Kiszka. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by
@@ -130,6 +130,9 @@ static int back_trace = IPIPE_DEFAULT_BAstatic int verbose_trace =1 ;static unsigned long trace_overhead; +static unsigned long trigger_begin; +static unsigned long trigger_end; +static DEFINE_MUTEX (out_mutex);static struct ipipe_trace_path *print_path;#ifdef CONFIG_IPIPE_TRACE_PANIC
@@ -347,7 +350,9 @@ __ipipe_trace(enum ipipe_trace_type type tp->post_trace = post_trace +1 ;/* freeze only if the slot is free and we are not already freezing */ -if (unlikely (type ==IPIPE_TRACE_FREEZE ) && +if ((unlikely (type ==IPIPE_TRACE_FREEZE ) || + (unlikely (eip >= trigger_begin && eip <= trigger_end) && + type ==IPIPE_TRACE_FUNC )) && (trace_paths[cpu_id][frozen_path[cpu_id]].begin <0 ) && !(tp->flags &IPIPE_TFLG_FREEZING )) { tp->post_trace = post_trace +1 ;
@@ -1193,6 +1198,61 @@ static int __ipipe_wr_proc_val(struct fireturn count; } +static int __ipipe_rd_trigger (char *page,char **start,off_t off,int count, +int *eof,void *data) +{ +int len; + +if (!trigger_begin) +return 0 ; + + len =sprint_symbol (page, trigger_begin); + page[len++] ='\n' ; + + len -= off; +if (len <= off + count) + *eof =1 ; + *start = page + off; +if (len > count) + len = count; +if (len <0 ) + len =0 ; + +return len; +} + +static int __ipipe_wr_trigger (struct file *file,const char __user *buffer, +unsigned long count,void *data) +{ +char buf[KSYM_SYMBOL_LEN ]; +unsigned long begin, end; + +if (count >sizeof (buf) -1 ) + count =sizeof (buf) -1 ; +if (copy_from_user (buf, buffer, count) <0 ) +return -EFAULT ; + buf[count] =0 ; +if (buf[count-1 ] =='\n' ) + buf[count-1 ] =0 ; + + begin =kallsyms_lookup_name (buf); +if (!begin || !kallsyms_lookup_size_offset (begin, &end,NULL )) +return -ENOENT ; + end += begin -1 ; + +mutex_lock (&out_mutex); +/* invalidate the current range before setting a new one */ + trigger_end =0 ; +wmb (); +/* set new range */ + trigger_begin = begin; +wmb (); + trigger_end = end; +mutex_unlock (&out_mutex); + +return count; +} +extern struct proc_dir_entry *ipipe_proc_root; static void __init
@@ -1262,6 +1322,13 @@ void __init __ipipe_init_tracer(void)if (entry) entry->proc_fops = &__ipipe_frozen_prtrace_fops; + entry =create_proc_entry ("trigger" ,0644 , trace_dir); +if (entry) { + entry->read_proc = __ipipe_rd_trigger; + entry->write_proc = __ipipe_wr_trigger; + entry->owner =THIS_MODULE ; + } +__ipipe_create_trace_proc_val (trace_dir,"pre_trace_points" , &pre_trace); __ipipe_create_trace_proc_val(trace_dir, "post_trace_points",