- Support for stepping over PPC atomic instruction sequences (BZ 237572).
- `set scheduler-locking step' is no longer enforced but it is now default.
This commit is contained in:
parent
4e636f8028
commit
5a72cdabf8
178
gdb-6.3-step-thread-exit-20050211-test.patch
Normal file
178
gdb-6.3-step-thread-exit-20050211-test.patch
Normal file
@ -0,0 +1,178 @@
|
||||
2005-02-11 Jeff Johnston <jjohnstn@redhat.com>
|
||||
|
||||
* 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 <pthread.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+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
|
||||
+ }
|
||||
+}
|
||||
+
|
@ -1,433 +0,0 @@
|
||||
2005-02-11 Jeff Johnston <jjohnstn@redhat.com>
|
||||
|
||||
* 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 <pthread.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+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
|
@ -1,58 +0,0 @@
|
||||
2004-12-07 Jeff Johnston <jjohnstn@redhat.com>
|
||||
|
||||
* 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. */
|
291
gdb-6.6-bz237572-ppc-atomic-sequence-test.patch
Normal file
291
gdb-6.6-bz237572-ppc-atomic-sequence-test.patch
Normal file
@ -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 <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <pthread.h>
|
||||
+#include <assert.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+#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"
|
1160
gdb-6.6-bz237572-ppc-atomic-sequence-upstream.patch
Normal file
1160
gdb-6.6-bz237572-ppc-atomic-sequence-upstream.patch
Normal file
File diff suppressed because it is too large
Load Diff
160
gdb-6.6-scheduler_locking-step-sw-watchpoints2.patch
Normal file
160
gdb-6.6-scheduler_locking-step-sw-watchpoints2.patch
Normal file
@ -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
|
80
gdb-6.6-step-thread-exit.patch
Normal file
80
gdb-6.6-step-thread-exit.patch
Normal file
@ -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;
|
23
gdb.spec
23
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 <jan.kratochvil@redhat.com> - 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 <jan.kratochvil@redhat.com> - 6.6-16
|
||||
- Fix attaching a stopped process on expected + upstream kernels (BZ 233852).
|
||||
- Fix attaching during a pending signal being delivered.
|
||||
|
Loading…
Reference in New Issue
Block a user