aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog15
-rw-r--r--gdb/breakpoint.c20
-rw-r--r--gdb/infrun.c15
-rw-r--r--gdb/testsuite/ChangeLog11
-rw-r--r--gdb/testsuite/gdb.base/foll-fork.exp193
5 files changed, 182 insertions, 72 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 21bcb7f..04ee3ef 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,18 @@
+2014-06-18 Don Breazeal <donb@codesourcery.com>
+
+ * breakpoint.c (set_longjmp_breakpoint): Call
+ momentary_breakpoint_from_master with additional argument.
+ (set_longjmp_breakpoint_for_call_dummy): Call
+ momentary_breakpoint_from_master with additional argument.
+ (set_std_terminate_breakpoint): Call
+ momentary_breakpoint_from_master with additional argument.
+ (momentary_breakpoint_from_master): Add argument to function
+ definition and use it to initialize structure member flag.
+ (clone_momentary_breakpoint): Call
+ momentary_breakpoint_from_master with additional argument.
+ * infrun.c (follow_inferior_reset_breakpoints): Clear structure
+ member flags set in momentary_breakpoint_from_master.
+
2014-06-18 Gary Benson <gbenson@redhat.com>
* i386-nat.c (i386_show_dr): Renamed to
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 2240f08..f3e6283 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -154,7 +154,8 @@ struct breakpoint *set_raw_breakpoint (struct gdbarch *gdbarch,
static struct breakpoint *
momentary_breakpoint_from_master (struct breakpoint *orig,
enum bptype type,
- const struct breakpoint_ops *ops);
+ const struct breakpoint_ops *ops,
+ int loc_enabled);
static void breakpoint_adjustment_warning (CORE_ADDR, CORE_ADDR, int, int);
@@ -7390,7 +7391,7 @@ set_longjmp_breakpoint (struct thread_info *tp, struct frame_id frame)
/* longjmp_breakpoint_ops ensures INITIATING_FRAME is cleared again
after their removal. */
clone = momentary_breakpoint_from_master (b, type,
- &longjmp_breakpoint_ops);
+ &longjmp_breakpoint_ops, 1);
clone->thread = thread;
}
@@ -7440,7 +7441,8 @@ set_longjmp_breakpoint_for_call_dummy (void)
struct breakpoint *new_b;
new_b = momentary_breakpoint_from_master (b, bp_longjmp_call_dummy,
- &momentary_breakpoint_ops);
+ &momentary_breakpoint_ops,
+ 1);
new_b->thread = pid_to_thread_id (inferior_ptid);
/* Link NEW_B into the chain of RETVAL breakpoints. */
@@ -7533,7 +7535,7 @@ set_std_terminate_breakpoint (void)
&& b->type == bp_std_terminate_master)
{
momentary_breakpoint_from_master (b, bp_std_terminate,
- &momentary_breakpoint_ops);
+ &momentary_breakpoint_ops, 1);
}
}
@@ -9052,13 +9054,14 @@ set_momentary_breakpoint (struct gdbarch *gdbarch, struct symtab_and_line sal,
}
/* Make a momentary breakpoint based on the master breakpoint ORIG.
- The new breakpoint will have type TYPE, and use OPS as it
- breakpoint_ops. */
+ The new breakpoint will have type TYPE, use OPS as its
+ breakpoint_ops, and will set enabled to LOC_ENABLED. */
static struct breakpoint *
momentary_breakpoint_from_master (struct breakpoint *orig,
enum bptype type,
- const struct breakpoint_ops *ops)
+ const struct breakpoint_ops *ops,
+ int loc_enabled)
{
struct breakpoint *copy;
@@ -9074,6 +9077,7 @@ momentary_breakpoint_from_master (struct breakpoint *orig,
copy->loc->probe = orig->loc->probe;
copy->loc->line_number = orig->loc->line_number;
copy->loc->symtab = orig->loc->symtab;
+ copy->loc->enabled = loc_enabled;
copy->frame_id = orig->frame_id;
copy->thread = orig->thread;
copy->pspace = orig->pspace;
@@ -9096,7 +9100,7 @@ clone_momentary_breakpoint (struct breakpoint *orig)
if (orig == NULL)
return NULL;
- return momentary_breakpoint_from_master (orig, orig->type, orig->ops);
+ return momentary_breakpoint_from_master (orig, orig->type, orig->ops, 0);
}
struct breakpoint *
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 47604c7..4e808d9 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -569,7 +569,9 @@ follow_inferior_reset_breakpoints (void)
/* Was there a step_resume breakpoint? (There was if the user
did a "next" at the fork() call.) If so, explicitly reset its
- thread number.
+ thread number. Cloned step_resume breakpoints are disabled on
+ creation, so enable it here now that it is associated with the
+ correct thread.
step_resumes are a form of bp that are made to be per-thread.
Since we created the step_resume bp when the parent process
@@ -579,10 +581,17 @@ follow_inferior_reset_breakpoints (void)
it is for, or it'll be ignored when it triggers. */
if (tp->control.step_resume_breakpoint)
- breakpoint_re_set_thread (tp->control.step_resume_breakpoint);
+ {
+ breakpoint_re_set_thread (tp->control.step_resume_breakpoint);
+ tp->control.step_resume_breakpoint->loc->enabled = 1;
+ }
+ /* Treat exception_resume breakpoints like step_resume breakpoints. */
if (tp->control.exception_resume_breakpoint)
- breakpoint_re_set_thread (tp->control.exception_resume_breakpoint);
+ {
+ breakpoint_re_set_thread (tp->control.exception_resume_breakpoint);
+ tp->control.exception_resume_breakpoint->loc->enabled = 1;
+ }
/* Reinsert all breakpoints in the child. The user may have set
breakpoints after catching the fork, in which case those
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index c6385cd..bbd3243 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,14 @@
+2014-06-18 Don Breazeal <donb@codesourcery.com>
+
+ * gdb.base/foll-fork.exp (default_fork_parent_follow):
+ Deleted procedure.
+ (explicit_fork_parent_follow): Deleted procedure.
+ (explicit_fork_child_follow): Deleted procedure.
+ (test_follow_fork): New procedure.
+ (do_fork_tests): Replace calls to deleted procedures with
+ calls to test_follow_fork and reset GDB for subsequent
+ procedure calls.
+
2014-06-17 Yao Qi <yao@codesourcery.com>
* gdb.base/wchar.exp: Set $cent to \u00A2 if "host-charset" is
diff --git a/gdb/testsuite/gdb.base/foll-fork.exp b/gdb/testsuite/gdb.base/foll-fork.exp
index e1201d7..ad8b750 100644
--- a/gdb/testsuite/gdb.base/foll-fork.exp
+++ b/gdb/testsuite/gdb.base/foll-fork.exp
@@ -53,60 +53,130 @@ proc check_fork_catchpoints {} {
}
}
-proc default_fork_parent_follow {} {
+# Test follow-fork to ensure that the correct process is followed, that
+# the followed process stops where it is expected to stop, that processes
+# are detached (or not) as expected, and that the inferior list has the
+# expected contents after following the fork. WHO is the argument to
+# the 'set follow-fork-mode' command, DETACH is the argument to the
+# 'set detach-on-fork' command, and CMD is the GDB command used to
+# execute the program past the fork. If the value of WHO or DETACH is
+# 'default', the corresponding GDB command is skipped for that test.
+# The value of CMD must be either 'next 2' or 'continue'.
+proc test_follow_fork { who detach cmd } {
global gdb_prompt
+ global srcfile
+ global testfile
- gdb_test "show follow-fork" \
- "Debugger response to a program call of fork or vfork is \"parent\".*" \
- "default show parent follow, no catchpoints"
+ with_test_prefix "follow $who, detach $detach, command \"$cmd\"" {
- gdb_test "next 2" \
- "Detaching after fork from.*" \
- "default parent follow, no catchpoints"
+ # Start a new debugger session each time so defaults are legitimate.
+ clean_restart $testfile
- # The child has been detached; allow time for any output it might
- # generate to arrive, so that output doesn't get confused with
- # any expected debugger output from a subsequent testpoint.
- #
- exec sleep 1
-}
+ if ![runto_main] {
+ untested "could not run to main"
+ return -1
+ }
-proc explicit_fork_parent_follow {} {
- global gdb_prompt
+ # The "Detaching..." and "Attaching..." messages may be hidden by
+ # default.
+ gdb_test_no_output "set verbose"
- gdb_test_no_output "set follow-fork parent"
+ # Set follow-fork-mode if we aren't using the default.
+ if {$who == "default"} {
+ set who "parent"
+ } else {
+ gdb_test_no_output "set follow-fork $who"
+ }
- gdb_test "show follow-fork" \
- "Debugger response to a program call of fork or vfork is \"parent\"." \
- "explicit show parent follow, no catchpoints"
+ gdb_test "show follow-fork" \
+ "Debugger response to a program call of fork or vfork is \"$who\"." \
+ "show follow-fork"
- gdb_test "next 2" "Detaching after fork from.*" \
- "explicit parent follow, no catchpoints"
+ # Set detach-on-fork mode if we aren't using the default.
+ if {$detach == "default"} {
+ set detach "on"
+ } else {
+ gdb_test_no_output "set detach-on-fork $detach"
+ }
- # The child has been detached; allow time for any output it might
- # generate to arrive, so that output doesn't get confused with
- # any expected debugger output from a subsequent testpoint.
- #
- exec sleep 1
-}
+ gdb_test "show detach-on-fork" \
+ "Whether gdb will detach.* fork is $detach." \
+ "show detach-on-fork"
+
+ # Set a breakpoint after the fork if we aren't single-stepping
+ # past the fork.
+ if {$cmd == "continue"} {
+ set bp_after_fork [gdb_get_line_number "set breakpoint here"]
+ gdb_test "break ${srcfile}:$bp_after_fork" \
+ "Breakpoint.*, line $bp_after_fork.*" \
+ "set breakpoint after fork"
+ }
-proc explicit_fork_child_follow {} {
- global gdb_prompt
+ # Set up the output we expect to see after we run.
+ set expected_re ""
+ if {$who == "child"} {
+ set expected_re "Attaching after.* fork to.*set breakpoint here.*"
+ } elseif {$who == "parent" && $detach == "on"} {
+ set expected_re "Detaching after fork from .*set breakpoint here.*"
+ } else {
+ set expected_re ".*set breakpoint here.*"
+ }
- gdb_test_no_output "set follow-fork child"
+ # Test running past and following the fork, using the parameters
+ # set above.
+ gdb_test $cmd $expected_re "$cmd past fork"
- gdb_test "show follow-fork" \
- "Debugger response to a program call of fork or vfork is \"child\"." \
- "explicit show child follow, no catchpoints"
+ # Check that we have the inferiors arranged correctly after
+ # following the fork.
+ set resume_unfollowed 0
+ if {$who == "parent" && $detach == "on"} {
- gdb_test "next 2" "Attaching after.* fork to.*" \
- "explicit child follow, no catchpoints"
+ # Follow parent / detach child: the only inferior is the parent.
+ gdb_test "info inferiors" "\\* 1 .* process.*" \
+ "info inferiors"
- # The child has been detached; allow time for any output it might
- # generate to arrive, so that output doesn't get confused with
- # any gdb_expected debugger output from a subsequent testpoint.
- #
- exec sleep 1
+ } elseif {$who == "parent" && $detach == "off"} {
+
+ # Follow parent / keep child: two inferiors under debug, the
+ # parent is the current inferior.
+ gdb_test "info inferiors" " 2 .*process.*\\* 1 .*process.*" \
+ "info inferiors"
+
+ gdb_test "inferior 2" "Switching to inferior 2 .*"
+ set resume_unfollowed 1
+
+ } elseif {$who == "child" && $detach == "on"} {
+
+ # Follow child / detach parent: the child is under debug and is
+ # the current inferior. The parent is listed but is not under
+ # debug.
+ gdb_test "info inferiors" "\\* 2 .*process.* 1 .*<null>.*" \
+ "info inferiors"
+
+ } elseif {$who == "child" && $detach == "off"} {
+
+ # Follow child / keep parent: two inferiors under debug, the
+ # child is the current inferior.
+ gdb_test "info inferiors" "\\* 2 .*process.* 1 .*process.*" \
+ "info inferiors"
+
+ gdb_test "inferior 1" "Switching to inferior 1 .*"
+ set resume_unfollowed 1
+ }
+
+ if {$resume_unfollowed == 1} {
+ if {$cmd == "next 2"} {
+
+ gdb_continue_to_end "continue unfollowed inferior to end"
+
+ } elseif {$cmd == "continue"} {
+
+ gdb_continue_to_breakpoint \
+ "continue unfollowed inferior to bp" \
+ ".* set breakpoint here.*"
+ }
+ }
+ }
}
proc catch_fork_child_follow {} {
@@ -254,6 +324,7 @@ proc tcatch_fork_parent_follow {} {
proc do_fork_tests {} {
global gdb_prompt
+ global testfile
# Verify that help is available for "set follow-fork-mode".
#
@@ -286,31 +357,31 @@ By default, the debugger will follow the parent process..*" \
# fork-following is supported.
if [runto_main] then { check_fork_catchpoints }
- # Test the default behaviour, which is to follow the parent of a
- # fork, and detach from the child. Do this without catchpoints.
+ # Test the basic follow-fork functionality using all combinations of
+ # values for follow-fork-mode and detach-on-fork, using either a
+ # breakpoint or single-step to execute past the fork.
#
- if [runto_main] then { default_fork_parent_follow }
-
- # Test the ability to explicitly follow the parent of a fork, and
- # detach from the child. Do this without catchpoints.
- #
- if [runto_main] then { explicit_fork_parent_follow }
+ # The first loop should be sufficient to test the defaults. There
+ # is no need to test using the defaults in other permutations (e.g.
+ # "default" "on", "parent" "default", etc.).
+ foreach cmd {"next 2" "continue"} {
+ test_follow_fork "default" "default" $cmd
+ }
- # Test the ability to follow the child of a fork, and detach from
- # the parent. Do this without catchpoints.
- #
- if [runto_main] then { explicit_fork_child_follow }
+ # Now test all explicit permutations.
+ foreach who {"parent" "child"} {
+ foreach detach {"on" "off"} {
+ foreach cmd {"next 2" "continue"} {
+ test_follow_fork $who $detach $cmd
+ }
+ }
+ }
- # Test the ability to follow both child and parent of a fork. Do
- # this without catchpoints.
- # ??rehrauer: NYI. Will add testpoints here when implemented.
- #
+ # Catchpoint tests.
- # Test the ability to have the debugger ask the user at fork-time
- # whether to follow the parent, child or both. Do this without
- # catchpoints.
- # ??rehrauer: NYI. Will add testpoints here when implemented.
- #
+ # Restart to eliminate any effects of the follow-fork tests.
+ clean_restart $testfile
+ gdb_test_no_output "set verbose"
# Test the ability to catch a fork, specify that the child be
# followed, and continue. Make the catchpoint permanent.