From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6090 invoked by alias); 8 Aug 2012 13:19:13 -0000 Received: (qmail 6072 invoked by uid 22791); 8 Aug 2012 13:19:11 -0000 X-SWARE-Spam-Status: No, hits=-6.1 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,SPF_HELO_PASS,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 08 Aug 2012 13:18:54 +0000 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q78DI6OC019457 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 8 Aug 2012 09:18:06 -0400 Received: from tranklukator.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id q78DI3as022379; Wed, 8 Aug 2012 09:18:04 -0400 Received: by tranklukator.brq.redhat.com (nbSMTP-1.00) for uid 500 oleg@redhat.com; Wed, 8 Aug 2012 15:15:00 +0200 (CEST) Date: Wed, 08 Aug 2012 13:19:00 -0000 From: Oleg Nesterov To: Sebastian Andrzej Siewior Cc: linux-kernel@vger.kernel.org, x86@kernel.org, Peter Zijlstra , Arnaldo Carvalho de Melo , Roland McGrath , Srikar Dronamraju , Ananth N Mavinakaynahalli , stan_shebs@mentor.com, gdb-patches@sourceware.org Subject: Re: [RFC 5/5] uprobes: add global breakpoints Message-ID: <20120808131457.GA5309@redhat.com> References: <1344355952-2382-1-git-send-email-bigeasy@linutronix.de> <1344355952-2382-6-git-send-email-bigeasy@linutronix.de> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <1344355952-2382-6-git-send-email-bigeasy@linutronix.de> User-Agent: Mutt/1.5.18 (2008-05-17) Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-08/txt/msg00253.txt.bz2 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.