This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [RFC 5/5] uprobes: add global breakpoints
- From: Oleg Nesterov <oleg at redhat dot com>
- To: Sebastian Andrzej Siewior <bigeasy at linutronix dot de>
- Cc: linux-kernel at vger dot kernel dot org, x86 at kernel dot org, Peter Zijlstra <a dot p dot zijlstra at chello dot nl>, Arnaldo Carvalho de Melo <acme at ghostprotocols dot net>, Roland McGrath <roland at redhat dot com>, Srikar Dronamraju <srikar at linux dot vnet dot ibm dot com>, Ananth N Mavinakaynahalli <ananth at in dot ibm dot com>, stan_shebs at mentor dot com, gdb-patches at sourceware dot org
- Date: Wed, 8 Aug 2012 15:14:57 +0200
- Subject: Re: [RFC 5/5] uprobes: add global breakpoints
- References: <1344355952-2382-1-git-send-email-bigeasy@linutronix.de> <1344355952-2382-6-git-send-email-bigeasy@linutronix.de>
On 08/07, Sebastian Andrzej Siewior wrote:
>
> By setting an uprobe tracepoint, one learns whenever a certain point
> within a program is reached / passed. This is recorded and the
> application continues.
> This patch adds the ability to hold the program once this point has been
> passed and the user may attach to the program via ptrace.
> First, setup a global breakpoint which is very similar to a uprobe trace
> point:
>
> |echo 'g /home/bigeasy/sample:0x0000044d %ip %ax' > uprobe_events
>
> This is exactly what uprobe does except that it starts with the letter
> 'g' instead of 'p'.
>
> Step two is to enable it:
> |echo 1 > events/uprobes/enable
>
> Lets assume you execute ./sample and the breakpoint is hit. In ps you will
> see:
> |1938 pts/1 t+ 0:00 ./sample
>
> Now you can attach gdb via 'gdb -p 1938'. The gdb can now interact with
> the tracee and inspect its registers, its stack, single step, let it
> runâ
> In case the process is not of great interest, the user may continue
> without gdb by writting its pid into the uprobe_gp_wakeup file
>
> |echo 1938 > uprobe_gp_wakeup
>
> What I miss right now is an interface to tell the user/gdb that there is a
> program that hit a global breakpoint and is waiting for further instructions.
> A "tail -f trace" does not work and may contain also a lot of other
> informations. I've been thinking about a poll()able file which returns pids of
> tasks which are put on hold. Other suggestions?
Honestly, I am not sure this is that useful...
OK, I'll try to read this patch later. But, at first glance,
> +int uprobe_wakeup_task(struct task_struct *t, int traced)
> +{
> + struct uprobe_task *utask;
> +
> + utask = t->utask;
> + if (!utask)
> + return -EINVAL;
> + if (utask->state != UTASK_TRACE_SLEEP)
> + return -EINVAL;
> +
> + utask->state = traced ?
> + UTASK_TRACE_WOKEUP_TRACED : UTASK_TRACE_WOKEUP_NORMAL;
> + wake_up_state(t, __TASK_TRACED);
> + return 0;
> +}
This can obviously race with uprobe_wait_traced(), see below
> @@ -286,8 +286,10 @@ static int ptrace_attach(struct task_struct *task, long request,
> __ptrace_link(task, current);
>
> /* SEIZE doesn't trap tracee on attach */
> - if (!seize)
> + if (!seize) {
> send_sig_info(SIGSTOP, SEND_SIG_FORCED, task);
> + uprobe_wakeup_task(task, 1);
> + }
Can't understand why uprobe_wakeup_task() depends on !PTRACE_SEIZE
> +static void uprobe_wait_traced(struct trace_uprobe *tu)
> +{
> + struct uprobe_task *utask;
> +
> + utask = current->utask;
> + utask->state = UTASK_TRACE_SLEEP;
WINDOW
> +
> + set_current_state(TASK_TRACED);
> + schedule();
> +}
Suppose that uprobe_wakeup_task() is called in the WINDOW above.
OTOH, uprobe_wakeup_task() can race with itself if it is called
twice at the same time, say from uprobes_gp_wakeup_write() and
ptrace_attach().
Oleg.