This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFA] thread specific breakpoints and single stepping


Hello Pedro, 

thank you for your review.  

From: Pedro Alves <pedro at codesourcery.com>
Subject: Re: [RFA] thread specific breakpoints and single stepping
Date: Tue, 08 Jul 2008 21:05:02 +0100

> I don't think that's correct.  You can't be sure inferior_ptid
> is the user stepping thread at this point.  GDB may have context-switched
> already due to another event having happened in another thread after
> the user started the step, and before reaching here.  

I see.  I could also reproduce some cases you suggested.  

> Does it work for you?

It works better than mine.  But while I am concerning about
single-stepping for software watchpoints, I noticed that we should
also check whether a hardware watchpoint is triggered.  

A revised patch is attached, which includes tests and ChangeLog
entries.  

Is that OK?

Thanks again, 
-- 
Emi SUZUKI / emi-suzuki at tjsys.co.jp

gdb:

2008-07-09  Pedro Alves  <pedro@codesourcery.com>
	    Emi Suzuki  <emi-suzuki@tjsys.co.jp>

	* infrun.c (handle_inferior_event): Check if the thread is
	neither single-stepping nor trapped by a hardware watchpoint
	trigger before hopping over a thread specific breakpoint.  

gdb/testsuite:

2008-07-09  Emi Suzuki  <emi-suzuki@tjsys.co.jp>

	* gdb.threads/thread-specific2.exp,
	gdb.threads/thread-specific2.c: New tests. 

Index: gdb/infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.285
diff -u -r1.285 infrun.c
--- gdb/infrun.c	8 Jul 2008 10:31:16 -0000	1.285
+++ gdb/infrun.c	9 Jul 2008 12:05:05 -0000
@@ -2122,7 +2122,19 @@
 	{
 	  ecs->random_signal = 0;
 	  if (!breakpoint_thread_match (stop_pc, ecs->ptid))
-	    thread_hop_needed = 1;
+	    {
+	      if (!ptid_equal (inferior_ptid, ecs->ptid))
+		context_switch (ecs);
+
+	      /* If the thread is currently single-stepping, whether it 
+		 will step over this breakpoint or not should be determined
+		 later.  Also, it should stop when a hardware watchpoint 
+		 trap is triggered.  */
+	      if (!((step_range_end && step_resume_breakpoint == NULL)
+		    || bpstat_should_step ()
+		    || STOPPED_BY_WATCHPOINT (&ecs->ws)))
+		thread_hop_needed = 1;
+	    }
 	}
       else if (singlestep_breakpoints_inserted_p)
 	{
Index: gdb/testsuite/gdb.threads/thread-specific2.c
===================================================================
RCS file: gdb/testsuite/gdb.threads/thread-specific2.c
diff -N gdb/testsuite/gdb.threads/thread-specific2.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/testsuite/gdb.threads/thread-specific2.c	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,45 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2008 Free Software Foundation, Inc.
+
+   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
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+void *
+thread_entry (void* args)
+{
+  int i = 0;
+  i += 1;  /* thread-specific2.exp: hop over 1 */
+  i -= 1;  /* thread-specific2.exp: hop over 2 */
+
+  pthread_exit(NULL);
+}
+
+int
+main (void)
+{
+  int res;
+  pthread_t tid;
+  void *thread_status;
+
+  res = pthread_create (&tid, NULL, (void *) thread_entry, NULL);
+
+  /* wait for the thread */
+  pthread_join (tid, &thread_status);
+
+  exit (EXIT_SUCCESS);
+}
Index: gdb/testsuite/gdb.threads/thread-specific2.exp
===================================================================
RCS file: gdb/testsuite/gdb.threads/thread-specific2.exp
diff -N gdb/testsuite/gdb.threads/thread-specific2.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/testsuite/gdb.threads/thread-specific2.exp	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,97 @@
+# Copyright 2008 Free Software Foundation, Inc.
+
+# 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
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# It tests that a thread-specific breakpoint would not be hopped when 
+# the trapped thread is currently single-stepping or a watchpoint 
+# triggered on the breakpoint.  
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "thread-specific2"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+    return -1
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_load ${binfile}
+
+gdb_test "set print sevenbit-strings" ""
+gdb_test "set width 0" ""
+
+if { ! [ runto "thread_entry" ] } then {
+    untested thread-specific2.exp
+    return -1
+}
+
+# Test 1: the target will get stopped on a thread specific breakpoint
+# when it is singile-stepping.  
+set line1 [gdb_get_line_number "thread-specific2.exp: hop over 1"]
+
+gdb_test_multiple "break $line1 thread 1" \
+    "breakpoint $line1 main thread" {
+    -re "Breakpoint (\[0-9\]*) at.* file .*$srcfile, line.*$gdb_prompt $" {
+	set thread_break1 $expect_out(1,string)
+	pass "breakpoint $line1 main thread"
+    }
+}
+
+gdb_test_multiple "step" \
+    "step onto thread-specific breakpoint" {
+    -re "$line1 *.*\r\n$gdb_prompt $" {
+	pass "step onto breakpoint $thread_break1"
+    }
+}
+
+# Test 2: the target will get stopped on a thread specific breakpoint
+# when a watchpoint triggered.  
+set line2 [gdb_get_line_number "thread-specific2.exp: hop over 2"]
+
+gdb_test_multiple "break $line2 thread 1" \
+    "breakpoint $line2 main thread" {
+    -re "Breakpoint (\[0-9\]*) at.* file .*$srcfile, line.*$gdb_prompt $" {
+	set thread_break2 $expect_out(1,string)
+	pass "breakpoint $line2 main thread"
+    }
+}
+
+gdb_test_multiple "watch i" \
+    "watch i" {
+      -re "\[Ww\]atchpoint (\[0-9\]*): i\r\n$gdb_prompt $" {
+      set watch_num $expect_out(1,string)
+      pass "watch i"
+    }
+}
+
+gdb_test_multiple "continue" \
+    "watchpoint $watch_num triggered on thread-specific breakpoint" {
+    -re "\[Ww\]atchpoint $watch_num: i\r\n.*\r\n$gdb_prompt $" {
+	pass "watchpoint $watch_num triggered on breakpoint $thread_break2"
+    }
+}
+
+return 0

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]