From 5a72cdabf8546db3bf7e67bff25eeede6e97fb61 Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Thu, 21 Jun 2007 05:22:01 +0000 Subject: [PATCH] - Support for stepping over PPC atomic instruction sequences (BZ 237572). - `set scheduler-locking step' is no longer enforced but it is now default. --- gdb-6.3-step-thread-exit-20050211-test.patch | 178 +++ gdb-6.3-step-thread-exit-20050211.patch | 433 ------ gdb-6.3-thread-step-20041207.patch | 58 - ....6-bz237572-ppc-atomic-sequence-test.patch | 291 +++++ ...z237572-ppc-atomic-sequence-upstream.patch | 1160 +++++++++++++++++ ...heduler_locking-step-sw-watchpoints2.patch | 160 +++ gdb-6.6-step-thread-exit.patch | 80 ++ gdb.spec | 23 +- 8 files changed, 1887 insertions(+), 496 deletions(-) create mode 100644 gdb-6.3-step-thread-exit-20050211-test.patch delete mode 100644 gdb-6.3-step-thread-exit-20050211.patch delete mode 100644 gdb-6.3-thread-step-20041207.patch create mode 100644 gdb-6.6-bz237572-ppc-atomic-sequence-test.patch create mode 100644 gdb-6.6-bz237572-ppc-atomic-sequence-upstream.patch create mode 100644 gdb-6.6-scheduler_locking-step-sw-watchpoints2.patch create mode 100644 gdb-6.6-step-thread-exit.patch diff --git a/gdb-6.3-step-thread-exit-20050211-test.patch b/gdb-6.3-step-thread-exit-20050211-test.patch new file mode 100644 index 0000000..15ef8d2 --- /dev/null +++ b/gdb-6.3-step-thread-exit-20050211-test.patch @@ -0,0 +1,178 @@ +2005-02-11 Jeff Johnston + + * testsuite/gdb.threads/step-thread-exit.c: New testcase. + * testsuite/gdb.threads/step-thread-exit.exp: Ditto. + +Index: gdb-6.5/gdb/testsuite/gdb.threads/step-thread-exit.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ gdb-6.5/gdb/testsuite/gdb.threads/step-thread-exit.c 2006-07-12 03:18:47.000000000 -0300 +@@ -0,0 +1,50 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++ Copyright 2005 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 2 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, write to the Free Software ++ Foundation, Inc., 59 Temple Place - Suite 330, ++ Boston, MA 02111-1307, USA. */ ++ ++#include ++#include ++#include ++#include ++ ++void *thread_function (void *ptr) ++{ ++ int *x = (int *)ptr; ++ printf("In thread_function, *x is %d\n", *x); ++} /* thread_function_end */ ++ ++volatile int repeat = 0; ++ ++main() ++{ ++ int ret; ++ pthread_t th; ++ int i = 3; ++ ++ ret = pthread_create (&th, NULL, thread_function, &i); ++ do ++ { ++ repeat = 0; ++ sleep (3); /* sleep */ ++ } ++ while (repeat); ++ pthread_join (th, NULL); ++ return 0; ++} ++ ++ +Index: gdb-6.5/gdb/testsuite/gdb.threads/step-thread-exit.exp +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ gdb-6.5/gdb/testsuite/gdb.threads/step-thread-exit.exp 2006-07-12 03:22:30.000000000 -0300 +@@ -0,0 +1,113 @@ ++# This testcase is part of GDB, the GNU debugger. ++ ++# Copyright 2005 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 2 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, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ ++# Check that GDB can step over a thread exit. ++ ++if $tracelevel { ++ strace $tracelevel ++} ++ ++set prms_id 0 ++set bug_id 0 ++ ++set testfile "step-thread-exit" ++set srcfile ${testfile}.c ++set binfile ${objdir}/${subdir}/${testfile} ++if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } { ++ return -1 ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${binfile} ++ ++# Reset the debug file directory so we can't debug within the C library ++gdb_test "set debug-file-directory ." "" "" ++ ++# ++# Run to `main' where we begin our tests. ++# ++ ++if ![runto_main] then { ++ gdb_suppress_tests ++} ++ ++set sleep_line [expr [gdb_get_line_number "sleep"]] ++set end_line [expr [gdb_get_line_number "thread_function_end"]] ++ ++gdb_breakpoint "$end_line" ++gdb_test "continue" "Break.*thread_function.*" "continue to thread_function 1" ++ ++# Keep nexting until we cause the thread to exit. We expect the main ++# thread to be stopped and a message printed to tell us we have stepped ++# over the thread exit. ++set test "step over thread exit 1" ++gdb_test_multiple "next" "$test" { ++ -re "\}.*$gdb_prompt $" { ++ send_gdb "next\n" ++ exp_continue ++ } ++ -re "Stepped over thread exit.*Program received signal SIGSTOP.*$gdb_prompt $" { ++ pass "$test" ++ } ++ -re "start_thread.*$gdb_prompt $" { ++ send_gdb "next\n" ++ exp_continue ++ } ++} ++ ++gdb_test "bt" ".*sleep.*main.*$sleep_line.*" "backtrace after step 1" ++ ++runto_main ++gdb_breakpoint "$sleep_line" ++gdb_breakpoint "$end_line" ++set test "continue to thread_function 2" ++gdb_test_multiple "continue" "$test" { ++ -re "Break.*thread_function.*$gdb_prompt $" { ++ pass $test ++ } ++ -re "Break.*$sleep_line.*$gdb_prompt $" { ++ gdb_test "set repeat=1" "" "" ++ send_gdb "continue\n" ++ exp_continue ++ } ++} ++ ++# Keep nexting until we cause the thread to exit. In this case, we ++# expect the breakpoint in the main thread to have already triggered ++# and so we should stop there with a message that we stepped over ++# the thread exit. ++set test "step over thread exit 2" ++gdb_test_multiple "next" "$test" { ++ -re "\}.*$gdb_prompt $" { ++ send_gdb "next\n" ++ exp_continue ++ } ++ -re "Stepped over thread exit.*Break.*$sleep_line.*$gdb_prompt $" { ++ pass "$test (breakpoint hit)" ++ } ++ -re "Stepped over thread exit.*$gdb_prompt $" { ++ pass "$test (breakpoint not hit)" ++ } ++ -re "start_thread.*$gdb_prompt $" { ++ send_gdb "next\n" ++ exp_continue ++ } ++} ++ diff --git a/gdb-6.3-step-thread-exit-20050211.patch b/gdb-6.3-step-thread-exit-20050211.patch deleted file mode 100644 index 1f0c582..0000000 --- a/gdb-6.3-step-thread-exit-20050211.patch +++ /dev/null @@ -1,433 +0,0 @@ -2005-02-11 Jeff Johnston - - * target.h (target_waitstatus): Add new step_thread_exit flag. - * infrun.c (init_execution_control_state): Initialize step_thread_exit. - (handle_inferior_event): If step_thread_exit flag is set, print - out special message and reset flag. - (currently_stepping): Do not return true if step_thread_exit flag - is set. - * linux-nat.c (resume_callback): Use second parameter to notify - if the resume should be a PTRACE_SINGLESTEP or PTRACE_CONT. - (stop_and_resume_callback): Pass on data parameter to resume_callback. - (linux_nat_resume): Don't attempt to resume if lp is NULL. - (linux_nat_wait): Do not wait on step_lp as first wait. After - wait, check if step_lp has an event or not. If the step lwp has - exited, issue a stop on the first non-step_lp lwp in the lwp list. - Change the delayed stop code to not ignore an intentional stop. - If we see an event on an lwp which isn't the step_lp, verify if - the step_lp has exited or not. Set the step_thread_exit flag if - we have verified that the step_lp is gone. - * testsuite/gdb.threads/step-thread-exit.c: New testcase. - * testsuite/gdb.threads/step-thread-exit.exp: Ditto. - -Index: gdb-6.5/gdb/testsuite/gdb.threads/step-thread-exit.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gdb-6.5/gdb/testsuite/gdb.threads/step-thread-exit.c 2006-07-12 03:18:47.000000000 -0300 -@@ -0,0 +1,50 @@ -+/* This testcase is part of GDB, the GNU debugger. -+ -+ Copyright 2005 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 2 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, write to the Free Software -+ Foundation, Inc., 59 Temple Place - Suite 330, -+ Boston, MA 02111-1307, USA. */ -+ -+#include -+#include -+#include -+#include -+ -+void *thread_function (void *ptr) -+{ -+ int *x = (int *)ptr; -+ printf("In thread_function, *x is %d\n", *x); -+} /* thread_function_end */ -+ -+volatile int repeat = 0; -+ -+main() -+{ -+ int ret; -+ pthread_t th; -+ int i = 3; -+ -+ ret = pthread_create (&th, NULL, thread_function, &i); -+ do -+ { -+ repeat = 0; -+ sleep (3); /* sleep */ -+ } -+ while (repeat); -+ pthread_join (th, NULL); -+ return 0; -+} -+ -+ -Index: gdb-6.5/gdb/testsuite/gdb.threads/step-thread-exit.exp -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gdb-6.5/gdb/testsuite/gdb.threads/step-thread-exit.exp 2006-07-12 03:22:30.000000000 -0300 -@@ -0,0 +1,113 @@ -+# This testcase is part of GDB, the GNU debugger. -+ -+# Copyright 2005 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 2 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, write to the Free Software -+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ -+# Check that GDB can step over a thread exit. -+ -+if $tracelevel { -+ strace $tracelevel -+} -+ -+set prms_id 0 -+set bug_id 0 -+ -+set testfile "step-thread-exit" -+set srcfile ${testfile}.c -+set binfile ${objdir}/${subdir}/${testfile} -+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } { -+ return -1 -+} -+ -+gdb_exit -+gdb_start -+gdb_reinitialize_dir $srcdir/$subdir -+gdb_load ${binfile} -+ -+# Reset the debug file directory so we can't debug within the C library -+gdb_test "set debug-file-directory ." "" "" -+ -+# -+# Run to `main' where we begin our tests. -+# -+ -+if ![runto_main] then { -+ gdb_suppress_tests -+} -+ -+set sleep_line [expr [gdb_get_line_number "sleep"]] -+set end_line [expr [gdb_get_line_number "thread_function_end"]] -+ -+gdb_breakpoint "$end_line" -+gdb_test "continue" "Break.*thread_function.*" "continue to thread_function 1" -+ -+# Keep nexting until we cause the thread to exit. We expect the main -+# thread to be stopped and a message printed to tell us we have stepped -+# over the thread exit. -+set test "step over thread exit 1" -+gdb_test_multiple "next" "$test" { -+ -re "\}.*$gdb_prompt $" { -+ send_gdb "next\n" -+ exp_continue -+ } -+ -re "Stepped over thread exit.*Program received signal SIGSTOP.*$gdb_prompt $" { -+ pass "$test" -+ } -+ -re "start_thread.*$gdb_prompt $" { -+ send_gdb "next\n" -+ exp_continue -+ } -+} -+ -+gdb_test "bt" ".*sleep.*main.*$sleep_line.*" "backtrace after step 1" -+ -+runto_main -+gdb_breakpoint "$sleep_line" -+gdb_breakpoint "$end_line" -+set test "continue to thread_function 2" -+gdb_test_multiple "continue" "$test" { -+ -re "Break.*thread_function.*$gdb_prompt $" { -+ pass $test -+ } -+ -re "Break.*$sleep_line.*$gdb_prompt $" { -+ gdb_test "set repeat=1" "" "" -+ send_gdb "continue\n" -+ exp_continue -+ } -+} -+ -+# Keep nexting until we cause the thread to exit. In this case, we -+# expect the breakpoint in the main thread to have already triggered -+# and so we should stop there with a message that we stepped over -+# the thread exit. -+set test "step over thread exit 2" -+gdb_test_multiple "next" "$test" { -+ -re "\}.*$gdb_prompt $" { -+ send_gdb "next\n" -+ exp_continue -+ } -+ -re "Stepped over thread exit.*Break.*$sleep_line.*$gdb_prompt $" { -+ pass "$test (breakpoint hit)" -+ } -+ -re "Stepped over thread exit.*$gdb_prompt $" { -+ pass "$test (breakpoint not hit)" -+ } -+ -re "start_thread.*$gdb_prompt $" { -+ send_gdb "next\n" -+ exp_continue -+ } -+} -+ -Index: gdb-6.5/gdb/infrun.c -=================================================================== ---- gdb-6.5.orig/gdb/infrun.c 2006-07-12 01:54:29.000000000 -0300 -+++ gdb-6.5/gdb/infrun.c 2006-07-12 03:22:41.000000000 -0300 -@@ -1088,6 +1088,7 @@ init_execution_control_state (struct exe - ecs->current_symtab = ecs->sal.symtab; - ecs->infwait_state = infwait_normal_state; - ecs->waiton_ptid = pid_to_ptid (-1); -+ ecs->ws.step_thread_exit = 0; - ecs->wp = &(ecs->ws); - } - -@@ -1307,6 +1308,16 @@ handle_inferior_event (struct execution_ - ui_out_text (uiout, "]\n"); - } - -+ /* Check if were stepping a thread and we stepped over the exit. -+ In such a case, we will have found another event to process. -+ Clear any stepping state and process that event. */ -+ if (ecs->ws.step_thread_exit) -+ { -+ printf_unfiltered ("[Stepped over thread exit]\n"); -+ clear_proceed_status (); -+ ecs->ws.step_thread_exit = 0; -+ } -+ - switch (ecs->ws.kind) - { - case TARGET_WAITKIND_LOADED: -@@ -2697,11 +2708,12 @@ process_event_stop_test: - static int - currently_stepping (struct execution_control_state *ecs) - { -- return ((!ecs->handling_longjmp -- && ((step_range_end && step_resume_breakpoint == NULL) -- || trap_expected)) -- || ecs->stepping_through_solib_after_catch -- || bpstat_should_step ()); -+ return (!ecs->ws.step_thread_exit -+ && ((!ecs->handling_longjmp -+ && ((step_range_end && step_resume_breakpoint == NULL) -+ || trap_expected)) -+ || ecs->stepping_through_solib_after_catch -+ || bpstat_should_step ())); - } - - /* Subroutine call with source code we should not step over. Do step -Index: gdb-6.5/gdb/linux-nat.c -=================================================================== ---- gdb-6.5.orig/gdb/linux-nat.c 2006-07-12 01:54:29.000000000 -0300 -+++ gdb-6.5/gdb/linux-nat.c 2006-07-12 03:22:42.000000000 -0300 -@@ -1137,18 +1137,21 @@ linux_nat_detach (char *args, int from_t - static int - resume_callback (struct lwp_info *lp, void *data) - { -+ int step = (data != NULL); -+ - if (lp->stopped && lp->status == 0) - { - struct thread_info *tp; - - linux_ops->to_resume (pid_to_ptid (GET_LWP (lp->ptid)), -- 0, TARGET_SIGNAL_0); -+ step, TARGET_SIGNAL_0); - if (debug_linux_nat) - fprintf_unfiltered (gdb_stdlog, -- "RC: PTRACE_CONT %s, 0, 0 (resume sibling)\n", -+ "RC: %s %s, 0, 0 (resume sibling)\n", -+ step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT", - target_pid_to_str (lp->ptid)); - lp->stopped = 0; -- lp->step = 0; -+ lp->step = step; - } - - return 0; -@@ -1259,13 +1262,17 @@ linux_nat_resume (ptid_t ptid, int step, - if (resume_all) - iterate_over_lwps (resume_callback, NULL); - -- linux_ops->to_resume (ptid, step, signo); -- if (debug_linux_nat) -- fprintf_unfiltered (gdb_stdlog, -- "LLR: %s %s, %s (resume event thread)\n", -- step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT", -- target_pid_to_str (ptid), -- signo ? strsignal (signo) : "0"); -+ if (lp) -+ { -+ linux_ops->to_resume (ptid, step, signo); -+ -+ if (debug_linux_nat) -+ fprintf_unfiltered (gdb_stdlog, -+ "LLR: %s %s, %s (resume event thread)\n", -+ step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT", -+ target_pid_to_str (ptid), -+ signo ? strsignal (signo) : "0"); -+ } - } - - /* Issue kill to specified lwp. */ -@@ -1863,7 +1870,7 @@ stop_and_resume_callback (struct lwp_inf - for (ptr = lwp_list; ptr; ptr = ptr->next) - if (lp == ptr) - { -- resume_callback (lp, NULL); -+ resume_callback (lp, data); - resume_set_callback (lp, NULL); - } - } -@@ -1874,8 +1881,10 @@ static ptid_t - linux_nat_wait (ptid_t ptid, struct target_waitstatus *ourstatus) - { - struct lwp_info *lp = NULL; -+ struct lwp_info *step_lp = NULL; - int options = 0; - int status = 0; -+ int intentional_stop = 0; - pid_t pid = PIDGET (ptid); - sigset_t flush_mask; - -@@ -1913,14 +1922,12 @@ retry: - gets the expected trap so we don't want to wait on any LWP. - This has ramifications when adjustment of the PC is required which can be - different after a breakpoint vs a step (e.g. x86). */ -- lp = iterate_over_lwps (find_singlestep_lwp_callback, NULL); -- if (lp) { -+ step_lp = iterate_over_lwps (find_singlestep_lwp_callback, NULL); -+ if (step_lp) { - if (debug_linux_nat) - fprintf_unfiltered (gdb_stdlog, - "LLW: Found step lwp %s.\n", -- target_pid_to_str (lp->ptid)); -- ptid = lp->ptid; -- pid = PIDGET (ptid); -+ target_pid_to_str (step_lp->ptid)); - } - - /* If any pid, check if there is a LWP with a wait status pending. */ -@@ -2161,8 +2168,9 @@ retry: - } - - /* Make sure we don't report a SIGSTOP that we sent -- ourselves in an attempt to stop an LWP. */ -- if (lp->signalled -+ ourselves in an attempt to stop an LWP, unless we -+ intentionally want to see the SIGSTOP. */ -+ if (lp->signalled && !intentional_stop - && WIFSTOPPED (status) && WSTOPSIG (status) == SIGSTOP) - { - if (debug_linux_nat) -@@ -2196,6 +2204,20 @@ retry: - - if (pid == -1) - { -+ lp = NULL; -+ if (step_lp && errno == ECHILD) -+ { -+ /* We have stepped over a thread exit. We want to stop -+ the first existing lwp we find and report a stop event. */ -+ for (lp = lwp_list; lp && lp == step_lp; lp = lp->next) -+ ; /* empty */ -+ } -+ if (lp != NULL) -+ { -+ stop_callback (lp, NULL); -+ intentional_stop = 1; -+ } -+ - /* Alternate between checking cloned and uncloned processes. */ - options ^= __WCLONE; - -@@ -2268,6 +2290,42 @@ retry: - fprintf_unfiltered (gdb_stdlog, "LLW: Candidate event %s in %s.\n", - status_to_str (status), target_pid_to_str (lp->ptid)); - -+ /* Check if there is any LWP that is being single-stepped. We need to -+ wait specifically on such an LWP because the higher-level code is -+ expecting a step operation to find an event on the stepped LWP. -+ It is possible for other events to occur before the step operation -+ gets the expected trap so we don't want to wait on any LWP. -+ This has ramifications when adjustment of the PC is required which can be -+ different after a breakpoint vs a step (e.g. x86). */ -+ if (step_lp && step_lp != lp) -+ { -+ struct lwp_info *ptr; -+ int arg = 1; -+ if (debug_linux_nat) -+ fprintf_unfiltered (gdb_stdlog, -+ "LLW: Found step lwp %s.\n", -+ target_pid_to_str (step_lp->ptid)); -+ stop_and_resume_callback (step_lp, &arg); -+ for (ptr = lwp_list; ptr; ptr = ptr->next) -+ if (step_lp == ptr) -+ break; -+ -+ if (ptr) -+ { -+ if (debug_linux_nat) -+ fprintf_unfiltered (gdb_stdlog, -+ "LLW: Continuing step lwp %s.\n", -+ target_pid_to_str (step_lp->ptid)); -+ ptid = step_lp->ptid; -+ pid = PIDGET (ptid); -+ lp->status = status; -+ status = 0; -+ options = WNOHANG | (step_lp->cloned ? __WCLONE : 0); -+ pid = GET_LWP (ptid); -+ goto retry; -+ } -+ } -+ - /* Now stop all other LWP's ... */ - iterate_over_lwps (stop_callback, NULL); - -@@ -2306,6 +2364,10 @@ retry: - else - store_waitstatus (ourstatus, status); - -+ /* If we were stepping a thread and it exited, mark this. */ -+ if (step_lp && step_lp != lp) -+ ourstatus->step_thread_exit = 1; -+ - return lp->ptid; - } - -Index: gdb-6.5/gdb/target.h -=================================================================== ---- gdb-6.5.orig/gdb/target.h 2006-07-12 01:54:29.000000000 -0300 -+++ gdb-6.5/gdb/target.h 2006-07-12 03:22:40.000000000 -0300 -@@ -136,6 +136,7 @@ enum target_waitkind - struct target_waitstatus - { - enum target_waitkind kind; -+ int step_thread_exit; /* non-zero if we step over a thread exit. */ - - /* Forked child pid, execd pathname, exit status or signal number. */ - union diff --git a/gdb-6.3-thread-step-20041207.patch b/gdb-6.3-thread-step-20041207.patch deleted file mode 100644 index c6e2a4e..0000000 --- a/gdb-6.3-thread-step-20041207.patch +++ /dev/null @@ -1,58 +0,0 @@ -2004-12-07 Jeff Johnston - - * linux-nat.c (find_singlestep_lwp_callback): New function. - (linux-nat-wait): Before waiting on any pid, check if there - is a stepping lwp and if so, wait on it specifically. - ---- gdb-6.3/gdb/linux-nat.c.fix Tue Dec 7 19:39:34 2004 -+++ gdb-6.3/gdb/linux-nat.c Tue Dec 7 19:39:46 2004 -@@ -1489,9 +1489,21 @@ count_events_callback (struct lwp_info * - return 0; - } - --/* Select the LWP (if any) that is currently being single-stepped. */ -+/* Find an LWP (if any) that is currently being single-stepped. */ - - static int -+find_singlestep_lwp_callback (struct lwp_info *lp, void *data) -+{ -+ if (lp->step) -+ return 1; -+ else -+ return 0; -+} -+ -+/* Select the LWP with an event (if any) that is currently being -+ single-stepped. */ -+ -+static int - select_singlestep_lwp_callback (struct lwp_info *lp, void *data) - { - if (lp->step && lp->status != 0) -@@ -1774,7 +1786,25 @@ retry: - least if there are any LWPs at all. */ - gdb_assert (num_lwps == 0 || iterate_over_lwps (resumed_callback, NULL)); - -- /* First check if there is a LWP with a wait status pending. */ -+ /* Check if there is any LWP that is being single-stepped. We need to -+ wait specifically on such an LWP because the higher-level code is -+ expecting a step operation to find an event on the stepped LWP. -+ It is possible for other events to occur before the step operation -+ gets the expected trap so we don't want to wait on any LWP. -+ This has ramifications when adjustment of the PC is required which can be -+ different after a breakpoint vs a step (e.g. x86). */ -+ lp = iterate_over_lwps (find_singlestep_lwp_callback, NULL); -+ if (lp) { -+ if (debug_linux_nat) -+ fprintf_unfiltered (gdb_stdlog, -+ "LLW: Found step lwp %s.\n", -+ target_pid_to_str (lp->ptid)); -+ ptid = lp->ptid; -+ pid = PIDGET (ptid); -+ } -+ -+ /* If any pid, check if there is a LWP with a wait status pending. */ -+ - if (pid == -1) - { - /* Any LWP that's been resumed will do. */ diff --git a/gdb-6.6-bz237572-ppc-atomic-sequence-test.patch b/gdb-6.6-bz237572-ppc-atomic-sequence-test.patch new file mode 100644 index 0000000..5195581 --- /dev/null +++ b/gdb-6.6-bz237572-ppc-atomic-sequence-test.patch @@ -0,0 +1,291 @@ +Index: gdb-6.6/gdb/testsuite/gdb.threads/atomic-seq-threaded.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ gdb-6.6/gdb/testsuite/gdb.threads/atomic-seq-threaded.c 2007-06-18 20:24:04.000000000 +0200 +@@ -0,0 +1,171 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++ Copyright 2007 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 2 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, write to the Free Software ++ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++/* Test stepping over RISC atomic sequences. ++ This variant testcases the code for stepping another thread while skipping ++ over the atomic sequence in the former thread ++ (STEPPING_PAST_SINGLESTEP_BREAKPOINT). ++ Code comes from gcc/testsuite/gcc.dg/sync-2.c */ ++ ++/* { dg-options "-march=i486" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ ++/* { dg-options "-mcpu=v9" { target sparc*-*-* } } */ ++ ++/* Test functionality of the intrinsics for 'short' and 'char'. */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define LOOPS 2 ++ ++static int unused; ++ ++static char AI[18]; ++static char init_qi[18] = { 3,5,7,9,0,0,0,0,-1,0,0,0,0,0,-1,0,0,0 }; ++static char test_qi[18] = { 3,5,7,9,1,4,22,-12,7,8,9,7,1,-12,7,8,9,7 }; ++ ++static void ++do_qi (void) ++{ ++ if (__sync_fetch_and_add(AI+4, 1) != 0) ++ abort (); ++ if (__sync_fetch_and_add(AI+5, 4) != 0) ++ abort (); ++ if (__sync_fetch_and_add(AI+6, 22) != 0) ++ abort (); ++ if (__sync_fetch_and_sub(AI+7, 12) != 0) ++ abort (); ++ if (__sync_fetch_and_and(AI+8, 7) != (char)-1) ++ abort (); ++ if (__sync_fetch_and_or(AI+9, 8) != 0) ++ abort (); ++ if (__sync_fetch_and_xor(AI+10, 9) != 0) ++ abort (); ++ if (__sync_fetch_and_nand(AI+11, 7) != 0) ++ abort (); ++ ++ if (__sync_add_and_fetch(AI+12, 1) != 1) ++ abort (); ++ if (__sync_sub_and_fetch(AI+13, 12) != (char)-12) ++ abort (); ++ if (__sync_and_and_fetch(AI+14, 7) != 7) ++ abort (); ++ if (__sync_or_and_fetch(AI+15, 8) != 8) ++ abort (); ++ if (__sync_xor_and_fetch(AI+16, 9) != 9) ++ abort (); ++ if (__sync_nand_and_fetch(AI+17, 7) != 7) ++ abort (); ++} ++ ++static short AL[18]; ++static short init_hi[18] = { 3,5,7,9,0,0,0,0,-1,0,0,0,0,0,-1,0,0,0 }; ++static short test_hi[18] = { 3,5,7,9,1,4,22,-12,7,8,9,7,1,-12,7,8,9,7 }; ++ ++static void ++do_hi (void) ++{ ++ if (__sync_fetch_and_add(AL+4, 1) != 0) ++ abort (); ++ if (__sync_fetch_and_add(AL+5, 4) != 0) ++ abort (); ++ if (__sync_fetch_and_add(AL+6, 22) != 0) ++ abort (); ++ if (__sync_fetch_and_sub(AL+7, 12) != 0) ++ abort (); ++ if (__sync_fetch_and_and(AL+8, 7) != -1) ++ abort (); ++ if (__sync_fetch_and_or(AL+9, 8) != 0) ++ abort (); ++ if (__sync_fetch_and_xor(AL+10, 9) != 0) ++ abort (); ++ if (__sync_fetch_and_nand(AL+11, 7) != 0) ++ abort (); ++ ++ if (__sync_add_and_fetch(AL+12, 1) != 1) ++ abort (); ++ if (__sync_sub_and_fetch(AL+13, 12) != -12) ++ abort (); ++ if (__sync_and_and_fetch(AL+14, 7) != 7) ++ abort (); ++ if (__sync_or_and_fetch(AL+15, 8) != 8) ++ abort (); ++ if (__sync_xor_and_fetch(AL+16, 9) != 9) ++ abort (); ++ if (__sync_nand_and_fetch(AL+17, 7) != 7) ++ abort (); ++} ++ ++static void * ++start1 (void *arg) ++{ ++ unsigned loop; ++ sleep(1); ++ ++ for (loop = 0; loop < LOOPS; loop++) ++ { ++ memcpy(AI, init_qi, sizeof(init_qi)); ++ ++ do_qi (); ++ ++ if (memcmp (AI, test_qi, sizeof(test_qi))) ++ abort (); ++ } ++ ++ return arg; /* _delete1_ */ ++} ++ ++static void * ++start2 (void *arg) ++{ ++ unsigned loop; ++ ++ for (loop = 0; loop < LOOPS; loop++) ++ { ++ memcpy(AL, init_hi, sizeof(init_hi)); ++ ++ do_hi (); ++ ++ if (memcmp (AL, test_hi, sizeof(test_hi))) ++ abort (); ++ } ++ ++ return arg; /* _delete2_ */ ++} ++ ++int ++main (int argc, char **argv) ++{ ++ pthread_t thread; ++ int i; ++ ++ i = pthread_create (&thread, NULL, start1, NULL); /* _create_ */ ++ assert (i == 0); /* _create_behind_ */ ++ ++ sleep(1); ++ ++ start2 (NULL); ++ ++ i = pthread_join (thread, NULL); /* _delete_ */ ++ assert (i == 0); ++ ++ return 0; /* _success_ */ ++} +Index: gdb-6.6/gdb/testsuite/gdb.threads/atomic-seq-threaded.exp +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ gdb-6.6/gdb/testsuite/gdb.threads/atomic-seq-threaded.exp 2007-06-18 20:24:04.000000000 +0200 +@@ -0,0 +1,110 @@ ++# atomic-seq-threaded.exp -- Test case for stepping over RISC atomic code seqs. ++# This variant testcases the code for stepping another thread while skipping ++# over the atomic sequence in the former thread ++# (STEPPING_PAST_SINGLESTEP_BREAKPOINT). ++# Copyright (C) 2007 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 2 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, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ ++ ++# Please email any bugs, comments, and/or additions to this file to: ++# bug-gdb@prep.ai.mit.edu ++ ++set testfile atomic-seq-threaded ++set srcfile ${testfile}.c ++set binfile ${objdir}/${subdir}/${testfile} ++ ++foreach opts {{} {compiler=gcc4} {FAIL}} { ++ if {$opts eq "FAIL"} { ++ return -1 ++ } ++ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug $opts]] eq "" } { ++ break ++ } ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++ ++gdb_load ${binfile} ++if ![runto_main] then { ++ fail "Can't run to main" ++ return 0 ++} ++ ++# pthread_create () will not pass even on x86_64 with software watchpoint. ++# Skip behind pthread_create () without any watchpoint active. ++ ++set line [gdb_get_line_number "_create_behind_"] ++gdb_test "tbreak $line" \ ++ "Breakpoint (\[0-9\]+) at .*$srcfile, line $line\..*" \ ++ "set breakpoint behind pthread_create ()" ++gdb_test "c" \ ++ ".*/\\* _create_behind_ \\*/.*" \ ++ "run till behind pthread_create ()" ++ ++# Without a watchpoint being software no single-stepping would be used. ++set test "Start (software) watchpoint" ++gdb_test_multiple "watch unused" $test { ++ -re "Watchpoint \[0-9\]+: unused.*$gdb_prompt $" { ++ pass $test ++ } ++ -re "Hardware watchpoint \[0-9\]+: unused.*$gdb_prompt $" { ++ # We do not test the goal but still the whole testcase should pass. ++ unsupported $test ++ } ++} ++gdb_test "set \$watchnum=\$bpnum" "" "Store the watchpoint number" ++ ++# pthread_join () will not pass even on x86_64 with software watchpoint. ++# Now pass the __sync_* () functions and remove the watchpoint. ++ ++#set line [gdb_get_line_number "_delete_"] ++#gdb_test "break $line" \ ++# "Breakpoint \[0-9\]+ at .*$srcfile, line $line\..*" \ ++# "set breakpoint at _delete_" ++#gdb_test "set \$deletenum=\$bpnum" "" "Store the _delete_ breakpoint number" ++#set line1 [gdb_get_line_number "_delete1_"] ++#gdb_test "break $line1" \ ++# "Breakpoint \[0-9\]+ at .*$srcfile, line $line1\..*" \ ++# "set breakpoint at _delete1_" ++#gdb_test "set \$delete1num=\$bpnum" "" "Store the _delete1_ breakpoint number" ++#set line2 [gdb_get_line_number "_delete2_"] ++#gdb_test "break $line2" \ ++# "Breakpoint \[0-9\]+ at .*$srcfile, line $line2\..*" \ ++# "set breakpoint at _delete2_" ++#gdb_test "set \$delete2num=\$bpnum" "" "Store the _delete2_ breakpoint number" ++#gdb_test "c" \ ++# ".*/\\* (_delete_|_delete1_|_delete2_) \\*/.*" \ ++# "run till (_delete_|_delete1_|_delete2_)" ++#gdb_test "delete \$watchnum" "" "Delete the watchpoint" ++#gdb_test "delete \$deletenum" "" "Delete the _delete_ breakpoint" ++#gdb_test "delete \$delete1num" "" "Delete the _delete1_ breakpoint" ++#gdb_test "delete \$delete2num" "" "Delete the _delete2_ breakpoint" ++ ++# Pass pthread_join () without the software watchpoint being active. ++ ++set line [gdb_get_line_number "_success_"] ++gdb_test "tbreak $line" \ ++ "Breakpoint \[0-9\]+ at .*$srcfile, line $line\..*" \ ++ "set breakpoint at _success_" ++set timeout 1800 ++gdb_test "c" \ ++ ".*/\\* _success_ \\*/.*" \ ++ "run till _success_" ++ ++gdb_test "c" \ ++ ".*Program exited normally\\..*" \ ++ "run till program exit" diff --git a/gdb-6.6-bz237572-ppc-atomic-sequence-upstream.patch b/gdb-6.6-bz237572-ppc-atomic-sequence-upstream.patch new file mode 100644 index 0000000..c215d84 --- /dev/null +++ b/gdb-6.6-bz237572-ppc-atomic-sequence-upstream.patch @@ -0,0 +1,1160 @@ +https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=235186 + +2007-01-10 Daniel Jacobowitz + + * infrun.c (singlestep_pc): New variable. + (resume): Set singlestep_pc. + (context_switch): Add a debugging message. Flush the frame cache. + (handle_inferior_event): Add debugging messages. Handle thread + hops when a software single step has completed. Let context_switch + handle flushing the frame cache. + +--- ./gdb/infrun.c 9 Jan 2007 17:58:51 -0000 1.218 ++++ ./gdb/infrun.c 10 Jan 2007 20:10:23 -0000 1.219 +@@ -469,6 +469,9 @@ static int singlestep_breakpoints_insert + /* The thread we inserted single-step breakpoints for. */ + static ptid_t singlestep_ptid; + ++/* PC when we started this single-step. */ ++static CORE_ADDR singlestep_pc; ++ + /* If another thread hit the singlestep breakpoint, we save the original + thread here so that we can resume single-stepping it later. */ + static ptid_t saved_singlestep_ptid; +@@ -563,6 +566,7 @@ resume (int step, enum target_signal sig + `wait_for_inferior' */ + singlestep_breakpoints_inserted_p = 1; + singlestep_ptid = inferior_ptid; ++ singlestep_pc = read_pc (); + } + + /* If there were any forks/vforks/execs that were caught and are +@@ -1126,6 +1130,14 @@ context_switch (struct execution_control + be lost. This may happen as a result of the target module + mishandling thread creation. */ + ++ if (debug_infrun) ++ { ++ fprintf_unfiltered (gdb_stdlog, "infrun: Switching context from %s ", ++ target_pid_to_str (inferior_ptid)); ++ fprintf_unfiltered (gdb_stdlog, "to %s\n", ++ target_pid_to_str (ecs->ptid)); ++ } ++ + if (in_thread_list (inferior_ptid) && in_thread_list (ecs->ptid)) + { /* Perform infrun state context switch: */ + /* Save infrun state for the old thread. */ +@@ -1149,6 +1161,7 @@ context_switch (struct execution_control + &ecs->current_line, &ecs->current_symtab); + } + inferior_ptid = ecs->ptid; ++ flush_cached_frames (); + } + + static void +@@ -1609,6 +1622,14 @@ handle_inferior_event (struct execution_ + } + else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) + { ++ /* We have not context switched yet, so this should be true ++ no matter which thread hit the singlestep breakpoint. */ ++ gdb_assert (ptid_equal (inferior_ptid, singlestep_ptid)); ++ if (debug_infrun) ++ fprintf_unfiltered (gdb_stdlog, "infrun: software single step " ++ "trap for %s\n", ++ target_pid_to_str (ecs->ptid)); ++ + ecs->random_signal = 0; + /* The call to in_thread_list is necessary because PTIDs sometimes + change when we go from single-threaded to multi-threaded. If +@@ -1617,9 +1638,46 @@ handle_inferior_event (struct execution_ + if (!ptid_equal (singlestep_ptid, ecs->ptid) + && in_thread_list (singlestep_ptid)) + { +- thread_hop_needed = 1; +- stepping_past_singlestep_breakpoint = 1; +- saved_singlestep_ptid = singlestep_ptid; ++ /* If the PC of the thread we were trying to single-step ++ has changed, discard this event (which we were going ++ to ignore anyway), and pretend we saw that thread ++ trap. This prevents us continuously moving the ++ single-step breakpoint forward, one instruction at a ++ time. If the PC has changed, then the thread we were ++ trying to single-step has trapped or been signalled, ++ but the event has not been reported to GDB yet. ++ ++ There might be some cases where this loses signal ++ information, if a signal has arrived at exactly the ++ same time that the PC changed, but this is the best ++ we can do with the information available. Perhaps we ++ should arrange to report all events for all threads ++ when they stop, or to re-poll the remote looking for ++ this particular thread (i.e. temporarily enable ++ schedlock). */ ++ if (read_pc_pid (singlestep_ptid) != singlestep_pc) ++ { ++ if (debug_infrun) ++ fprintf_unfiltered (gdb_stdlog, "infrun: unexpected thread," ++ " but expected thread advanced also\n"); ++ ++ /* The current context still belongs to ++ singlestep_ptid. Don't swap here, since that's ++ the context we want to use. Just fudge our ++ state and continue. */ ++ ecs->ptid = singlestep_ptid; ++ stop_pc = read_pc_pid (ecs->ptid); ++ } ++ else ++ { ++ if (debug_infrun) ++ fprintf_unfiltered (gdb_stdlog, ++ "infrun: unexpected thread\n"); ++ ++ thread_hop_needed = 1; ++ stepping_past_singlestep_breakpoint = 1; ++ saved_singlestep_ptid = singlestep_ptid; ++ } + } + } + +@@ -1702,8 +1760,6 @@ handle_inferior_event (struct execution_ + + if (deprecated_context_hook) + deprecated_context_hook (pid_to_thread_id (ecs->ptid)); +- +- flush_cached_frames (); + } + + if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) + + + +2007-04-12 Luis Machado + + * gdbarch.sh (software_single_step): Change the return type + from void to int and reformatted some comments to <= 80 + columns. + * gdbarch.c, gdbarch.h: Regenerated. + * alpha-tdep.c (alpha_software_single_step): Likewise. + * alpha-tdep.h (alpha_software_single_step): Likewise. + * arm-tdep.c (arm_software_single_step): Likewise. + * cris-tdep.c (cris_software_single_step): Likewise. + * mips-tdep.c (mips_software_single_step): Likewise. + * mips-tdep.h (mips_software_single_step): Likewise. + * rs6000-tdep.c (rs6000_software_single_step): Likewise. + * rs6000-tdep.h (rs6000_software_single_step): Likewise. + * sparc-tdep.c (sparc_software_single_step): Likewise. + * sparc-tdep.h (sparc_software_single_step): Likewise. +[REMOVED] * spu-tdep.c (spu_software_single_step): Likewise. + * infrun.c (resume): Check the return value from SOFTWARE_SINGLE_STEP + and act accordingly. + +--- ./gdb/alpha-tdep.c 27 Feb 2007 20:17:18 -0000 1.162 ++++ ./gdb/alpha-tdep.c 12 Apr 2007 14:52:19 -0000 1.163 +@@ -1518,7 +1518,7 @@ alpha_next_pc (CORE_ADDR pc) + return (pc + ALPHA_INSN_SIZE); + } + +-void ++int + alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p) + { + static CORE_ADDR next_pc; +@@ -1536,6 +1536,7 @@ alpha_software_single_step (enum target_ + remove_single_step_breakpoints (); + write_pc (next_pc); + } ++ return 1; + } + + +--- ./gdb/alpha-tdep.h 9 Jan 2007 17:58:49 -0000 1.27 ++++ ./gdb/alpha-tdep.h 12 Apr 2007 14:52:19 -0000 1.28 +@@ -107,7 +107,7 @@ struct gdbarch_tdep + }; + + extern unsigned int alpha_read_insn (CORE_ADDR pc); +-extern void alpha_software_single_step (enum target_signal, int); ++extern int alpha_software_single_step (enum target_signal, int); + extern CORE_ADDR alpha_after_prologue (CORE_ADDR pc); + + extern void alpha_mdebug_init_abi (struct gdbarch_info, struct gdbarch *); +--- ./gdb/arm-tdep.c 30 Mar 2007 22:50:33 -0000 1.225 ++++ ./gdb/arm-tdep.c 12 Apr 2007 14:52:19 -0000 1.226 +@@ -1907,7 +1907,7 @@ arm_get_next_pc (CORE_ADDR pc) + single_step() is also called just after the inferior stops. If we + had set up a simulated single-step, we undo our damage. */ + +-static void ++static int + arm_software_single_step (enum target_signal sig, int insert_bpt) + { + /* NOTE: This may insert the wrong breakpoint instruction when +@@ -1922,6 +1922,8 @@ arm_software_single_step (enum target_si + } + else + remove_single_step_breakpoints (); ++ ++ return 1; + } + + #include "bfd-in2.h" +--- ./gdb/cris-tdep.c 27 Feb 2007 20:17:18 -0000 1.138 ++++ ./gdb/cris-tdep.c 12 Apr 2007 14:52:19 -0000 1.139 +@@ -2119,7 +2119,7 @@ find_step_target (inst_env_type *inst_en + digs through the opcodes in order to find all possible targets. + Either one ordinary target or two targets for branches may be found. */ + +-static void ++static int + cris_software_single_step (enum target_signal ignore, int insert_breakpoints) + { + inst_env_type inst_env; +@@ -2152,6 +2152,8 @@ cris_software_single_step (enum target_s + } + else + remove_single_step_breakpoints (); ++ ++ return 1; + } + + /* Calculates the prefix value for quick offset addressing mode. */ +--- ./gdb/gdbarch.c 28 Feb 2007 17:34:58 -0000 1.338 ++++ ./gdb/gdbarch.c 12 Apr 2007 14:52:19 -0000 1.339 +@@ -3289,14 +3289,14 @@ gdbarch_software_single_step_p (struct g + return gdbarch->software_single_step != NULL; + } + +-void ++int + gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p) + { + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->software_single_step != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_software_single_step called\n"); +- gdbarch->software_single_step (sig, insert_breakpoints_p); ++ return gdbarch->software_single_step (sig, insert_breakpoints_p); + } + + void +--- ./gdb/gdbarch.h 8 Feb 2007 21:00:29 -0000 1.294 ++++ ./gdb/gdbarch.h 12 Apr 2007 14:52:19 -0000 1.295 +@@ -1144,14 +1144,19 @@ extern void set_gdbarch_smash_text_addre + #define SMASH_TEXT_ADDRESS(addr) (gdbarch_smash_text_address (current_gdbarch, addr)) + #endif + +-/* FIXME/cagney/2001-01-18: This should be split in two. A target method that indicates if +- the target needs software single step. An ISA method to implement it. ++/* FIXME/cagney/2001-01-18: This should be split in two. A target method that ++ indicates if the target needs software single step. An ISA method to ++ implement it. + +- FIXME/cagney/2001-01-18: This should be replaced with something that inserts breakpoints +- using the breakpoint system instead of blatting memory directly (as with rs6000). ++ FIXME/cagney/2001-01-18: This should be replaced with something that inserts ++ breakpoints using the breakpoint system instead of blatting memory directly ++ (as with rs6000). + +- FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the target can +- single step. If not, then implement single step using breakpoints. */ ++ FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the ++ target can single step. If not, then implement single step using breakpoints. ++ ++ A return value of 1 means that the software_single_step breakpoints ++ were inserted; 0 means they were not. */ + + #if defined (SOFTWARE_SINGLE_STEP) + /* Legacy for systems yet to multi-arch SOFTWARE_SINGLE_STEP */ +@@ -1168,8 +1173,8 @@ extern int gdbarch_software_single_step_ + #define SOFTWARE_SINGLE_STEP_P() (gdbarch_software_single_step_p (current_gdbarch)) + #endif + +-typedef void (gdbarch_software_single_step_ftype) (enum target_signal sig, int insert_breakpoints_p); +-extern void gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p); ++typedef int (gdbarch_software_single_step_ftype) (enum target_signal sig, int insert_breakpoints_p); ++extern int gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p); + extern void set_gdbarch_software_single_step (struct gdbarch *gdbarch, gdbarch_software_single_step_ftype *software_single_step); + #if !defined (GDB_TM_FILE) && defined (SOFTWARE_SINGLE_STEP) + #error "Non multi-arch definition of SOFTWARE_SINGLE_STEP" +--- ./gdb/gdbarch.sh 28 Feb 2007 17:35:00 -0000 1.376 ++++ ./gdb/gdbarch.sh 12 Apr 2007 14:52:19 -0000 1.377 +@@ -614,15 +614,22 @@ f:=:CORE_ADDR:addr_bits_remove:CORE_ADDR + # It is not at all clear why SMASH_TEXT_ADDRESS is not folded into + # ADDR_BITS_REMOVE. + f:=:CORE_ADDR:smash_text_address:CORE_ADDR addr:addr::core_addr_identity::0 +-# FIXME/cagney/2001-01-18: This should be split in two. A target method that indicates if +-# the target needs software single step. An ISA method to implement it. ++ ++# FIXME/cagney/2001-01-18: This should be split in two. A target method that ++# indicates if the target needs software single step. An ISA method to ++# implement it. ++# ++# FIXME/cagney/2001-01-18: This should be replaced with something that inserts ++# breakpoints using the breakpoint system instead of blatting memory directly ++# (as with rs6000). + # +-# FIXME/cagney/2001-01-18: This should be replaced with something that inserts breakpoints +-# using the breakpoint system instead of blatting memory directly (as with rs6000). ++# FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the ++# target can single step. If not, then implement single step using breakpoints. + # +-# FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the target can +-# single step. If not, then implement single step using breakpoints. +-F:=:void:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p ++# A return value of 1 means that the software_single_step breakpoints ++# were inserted; 0 means they were not. ++F:=:int:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p ++ + # Return non-zero if the processor is executing a delay slot and a + # further single-step is needed before the instruction finishes. + M::int:single_step_through_delay:struct frame_info *frame:frame +--- ./gdb/infrun.c 29 Mar 2007 07:35:39 -0000 1.225 ++++ ./gdb/infrun.c 12 Apr 2007 14:52:19 -0000 1.226 +@@ -548,14 +548,16 @@ resume (int step, enum target_signal sig + if (SOFTWARE_SINGLE_STEP_P () && step) + { + /* Do it the hard way, w/temp breakpoints */ +- SOFTWARE_SINGLE_STEP (sig, 1 /*insert-breakpoints */ ); +- /* ...and don't ask hardware to do it. */ +- step = 0; +- /* and do not pull these breakpoints until after a `wait' in +- `wait_for_inferior' */ +- singlestep_breakpoints_inserted_p = 1; +- singlestep_ptid = inferior_ptid; +- singlestep_pc = read_pc (); ++ if (SOFTWARE_SINGLE_STEP (sig, 1 /*insert-breakpoints */ )) ++ { ++ /* ...and don't ask hardware to do it. */ ++ step = 0; ++ /* and do not pull these breakpoints until after a `wait' in ++ `wait_for_inferior' */ ++ singlestep_breakpoints_inserted_p = 1; ++ singlestep_ptid = inferior_ptid; ++ singlestep_pc = read_pc (); ++ } + } + + /* If there were any forks/vforks/execs that were caught and are +@@ -1378,7 +1380,7 @@ handle_inferior_event (struct execution_ + (LONGEST) ecs->ws.value.integer)); + gdb_flush (gdb_stdout); + target_mourn_inferior (); +- singlestep_breakpoints_inserted_p = 0; /*SOFTWARE_SINGLE_STEP_P() */ ++ singlestep_breakpoints_inserted_p = 0; /* SOFTWARE_SINGLE_STEP_P() */ + stop_print_frame = 0; + stop_stepping (ecs); + return; +@@ -1398,7 +1400,7 @@ handle_inferior_event (struct execution_ + target_mourn_inferior (); + + print_stop_reason (SIGNAL_EXITED, stop_signal); +- singlestep_breakpoints_inserted_p = 0; /*SOFTWARE_SINGLE_STEP_P() */ ++ singlestep_breakpoints_inserted_p = 0; /* SOFTWARE_SINGLE_STEP_P() */ + stop_stepping (ecs); + return; + +@@ -1569,7 +1571,7 @@ handle_inferior_event (struct execution_ + if (debug_infrun) + fprintf_unfiltered (gdb_stdlog, "infrun: stepping_past_singlestep_breakpoint\n"); + /* Pull the single step breakpoints out of the target. */ +- SOFTWARE_SINGLE_STEP (0, 0); ++ (void) SOFTWARE_SINGLE_STEP (0, 0); + singlestep_breakpoints_inserted_p = 0; + + ecs->random_signal = 0; +@@ -1678,7 +1680,7 @@ handle_inferior_event (struct execution_ + if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) + { + /* Pull the single step breakpoints out of the target. */ +- SOFTWARE_SINGLE_STEP (0, 0); ++ (void) SOFTWARE_SINGLE_STEP (0, 0); + singlestep_breakpoints_inserted_p = 0; + } + +@@ -1749,7 +1751,7 @@ handle_inferior_event (struct execution_ + if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) + { + /* Pull the single step breakpoints out of the target. */ +- SOFTWARE_SINGLE_STEP (0, 0); ++ (void) SOFTWARE_SINGLE_STEP (0, 0); + singlestep_breakpoints_inserted_p = 0; + } + +--- ./gdb/mips-tdep.c 30 Mar 2007 22:50:33 -0000 1.407 ++++ ./gdb/mips-tdep.c 12 Apr 2007 14:52:19 -0000 1.408 +@@ -2204,7 +2204,7 @@ mips_addr_bits_remove (CORE_ADDR addr) + single_step is also called just after the inferior stops. If we had + set up a simulated single-step, we undo our damage. */ + +-void ++int + mips_software_single_step (enum target_signal sig, int insert_breakpoints_p) + { + CORE_ADDR pc, next_pc; +@@ -2218,6 +2218,8 @@ mips_software_single_step (enum target_s + } + else + remove_single_step_breakpoints (); ++ ++ return 1; + } + + /* Test whether the PC points to the return instruction at the +--- ./gdb/mips-tdep.h 30 Mar 2007 22:50:33 -0000 1.20 ++++ ./gdb/mips-tdep.h 12 Apr 2007 14:52:20 -0000 1.21 +@@ -100,7 +100,7 @@ enum + }; + + /* Single step based on where the current instruction will take us. */ +-extern void mips_software_single_step (enum target_signal, int); ++extern int mips_software_single_step (enum target_signal, int); + + /* Tell if the program counter value in MEMADDR is in a MIPS16 + function. */ +--- ./gdb/rs6000-tdep.c 10 Apr 2007 16:02:41 -0000 1.270 ++++ ./gdb/rs6000-tdep.c 12 Apr 2007 14:52:20 -0000 1.271 +@@ -722,7 +722,7 @@ rs6000_breakpoint_from_pc (CORE_ADDR *bp + + /* AIX does not support PT_STEP. Simulate it. */ + +-void ++int + rs6000_software_single_step (enum target_signal signal, + int insert_breakpoints_p) + { +@@ -761,6 +761,7 @@ rs6000_software_single_step (enum target + + errno = 0; /* FIXME, don't ignore errors! */ + /* What errors? {read,write}_memory call error(). */ ++ return 1; + } + + +--- ./gdb/rs6000-tdep.h 27 Feb 2007 23:04:28 -0000 1.3 ++++ ./gdb/rs6000-tdep.h 12 Apr 2007 14:52:20 -0000 1.4 +@@ -21,8 +21,8 @@ + + #include "defs.h" + +-extern void rs6000_software_single_step (enum target_signal signal, +- int insert_breakpoints_p); ++extern int rs6000_software_single_step (enum target_signal signal, ++ int insert_breakpoints_p); + + /* Hook in rs6000-tdep.c for determining the TOC address when + calling functions in the inferior. */ +--- ./gdb/sparc-tdep.c 11 Apr 2007 07:10:08 -0000 1.179 ++++ ./gdb/sparc-tdep.c 12 Apr 2007 14:52:20 -0000 1.180 +@@ -1329,7 +1329,7 @@ sparc_step_trap (unsigned long insn) + return 0; + } + +-void ++int + sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p) + { + struct gdbarch *arch = current_gdbarch; +@@ -1359,6 +1359,8 @@ sparc_software_single_step (enum target_ + } + else + remove_single_step_breakpoints (); ++ ++ return 1; + } + + static void +--- ./gdb/sparc-tdep.h 9 Jan 2007 17:58:58 -0000 1.12 ++++ ./gdb/sparc-tdep.h 12 Apr 2007 14:52:20 -0000 1.13 +@@ -167,8 +167,8 @@ extern struct sparc_frame_cache * + + + +-extern void sparc_software_single_step (enum target_signal sig, +- int insert_breakpoints_p); ++extern int sparc_software_single_step (enum target_signal sig, ++ int insert_breakpoints_p); + + extern void sparc_supply_rwindow (struct regcache *regcache, + CORE_ADDR sp, int regnum); + + + +2007-04-14 Ulrich Weigand + + * alpha-tdep.c (alpha_software_single_step): Do not call write_pc + when removing single-step breakpoints. + +--- ./gdb/alpha-tdep.c 12 Apr 2007 14:52:19 -0000 1.163 ++++ ./gdb/alpha-tdep.c 14 Apr 2007 16:17:39 -0000 1.164 +@@ -1521,7 +1521,7 @@ alpha_next_pc (CORE_ADDR pc) + int + alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p) + { +- static CORE_ADDR next_pc; ++ CORE_ADDR next_pc; + CORE_ADDR pc; + + if (insert_breakpoints_p) +@@ -1534,7 +1534,6 @@ alpha_software_single_step (enum target_ + else + { + remove_single_step_breakpoints (); +- write_pc (next_pc); + } + return 1; + } + + + +2007-04-14 Ulrich Weigand + + * gdbarch.sh (software_single_step): Remove "insert_breakpoints_p" and + "sig" arguments, add "regcache" argument. + * gdbarch.c, gdbarch.h: Regenerate. + + * infrun.c (resume): Update SOFTWARE_SINGLE_STEP call arguments. + (handle_inferior_event): Call remove_single_step_breakpoints directly + instead of calling SOFTWARE_SINGLE_STEP to remove breakpoints. + + * alpha-tdep.c (alpha_software_single_step): Update argument list. + Remove handling of !insert_breakpoints_p case. + * arm-tdep.c (arm_software_single_step): Likewise. + * cris-tdep.c (cris_software_single_step): Likewise. + * mips-tdep.c (mips_software_single_step): Likewise. + * rs6000-tdep.c (rs6000_software_single_step): Likewise. + * sparc-tdep.c (sparc_software_single_step): Likewise. +[REMOVED] * spu-tdep.c (spu_software_single_step): Likewise. + + * alpha-tdep.h (alpha_software_single_step): Update prototype. + * mips-tdep.h (mips_software_single_step): Likewise. + * rs6000-tdep.h (rs6000_software_single_step): Likewise. + * sparc-tdep.h (sparc_software_single_step): Likewise. + +--- ./gdb/alpha-tdep.c 14 Apr 2007 16:17:39 -0000 1.164 ++++ ./gdb/alpha-tdep.c 14 Apr 2007 18:10:54 -0000 1.165 +@@ -1391,10 +1391,7 @@ fp_register_sign_bit (LONGEST reg) + /* alpha_software_single_step() is called just before we want to resume + the inferior, if we want to single-step it but there is no hardware + or kernel single-step support (NetBSD on Alpha, for example). We find +- the target of the coming instruction and breakpoint it. +- +- single_step is also called just after the inferior stops. If we had +- set up a simulated single-step, we undo our damage. */ ++ the target of the coming instruction and breakpoint it. */ + + static CORE_ADDR + alpha_next_pc (CORE_ADDR pc) +@@ -1519,22 +1516,14 @@ alpha_next_pc (CORE_ADDR pc) + } + + int +-alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p) ++alpha_software_single_step (struct regcache *regcache) + { +- CORE_ADDR next_pc; +- CORE_ADDR pc; ++ CORE_ADDR pc, next_pc; + +- if (insert_breakpoints_p) +- { +- pc = read_pc (); +- next_pc = alpha_next_pc (pc); ++ pc = read_pc (); ++ next_pc = alpha_next_pc (pc); + +- insert_single_step_breakpoint (next_pc); +- } +- else +- { +- remove_single_step_breakpoints (); +- } ++ insert_single_step_breakpoint (next_pc); + return 1; + } + +--- ./gdb/alpha-tdep.h 12 Apr 2007 14:52:19 -0000 1.28 ++++ ./gdb/alpha-tdep.h 14 Apr 2007 18:10:54 -0000 1.29 +@@ -107,7 +107,7 @@ struct gdbarch_tdep + }; + + extern unsigned int alpha_read_insn (CORE_ADDR pc); +-extern int alpha_software_single_step (enum target_signal, int); ++extern int alpha_software_single_step (struct regcache *regcache); + extern CORE_ADDR alpha_after_prologue (CORE_ADDR pc); + + extern void alpha_mdebug_init_abi (struct gdbarch_info, struct gdbarch *); +--- ./gdb/arm-tdep.c 12 Apr 2007 14:52:19 -0000 1.226 ++++ ./gdb/arm-tdep.c 14 Apr 2007 18:10:54 -0000 1.227 +@@ -1902,26 +1902,17 @@ arm_get_next_pc (CORE_ADDR pc) + /* single_step() is called just before we want to resume the inferior, + if we want to single-step it but there is no hardware or kernel + single-step support. We find the target of the coming instruction +- and breakpoint it. +- +- single_step() is also called just after the inferior stops. If we +- had set up a simulated single-step, we undo our damage. */ ++ and breakpoint it. */ + + static int +-arm_software_single_step (enum target_signal sig, int insert_bpt) ++arm_software_single_step (struct regcache *regcache) + { + /* NOTE: This may insert the wrong breakpoint instruction when + single-stepping over a mode-changing instruction, if the + CPSR heuristics are used. */ + +- if (insert_bpt) +- { +- CORE_ADDR next_pc = arm_get_next_pc (read_register (ARM_PC_REGNUM)); +- +- insert_single_step_breakpoint (next_pc); +- } +- else +- remove_single_step_breakpoints (); ++ CORE_ADDR next_pc = arm_get_next_pc (read_register (ARM_PC_REGNUM)); ++ insert_single_step_breakpoint (next_pc); + + return 1; + } +--- ./gdb/cris-tdep.c 12 Apr 2007 14:52:19 -0000 1.139 ++++ ./gdb/cris-tdep.c 14 Apr 2007 18:10:54 -0000 1.140 +@@ -2120,38 +2120,33 @@ find_step_target (inst_env_type *inst_en + Either one ordinary target or two targets for branches may be found. */ + + static int +-cris_software_single_step (enum target_signal ignore, int insert_breakpoints) ++cris_software_single_step (struct regcache *regcache) + { + inst_env_type inst_env; + +- if (insert_breakpoints) +- { +- /* Analyse the present instruction environment and insert +- breakpoints. */ +- int status = find_step_target (&inst_env); +- if (status == -1) +- { +- /* Could not find a target. Things are likely to go downhill +- from here. */ +- warning (_("CRIS software single step could not find a step target.")); +- } +- else +- { +- /* Insert at most two breakpoints. One for the next PC content +- and possibly another one for a branch, jump, etc. */ +- CORE_ADDR next_pc = (CORE_ADDR) inst_env.reg[PC_REGNUM]; +- insert_single_step_breakpoint (next_pc); +- if (inst_env.branch_found +- && (CORE_ADDR) inst_env.branch_break_address != next_pc) +- { +- CORE_ADDR branch_target_address +- = (CORE_ADDR) inst_env.branch_break_address; +- insert_single_step_breakpoint (branch_target_address); +- } +- } ++ /* Analyse the present instruction environment and insert ++ breakpoints. */ ++ int status = find_step_target (&inst_env); ++ if (status == -1) ++ { ++ /* Could not find a target. Things are likely to go downhill ++ from here. */ ++ warning (_("CRIS software single step could not find a step target.")); + } + else +- remove_single_step_breakpoints (); ++ { ++ /* Insert at most two breakpoints. One for the next PC content ++ and possibly another one for a branch, jump, etc. */ ++ CORE_ADDR next_pc = (CORE_ADDR) inst_env.reg[PC_REGNUM]; ++ insert_single_step_breakpoint (next_pc); ++ if (inst_env.branch_found ++ && (CORE_ADDR) inst_env.branch_break_address != next_pc) ++ { ++ CORE_ADDR branch_target_address ++ = (CORE_ADDR) inst_env.branch_break_address; ++ insert_single_step_breakpoint (branch_target_address); ++ } ++ } + + return 1; + } +--- ./gdb/gdbarch.c 12 Apr 2007 14:52:19 -0000 1.339 ++++ ./gdb/gdbarch.c 14 Apr 2007 18:10:54 -0000 1.340 +@@ -1522,8 +1522,8 @@ gdbarch_dump (struct gdbarch *current_gd + #ifdef SOFTWARE_SINGLE_STEP + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", +- "SOFTWARE_SINGLE_STEP(sig, insert_breakpoints_p)", +- XSTRING (SOFTWARE_SINGLE_STEP (sig, insert_breakpoints_p))); ++ "SOFTWARE_SINGLE_STEP(regcache)", ++ XSTRING (SOFTWARE_SINGLE_STEP (regcache))); + #endif + fprintf_unfiltered (file, + "gdbarch_dump: software_single_step = <0x%lx>\n", +@@ -3290,13 +3290,13 @@ gdbarch_software_single_step_p (struct g + } + + int +-gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p) ++gdbarch_software_single_step (struct gdbarch *gdbarch, struct regcache *regcache) + { + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->software_single_step != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_software_single_step called\n"); +- return gdbarch->software_single_step (sig, insert_breakpoints_p); ++ return gdbarch->software_single_step (regcache); + } + + void +--- ./gdb/gdbarch.h 12 Apr 2007 14:52:19 -0000 1.295 ++++ ./gdb/gdbarch.h 14 Apr 2007 18:10:54 -0000 1.296 +@@ -1173,14 +1173,14 @@ extern int gdbarch_software_single_step_ + #define SOFTWARE_SINGLE_STEP_P() (gdbarch_software_single_step_p (current_gdbarch)) + #endif + +-typedef int (gdbarch_software_single_step_ftype) (enum target_signal sig, int insert_breakpoints_p); +-extern int gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p); ++typedef int (gdbarch_software_single_step_ftype) (struct regcache *regcache); ++extern int gdbarch_software_single_step (struct gdbarch *gdbarch, struct regcache *regcache); + extern void set_gdbarch_software_single_step (struct gdbarch *gdbarch, gdbarch_software_single_step_ftype *software_single_step); + #if !defined (GDB_TM_FILE) && defined (SOFTWARE_SINGLE_STEP) + #error "Non multi-arch definition of SOFTWARE_SINGLE_STEP" + #endif + #if !defined (SOFTWARE_SINGLE_STEP) +-#define SOFTWARE_SINGLE_STEP(sig, insert_breakpoints_p) (gdbarch_software_single_step (current_gdbarch, sig, insert_breakpoints_p)) ++#define SOFTWARE_SINGLE_STEP(regcache) (gdbarch_software_single_step (current_gdbarch, regcache)) + #endif + + /* Return non-zero if the processor is executing a delay slot and a +--- ./gdb/gdbarch.sh 12 Apr 2007 14:52:19 -0000 1.377 ++++ ./gdb/gdbarch.sh 14 Apr 2007 18:10:54 -0000 1.378 +@@ -628,7 +628,7 @@ f:=:CORE_ADDR:smash_text_address:CORE_AD + # + # A return value of 1 means that the software_single_step breakpoints + # were inserted; 0 means they were not. +-F:=:int:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p ++F:=:int:software_single_step:struct regcache *regcache:regcache + + # Return non-zero if the processor is executing a delay slot and a + # further single-step is needed before the instruction finishes. +--- ./gdb/infrun.c 13 Apr 2007 13:29:42 -0000 1.227 ++++ ./gdb/infrun.c 14 Apr 2007 18:10:54 -0000 1.228 +@@ -548,7 +548,7 @@ resume (int step, enum target_signal sig + if (SOFTWARE_SINGLE_STEP_P () && step) + { + /* Do it the hard way, w/temp breakpoints */ +- if (SOFTWARE_SINGLE_STEP (sig, 1 /*insert-breakpoints */ )) ++ if (SOFTWARE_SINGLE_STEP (current_regcache)) + { + /* ...and don't ask hardware to do it. */ + step = 0; +@@ -1571,7 +1571,7 @@ handle_inferior_event (struct execution_ + if (debug_infrun) + fprintf_unfiltered (gdb_stdlog, "infrun: stepping_past_singlestep_breakpoint\n"); + /* Pull the single step breakpoints out of the target. */ +- (void) SOFTWARE_SINGLE_STEP (0, 0); ++ remove_single_step_breakpoints (); + singlestep_breakpoints_inserted_p = 0; + + ecs->random_signal = 0; +@@ -1680,7 +1680,7 @@ handle_inferior_event (struct execution_ + if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) + { + /* Pull the single step breakpoints out of the target. */ +- (void) SOFTWARE_SINGLE_STEP (0, 0); ++ remove_single_step_breakpoints (); + singlestep_breakpoints_inserted_p = 0; + } + +@@ -1751,7 +1751,7 @@ handle_inferior_event (struct execution_ + if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) + { + /* Pull the single step breakpoints out of the target. */ +- (void) SOFTWARE_SINGLE_STEP (0, 0); ++ remove_single_step_breakpoints (); + singlestep_breakpoints_inserted_p = 0; + } + +--- ./gdb/mips-tdep.c 12 Apr 2007 14:52:19 -0000 1.408 ++++ ./gdb/mips-tdep.c 14 Apr 2007 18:10:54 -0000 1.409 +@@ -2199,26 +2199,17 @@ mips_addr_bits_remove (CORE_ADDR addr) + /* mips_software_single_step() is called just before we want to resume + the inferior, if we want to single-step it but there is no hardware + or kernel single-step support (MIPS on GNU/Linux for example). We find +- the target of the coming instruction and breakpoint it. +- +- single_step is also called just after the inferior stops. If we had +- set up a simulated single-step, we undo our damage. */ ++ the target of the coming instruction and breakpoint it. */ + + int +-mips_software_single_step (enum target_signal sig, int insert_breakpoints_p) ++mips_software_single_step (struct regcache *regcache) + { + CORE_ADDR pc, next_pc; + +- if (insert_breakpoints_p) +- { +- pc = read_register (mips_regnum (current_gdbarch)->pc); +- next_pc = mips_next_pc (pc); +- +- insert_single_step_breakpoint (next_pc); +- } +- else +- remove_single_step_breakpoints (); ++ pc = read_register (mips_regnum (current_gdbarch)->pc); ++ next_pc = mips_next_pc (pc); + ++ insert_single_step_breakpoint (next_pc); + return 1; + } + +--- ./gdb/mips-tdep.h 12 Apr 2007 14:52:20 -0000 1.21 ++++ ./gdb/mips-tdep.h 14 Apr 2007 18:10:54 -0000 1.22 +@@ -100,7 +100,7 @@ enum + }; + + /* Single step based on where the current instruction will take us. */ +-extern int mips_software_single_step (enum target_signal, int); ++extern int mips_software_single_step (struct regcache *regcache); + + /* Tell if the program counter value in MEMADDR is in a MIPS16 + function. */ +--- ./gdb/rs6000-tdep.c 12 Apr 2007 14:52:20 -0000 1.271 ++++ ./gdb/rs6000-tdep.c 14 Apr 2007 18:10:54 -0000 1.272 +@@ -723,8 +723,7 @@ rs6000_breakpoint_from_pc (CORE_ADDR *bp + /* AIX does not support PT_STEP. Simulate it. */ + + int +-rs6000_software_single_step (enum target_signal signal, +- int insert_breakpoints_p) ++rs6000_software_single_step (struct regcache *regcache) + { + CORE_ADDR dummy; + int breakp_sz; +@@ -734,30 +733,25 @@ rs6000_software_single_step (enum target + CORE_ADDR breaks[2]; + int opcode; + +- if (insert_breakpoints_p) +- { +- loc = read_pc (); ++ loc = read_pc (); + +- insn = read_memory_integer (loc, 4); ++ insn = read_memory_integer (loc, 4); + +- breaks[0] = loc + breakp_sz; +- opcode = insn >> 26; +- breaks[1] = branch_dest (opcode, insn, loc, breaks[0]); ++ breaks[0] = loc + breakp_sz; ++ opcode = insn >> 26; ++ breaks[1] = branch_dest (opcode, insn, loc, breaks[0]); + +- /* Don't put two breakpoints on the same address. */ +- if (breaks[1] == breaks[0]) +- breaks[1] = -1; ++ /* Don't put two breakpoints on the same address. */ ++ if (breaks[1] == breaks[0]) ++ breaks[1] = -1; + +- for (ii = 0; ii < 2; ++ii) +- { +- /* ignore invalid breakpoint. */ +- if (breaks[ii] == -1) +- continue; +- insert_single_step_breakpoint (breaks[ii]); +- } ++ for (ii = 0; ii < 2; ++ii) ++ { ++ /* ignore invalid breakpoint. */ ++ if (breaks[ii] == -1) ++ continue; ++ insert_single_step_breakpoint (breaks[ii]); + } +- else +- remove_single_step_breakpoints (); + + errno = 0; /* FIXME, don't ignore errors! */ + /* What errors? {read,write}_memory call error(). */ +--- ./gdb/rs6000-tdep.h 12 Apr 2007 14:52:20 -0000 1.4 ++++ ./gdb/rs6000-tdep.h 14 Apr 2007 18:10:54 -0000 1.5 +@@ -21,8 +21,7 @@ + + #include "defs.h" + +-extern int rs6000_software_single_step (enum target_signal signal, +- int insert_breakpoints_p); ++extern int rs6000_software_single_step (struct regcache *regcache); + + /* Hook in rs6000-tdep.c for determining the TOC address when + calling functions in the inferior. */ +--- ./gdb/sparc-tdep.c 12 Apr 2007 14:52:20 -0000 1.180 ++++ ./gdb/sparc-tdep.c 14 Apr 2007 18:10:54 -0000 1.181 +@@ -1330,35 +1330,30 @@ sparc_step_trap (unsigned long insn) + } + + int +-sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p) ++sparc_software_single_step (struct regcache *regcache) + { + struct gdbarch *arch = current_gdbarch; + struct gdbarch_tdep *tdep = gdbarch_tdep (arch); + CORE_ADDR npc, nnpc; + +- if (insert_breakpoints_p) +- { +- CORE_ADDR pc, orig_npc; ++ CORE_ADDR pc, orig_npc; + +- pc = sparc_address_from_register (tdep->pc_regnum); +- orig_npc = npc = sparc_address_from_register (tdep->npc_regnum); ++ pc = sparc_address_from_register (tdep->pc_regnum); ++ orig_npc = npc = sparc_address_from_register (tdep->npc_regnum); + +- /* Analyze the instruction at PC. */ +- nnpc = sparc_analyze_control_transfer (arch, pc, &npc); +- if (npc != 0) +- insert_single_step_breakpoint (npc); +- +- if (nnpc != 0) +- insert_single_step_breakpoint (nnpc); +- +- /* Assert that we have set at least one breakpoint, and that +- they're not set at the same spot - unless we're going +- from here straight to NULL, i.e. a call or jump to 0. */ +- gdb_assert (npc != 0 || nnpc != 0 || orig_npc == 0); +- gdb_assert (nnpc != npc || orig_npc == 0); +- } +- else +- remove_single_step_breakpoints (); ++ /* Analyze the instruction at PC. */ ++ nnpc = sparc_analyze_control_transfer (arch, pc, &npc); ++ if (npc != 0) ++ insert_single_step_breakpoint (npc); ++ ++ if (nnpc != 0) ++ insert_single_step_breakpoint (nnpc); ++ ++ /* Assert that we have set at least one breakpoint, and that ++ they're not set at the same spot - unless we're going ++ from here straight to NULL, i.e. a call or jump to 0. */ ++ gdb_assert (npc != 0 || nnpc != 0 || orig_npc == 0); ++ gdb_assert (nnpc != npc || orig_npc == 0); + + return 1; + } +--- ./gdb/sparc-tdep.h 12 Apr 2007 14:52:20 -0000 1.13 ++++ ./gdb/sparc-tdep.h 14 Apr 2007 18:10:54 -0000 1.14 +@@ -167,8 +167,7 @@ extern struct sparc_frame_cache * + + + +-extern int sparc_software_single_step (enum target_signal sig, +- int insert_breakpoints_p); ++extern int sparc_software_single_step (struct regcache *regcache); + + extern void sparc_supply_rwindow (struct regcache *regcache, + CORE_ADDR sp, int regnum); + + + +2007-05-11 Ulrich Weigand + + * breakpoint.c (single_step_breakpoint_inserted_here_p): New function. + (breakpoint_inserted_here_p): Call it. + (software_breakpoint_inserted_here_p): Likewise. + +--- ./gdb/breakpoint.c 3 May 2007 17:42:25 -0000 1.247 ++++ ./gdb/breakpoint.c 11 May 2007 12:44:34 -0000 1.248 +@@ -202,6 +202,8 @@ static void tcatch_command (char *arg, i + + static void ep_skip_leading_whitespace (char **s); + ++static int single_step_breakpoint_inserted_here_p (CORE_ADDR pc); ++ + /* Prototypes for exported functions. */ + + /* If FALSE, gdb will not use hardware support for watchpoints, even +@@ -1841,6 +1843,10 @@ breakpoint_inserted_here_p (CORE_ADDR pc + } + } + ++ /* Also check for software single-step breakpoints. */ ++ if (single_step_breakpoint_inserted_here_p (pc)) ++ return 1; ++ + return 0; + } + +@@ -1872,6 +1878,10 @@ software_breakpoint_inserted_here_p (COR + } + } + ++ /* Also check for software single-step breakpoints. */ ++ if (single_step_breakpoint_inserted_here_p (pc)) ++ return 1; ++ + return 0; + } + +@@ -7951,6 +7961,23 @@ remove_single_step_breakpoints (void) + } + } + ++/* Check whether a software single-step breakpoint is inserted at PC. */ ++ ++static int ++single_step_breakpoint_inserted_here_p (CORE_ADDR pc) ++{ ++ int i; ++ ++ for (i = 0; i < 2; i++) ++ { ++ struct bp_target_info *bp_tgt = single_step_breakpoints[i]; ++ if (bp_tgt && bp_tgt->placed_address == pc) ++ return 1; ++ } ++ ++ return 0; ++} ++ + + /* This help string is used for the break, hbreak, tbreak and thbreak commands. + It is defined as a macro to prevent duplication. + + + +2007-05-08 Paul Gilliam + Luis Machado + + * rs6000-tdep.c: (LWARX_MASK, LWARX_INSTRUCTION, LDARX_INSTRUCTION, + STWCX_MASK, STWCX_INSTRUCTION, STDCX_INSTRUCTION, BC_MASK, + BC_INSTRUCTION): Define. + (deal_with_atomic_sequence): New function. + (rs6000_software_single_step): Call deal_with_atomic_sequence. + (rs6000_gdbarch_init): Install deal_with_atomic_sequence as + gdbarch_software_single_step routine. + +--- ./gdb/rs6000-tdep.c 7 May 2007 01:25:07 -0000 1.274 ++++ ./gdb/rs6000-tdep.c 8 May 2007 12:49:12 -0000 1.275 +@@ -707,7 +707,95 @@ rs6000_breakpoint_from_pc (CORE_ADDR *bp + } + + +-/* AIX does not support PT_STEP. Simulate it. */ ++/* Instruction masks used during single-stepping of atomic sequences. */ ++#define LWARX_MASK 0xfc0007fe ++#define LWARX_INSTRUCTION 0x7c000028 ++#define LDARX_INSTRUCTION 0x7c0000A8 ++#define STWCX_MASK 0xfc0007ff ++#define STWCX_INSTRUCTION 0x7c00012d ++#define STDCX_INSTRUCTION 0x7c0001ad ++#define BC_MASK 0xfc000000 ++#define BC_INSTRUCTION 0x40000000 ++ ++/* Checks for an atomic sequence of instructions beginning with a LWARX/LDARX ++ instruction and ending with a STWCX/STDCX instruction. If such a sequence ++ is found, attempt to step through it. A breakpoint is placed at the end of ++ the sequence. */ ++ ++static int ++deal_with_atomic_sequence (struct regcache *regcache) ++{ ++ CORE_ADDR pc = read_pc (); ++ CORE_ADDR breaks[2] = {-1, -1}; ++ CORE_ADDR loc = pc; ++ CORE_ADDR branch_bp; /* Breakpoint at branch instruction's destination. */ ++ int insn = read_memory_integer (loc, PPC_INSN_SIZE); ++ int insn_count; ++ int index; ++ int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */ ++ const int atomic_sequence_length = 16; /* Instruction sequence length. */ ++ const int opcode = BC_INSTRUCTION; /* Branch instruction's OPcode. */ ++ int bc_insn_count = 0; /* Conditional branch instruction count. */ ++ ++ /* Assume all atomic sequences start with a lwarx/ldarx instruction. */ ++ if ((insn & LWARX_MASK) != LWARX_INSTRUCTION ++ && (insn & LWARX_MASK) != LDARX_INSTRUCTION) ++ return 0; ++ ++ /* Assume that no atomic sequence is longer than "atomic_sequence_length" ++ instructions. */ ++ for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count) ++ { ++ loc += PPC_INSN_SIZE; ++ insn = read_memory_integer (loc, PPC_INSN_SIZE); ++ ++ /* Assume that there is at most one conditional branch in the atomic ++ sequence. If a conditional branch is found, put a breakpoint in ++ its destination address. */ ++ if ((insn & BC_MASK) == BC_INSTRUCTION) ++ { ++ if (bc_insn_count >= 1) ++ return 0; /* More than one conditional branch found, fallback ++ to the standard single-step code. */ ++ ++ branch_bp = branch_dest (opcode, insn, pc, breaks[0]); ++ ++ if (branch_bp != -1) ++ { ++ breaks[1] = branch_bp; ++ bc_insn_count++; ++ last_breakpoint++; ++ } ++ } ++ ++ if ((insn & STWCX_MASK) == STWCX_INSTRUCTION ++ || (insn & STWCX_MASK) == STDCX_INSTRUCTION) ++ break; ++ } ++ ++ /* Assume that the atomic sequence ends with a stwcx/stdcx instruction. */ ++ if ((insn & STWCX_MASK) != STWCX_INSTRUCTION ++ && (insn & STWCX_MASK) != STDCX_INSTRUCTION) ++ return 0; ++ ++ loc += PPC_INSN_SIZE; ++ insn = read_memory_integer (loc, PPC_INSN_SIZE); ++ ++ /* Insert a breakpoint right after the end of the atomic sequence. */ ++ breaks[0] = loc; ++ ++ /* Check for duplicated breakpoints. */ ++ if (last_breakpoint && (breaks[1] == breaks[0])) ++ last_breakpoint = 0; ++ ++ /* Effectively inserts the breakpoints. */ ++ for (index = 0; index <= last_breakpoint; index++) ++ insert_single_step_breakpoint (breaks[index]); ++ ++ return 1; ++} ++ ++/* AIX does not support PT_STEP. Simulate it. */ + + int + rs6000_software_single_step (struct regcache *regcache) +@@ -724,6 +812,9 @@ rs6000_software_single_step (struct regc + + insn = read_memory_integer (loc, 4); + ++ if (deal_with_atomic_sequence (regcache)) ++ return 1; ++ + breaks[0] = loc + breakp_sz; + opcode = insn >> 26; + breaks[1] = branch_dest (opcode, insn, loc, breaks[0]); +@@ -3448,6 +3539,9 @@ rs6000_gdbarch_init (struct gdbarch_info + set_gdbarch_inner_than (gdbarch, core_addr_lessthan); + set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc); + ++ /* Handles single stepping of atomic sequences. */ ++ set_gdbarch_software_single_step (gdbarch, deal_with_atomic_sequence); ++ + /* Handle the 64-bit SVR4 minimal-symbol convention of using "FN" + for the descriptor and ".FN" for the entry-point -- a user + specifying "break FN" will unexpectedly end up with a breakpoint diff --git a/gdb-6.6-scheduler_locking-step-sw-watchpoints2.patch b/gdb-6.6-scheduler_locking-step-sw-watchpoints2.patch new file mode 100644 index 0000000..ef57986 --- /dev/null +++ b/gdb-6.6-scheduler_locking-step-sw-watchpoints2.patch @@ -0,0 +1,160 @@ +Index: ./gdb/inferior.h +=================================================================== +RCS file: /cvs/src/src/gdb/inferior.h,v +retrieving revision 1.83 +diff -u -p -r1.83 inferior.h +--- ./gdb/inferior.h 15 Jun 2007 22:44:55 -0000 1.83 ++++ ./gdb/inferior.h 19 Jun 2007 07:14:04 -0000 +@@ -194,7 +194,15 @@ extern void reopen_exec_file (void); + /* The `resume' routine should only be called in special circumstances. + Normally, use `proceed', which handles a lot of bookkeeping. */ + +-extern void resume (int, enum target_signal); ++enum resume_step ++ { ++ /* currently_stepping () should return non-zero for non-continue. */ ++ RESUME_STEP_CONTINUE = 0, ++ RESUME_STEP_USER, /* Stepping is intentional by the user. */ ++ RESUME_STEP_NEEDED /* Stepping only for software watchpoints. */ ++ }; ++ ++extern void resume (enum resume_step, enum target_signal); + + /* From misc files */ + +Index: ./gdb/infrun.c +=================================================================== +RCS file: /cvs/src/src/gdb/infrun.c,v +retrieving revision 1.241 +diff -u -p -r1.241 infrun.c +--- ./gdb/infrun.c 18 Jun 2007 18:23:08 -0000 1.241 ++++ ./gdb/infrun.c 19 Jun 2007 07:14:32 -0000 +@@ -76,7 +76,8 @@ static void set_schedlock_func (char *ar + + struct execution_control_state; + +-static int currently_stepping (struct execution_control_state *ecs); ++static enum resume_step currently_stepping (struct execution_control_state ++ *ecs); + + static void xdb_handle_command (char *args, int from_tty); + +@@ -466,7 +467,7 @@ static const char *scheduler_enums[] = { + schedlock_step, + NULL + }; +-static const char *scheduler_mode = schedlock_off; ++static const char *scheduler_mode = schedlock_step; + static void + show_scheduler_mode (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +@@ -496,15 +497,18 @@ set_schedlock_func (char *args, int from + STEP nonzero if we should step (zero to continue instead). + SIG is the signal to give the inferior (zero for none). */ + void +-resume (int step, enum target_signal sig) ++resume (enum resume_step step, enum target_signal sig) + { + int should_resume = 1; + struct cleanup *old_cleanups = make_cleanup (resume_cleanups, 0); + QUIT; + + if (debug_infrun) +- fprintf_unfiltered (gdb_stdlog, "infrun: resume (step=%d, signal=%d)\n", +- step, sig); ++ fprintf_unfiltered (gdb_stdlog, "infrun: resume (step=%s, signal=%d)\n", ++ (step == RESUME_STEP_CONTINUE ? "RESUME_STEP_CONTINUE" ++ : (step == RESUME_STEP_USER ? "RESUME_STEP_USER" ++ : "RESUME_STEP_NEEDED")), ++ sig); + + /* FIXME: calling breakpoint_here_p (read_pc ()) three times! */ + +@@ -595,7 +599,8 @@ a command like `return' or `jump' to con + + if ((scheduler_mode == schedlock_on) + || (scheduler_mode == schedlock_step +- && (step || singlestep_breakpoints_inserted_p))) ++ && (step == RESUME_STEP_USER ++ || singlestep_breakpoints_inserted_p))) + { + /* User-settable 'scheduler' mode requires solo thread resume. */ + resume_ptid = inferior_ptid; +@@ -705,7 +710,8 @@ static CORE_ADDR prev_pc; + void + proceed (CORE_ADDR addr, enum target_signal siggnal, int step) + { +- int oneproc = 0; ++ enum resume_step resume_step = (step ? RESUME_STEP_USER ++ : RESUME_STEP_CONTINUE); + + if (step > 0) + step_start_function = find_pc_function (read_pc ()); +@@ -719,13 +725,13 @@ proceed (CORE_ADDR addr, enum target_sig + step one instruction before inserting breakpoints so that + we do not stop right away (and report a second hit at this + breakpoint). */ +- oneproc = 1; ++ resume_step = RESUME_STEP_USER; + else if (gdbarch_single_step_through_delay_p (current_gdbarch) + && gdbarch_single_step_through_delay (current_gdbarch, + get_current_frame ())) + /* We stepped onto an instruction that needs to be stepped + again before re-inserting the breakpoint, do so. */ +- oneproc = 1; ++ resume_step = RESUME_STEP_USER; + } + else + { +@@ -749,9 +755,9 @@ proceed (CORE_ADDR addr, enum target_sig + that reported the most recent event. If a step-over is required + it returns TRUE and sets the current thread to the old thread. */ + if (prepare_to_proceed () && breakpoint_here_p (read_pc ())) +- oneproc = 1; ++ resume_step = RESUME_STEP_USER; + +- if (oneproc) ++ if (resume_step == RESUME_STEP_USER) + /* We will get a trace trap after one instruction. + Continue it automatically and insert breakpoints then. */ + trap_expected = 1; +@@ -800,8 +806,11 @@ proceed (CORE_ADDR addr, enum target_sig + updated correctly when the inferior is stopped. */ + prev_pc = read_pc (); + ++ if (resume_step == RESUME_STEP_CONTINUE && bpstat_should_step ()) ++ resume_step = RESUME_STEP_NEEDED; ++ + /* Resume inferior. */ +- resume (oneproc || step || bpstat_should_step (), stop_signal); ++ resume (resume_step, stop_signal); + + /* Wait for it to stop (if not standalone) + and in any case decode why it stopped, and act accordingly. */ +@@ -2695,14 +2704,20 @@ process_event_stop_test: + + /* Are we in the middle of stepping? */ + +-static int ++static enum resume_step + currently_stepping (struct execution_control_state *ecs) + { +- return ((!ecs->handling_longjmp +- && ((step_range_end && step_resume_breakpoint == NULL) +- || trap_expected)) +- || ecs->stepping_through_solib_after_catch +- || bpstat_should_step ()); ++ if (!ecs->handling_longjmp ++ && ((step_range_end && step_resume_breakpoint == NULL) || trap_expected)) ++ return RESUME_STEP_USER; ++ ++ if (ecs->stepping_through_solib_after_catch) ++ return RESUME_STEP_USER; ++ ++ if (bpstat_should_step ()) ++ return RESUME_STEP_NEEDED; ++ ++ return RESUME_STEP_CONTINUE; + } + + /* Subroutine call with source code we should not step over. Do step diff --git a/gdb-6.6-step-thread-exit.patch b/gdb-6.6-step-thread-exit.patch new file mode 100644 index 0000000..5e765c6 --- /dev/null +++ b/gdb-6.6-step-thread-exit.patch @@ -0,0 +1,80 @@ +Index: ./gdb/linux-nat.c +=================================================================== +RCS file: /cvs/src/src/gdb/linux-nat.c,v +retrieving revision 1.64 +diff -u -p -r1.64 linux-nat.c +--- ./gdb/linux-nat.c 16 Jun 2007 17:16:25 -0000 1.64 ++++ ./gdb/linux-nat.c 18 Jun 2007 12:53:41 -0000 +@@ -1109,15 +1109,17 @@ resume_set_callback (struct lwp_info *lp + } + + static void +-linux_nat_resume (ptid_t ptid, int step, enum target_signal signo) ++linux_nat_resume (ptid_t ptid, int step_int, enum target_signal signo) + { + struct lwp_info *lp; + int resume_all; ++ enum resume_step step = step_int; + + if (debug_linux_nat) + fprintf_unfiltered (gdb_stdlog, + "LLR: Preparing to %s %s, %s, inferior_ptid %s\n", +- step ? "step" : "resume", ++ (step == RESUME_STEP_NEEDED ++ ? "needed" : (step ? "step" : "resume")), + target_pid_to_str (ptid), + signo ? strsignal (signo) : "0", + target_pid_to_str (inferior_ptid)); +@@ -2077,6 +2082,9 @@ retry: + /* Check if the thread has exited. */ + if ((WIFEXITED (status) || WIFSIGNALED (status)) && num_lwps > 1) + { ++ enum resume_step step = lp->step; ++ pid_t pid = GET_PID (lp->ptid); ++ + /* If this is the main thread, we must stop all threads and + verify if they are still alive. This is because in the nptl + thread model, there is no signal issued for exiting LWPs +@@ -2095,6 +2103,10 @@ retry: + fprintf_unfiltered (gdb_stdlog, + "LLW: %s exited.\n", + target_pid_to_str (lp->ptid)); ++ /* Backward compatibility with: ++ gdb-6.3-step-thread-exit-20050211.patch */ ++ if (step == RESUME_STEP_USER) ++ printf_unfiltered ("[Stepped over thread exit]\n"); + + exit_lwp (lp); + +@@ -2105,8 +2117,29 @@ retry: + ignored. */ + if (num_lwps > 0) + { +- /* Make sure there is at least one thread running. */ +- gdb_assert (iterate_over_lwps (running_callback, NULL)); ++ if (step == RESUME_STEP_USER) ++ { ++ /* Now stop the closest LWP's ... */ ++ lp = find_lwp_pid (pid_to_ptid (pid)); ++ if (!lp) ++ lp = lwp_list; ++ errno = 0; ++ ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, ++ (void *) (unsigned long) SIGSTOP); ++ if (debug_linux_nat) ++ fprintf_unfiltered (gdb_stdlog, ++ "PTRACE_CONT %s, 0, 0 (%s)\n", ++ target_pid_to_str (lp->ptid), ++ errno ? safe_strerror (errno) ++ : "OK"); ++ /* Avoid the silent `delayed SIGSTOP' handling. */ ++ lp->signalled = 0; ++ } ++ else ++ { ++ /* Make sure there is at least one thread running. */ ++ gdb_assert (iterate_over_lwps (running_callback, NULL)); ++ } + + /* Discard the event. */ + status = 0; diff --git a/gdb.spec b/gdb.spec index 22641b9..96521f6 100644 --- a/gdb.spec +++ b/gdb.spec @@ -11,7 +11,7 @@ Name: gdb Version: 6.6 # The release always contains a leading reserved number, start it at 1. -Release: 16%{?dist} +Release: 17%{?dist} License: GPL Group: Development/Debuggers @@ -74,8 +74,9 @@ Patch108: gdb-6.3-ppc64section-20041026.patch # correct symbol is found. Patch111: gdb-6.3-ppc64displaysymbol-20041124.patch -# Fix stepping in threads -Patch112: gdb-6.3-thread-step-20041207.patch +# Use upstream `set scheduler-locking step' as default. +# Fix upstream `set scheduler-locking step' vs. upstream PPC atomic seqs. +Patch112: gdb-6.6-scheduler_locking-step-sw-watchpoints2.patch # Threaded watchpoint support Patch113: gdb-6.3-threaded-watchpoints-20041213.patch @@ -128,8 +129,9 @@ Patch139: gdb-6.3-dwattype0-20050201.patch # Fix gcore for threads Patch140: gdb-6.3-gcore-thread-20050204.patch -# Fix stepping over thread exit -Patch141: gdb-6.3-step-thread-exit-20050211.patch +# Stop while intentionally stepping and the thread exit is met. +Patch141: gdb-6.6-step-thread-exit.patch +Patch259: gdb-6.3-step-thread-exit-20050211-test.patch # Prevent gdb from being pushed into background Patch142: gdb-6.3-terminal-fix-20050214.patch @@ -350,6 +352,10 @@ Patch254: gdb-6.6-testsuite-timeouts.patch # Fix attaching during a pending signal being delivered. Patch256: gdb-6.6-bz233852-attach-signalled.patch +# Support for stepping over PPC atomic instruction sequences (BZ 237572). +Patch257: gdb-6.6-bz237572-ppc-atomic-sequence-upstream.patch +Patch258: gdb-6.6-bz237572-ppc-atomic-sequence-test.patch + BuildRequires: ncurses-devel glibc-devel gcc make gzip texinfo dejagnu gettext BuildRequires: flex bison sharutils expat-devel @@ -418,6 +424,7 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c %patch139 -p1 %patch140 -p1 %patch141 -p1 +%patch259 -p1 %patch142 -p1 %patch145 -p1 %patch147 -p1 @@ -494,6 +501,8 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c %patch251 -p1 %patch254 -p1 %patch256 -p1 +%patch257 -p1 +%patch258 -p1 # Change the version that gets printed at GDB startup, so it is RedHat # specific. @@ -643,6 +652,10 @@ fi # don't include the files in include, they are part of binutils %changelog +* Thu Jun 21 2007 Jan Kratochvil - 6.6-17 +- Support for stepping over PPC atomic instruction sequences (BZ 237572). +- `set scheduler-locking step' is no longer enforced but it is now default. + * Wed Jun 20 2007 Jan Kratochvil - 6.6-16 - Fix attaching a stopped process on expected + upstream kernels (BZ 233852). - Fix attaching during a pending signal being delivered.