Commit | Line | Data |
---|---|---|
b811d2c2 | 1 | # Copyright 2018-2020 Free Software Foundation, Inc. |
9d4a934c AB |
2 | |
3 | # This program is free software; you can redistribute it and/or modify | |
4 | # it under the terms of the GNU General Public License as published by | |
5 | # the Free Software Foundation; either version 3 of the License, or | |
6 | # (at your option) any later version. | |
7 | # | |
8 | # This program is distributed in the hope that it will be useful, | |
9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | # GNU General Public License for more details. | |
12 | # | |
13 | # You should have received a copy of the GNU General Public License | |
14 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
15 | ||
16 | # This test is about restarting execution of a forked application when | |
17 | # using gdb extended remote target. | |
18 | # | |
19 | # There are two issues that the test tries to expose in GDB: | |
20 | # | |
21 | # 1. GDB would throw an assertion upon reconnecting to a remote target | |
22 | # if there was more than one inferior already active in GDB, and | |
23 | # | |
24 | # 2. GDB would not prune transient inferiors from the inferior list | |
25 | # when reconnecting to a remote target. So, for example, an inferior | |
26 | # created by GDB to track the child of a fork would usually be removed | |
27 | # from the inferior list once the child exited. However, reconnecting | |
28 | # to a remote target would result in the child inferior remaining in | |
29 | # the inferior list. | |
30 | ||
31 | # This test is only for extended remote targets. | |
32 | if {[target_info gdb_protocol] != "extended-remote"} { | |
33 | continue | |
34 | } | |
35 | ||
36 | # This test also makes use of 'detach-on-fork' which is not supported | |
37 | # on all platforms. | |
38 | if { ![istarget "*-*-linux*"] && ![istarget "*-*-openbsd*"] } then { | |
39 | continue | |
40 | } | |
41 | ||
42 | # And we need to be able to reconnect to gdbserver. | |
43 | set gdbserver_reconnect_p 1 | |
44 | if { [info proc gdb_reconnect] == "" } { | |
45 | return 0 | |
46 | } | |
47 | ||
48 | standard_testfile | |
49 | ||
50 | if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} { | |
51 | return -1 | |
52 | } | |
53 | ||
54 | # Core of the test. DO_KILL_P controls whether we kill one of the | |
55 | # inferiors before reconnecting. And FOLLOW_CHILD_P controls whether | |
56 | # we follow the child or the parent at the fork. | |
57 | proc test_reload { do_kill_p follow_child_p } { | |
58 | global decimal | |
59 | global binfile | |
60 | ||
61 | clean_restart ${binfile} | |
62 | ||
63 | if ![runto_main] then { | |
64 | fail "can't run to main" | |
65 | return 0 | |
66 | } | |
67 | ||
68 | # Set detach-on-fork off | |
69 | gdb_test_no_output "set detach-on-fork off" | |
70 | ||
71 | set live_inf_ptn "process $decimal" | |
72 | set dead_inf_ptn "<null>" | |
73 | ||
74 | if ${follow_child_p} { | |
75 | gdb_test_no_output "set follow-fork child" | |
76 | set parent_prefix " " | |
77 | set child_prefix "\\*" | |
78 | set parent_inf_after_kill_ptn ${live_inf_ptn} | |
79 | set child_inf_after_kill_ptn ${dead_inf_ptn} | |
80 | } else { | |
81 | gdb_test_no_output "set follow-fork parent" | |
82 | set parent_prefix "\\*" | |
83 | set child_prefix " " | |
84 | set parent_inf_after_kill_ptn ${dead_inf_ptn} | |
85 | set child_inf_after_kill_ptn ${live_inf_ptn} | |
86 | } | |
87 | ||
88 | gdb_breakpoint "breakpt" | |
89 | gdb_continue_to_breakpoint "breakpt" | |
90 | ||
91 | # Check we have the expected inferiors. | |
92 | gdb_test "info inferiors" \ | |
93 | [multi_line \ | |
94 | " Num Description Executable.*" \ | |
95 | "${parent_prefix} 1 +${live_inf_ptn} \[^\r\n\]+" \ | |
96 | "${child_prefix} 2 +${live_inf_ptn} \[^\r\n\]+" ] \ | |
97 | "Check inferiors at breakpoint" | |
98 | ||
99 | if { $do_kill_p } { | |
100 | # (Optional) Kill one of the inferiors. | |
101 | gdb_test "kill" \ | |
102 | "" \ | |
103 | "Kill inferior" \ | |
104 | "Kill the program being debugged.*y or n. $" \ | |
105 | "y" | |
106 | ||
107 | # Check the first inferior really did die. | |
108 | gdb_test "info inferiors" \ | |
109 | [multi_line \ | |
110 | " Num Description Executable.*" \ | |
111 | "${parent_prefix} 1 +${parent_inf_after_kill_ptn} \[^\r\n\]+" \ | |
112 | "${child_prefix} 2 +${child_inf_after_kill_ptn} \[^\r\n\]+" ] \ | |
113 | "Check inferior was killed" | |
114 | } | |
115 | ||
78f2c40a PA |
116 | # Disconnect, and reconnect to the target. |
117 | gdb_test "disconnect" ".*" | |
118 | ||
9d4a934c AB |
119 | if { [gdb_reconnect] == 0 } { |
120 | pass "reconnect after fork" | |
121 | } else { | |
122 | fail "reconnect after fork" | |
123 | } | |
124 | } | |
125 | ||
126 | # Run all combinations of the test. | |
127 | foreach do_kill_p [list 1 0] { | |
128 | foreach follow_child_p [list 1 0] { | |
129 | with_test_prefix \ | |
130 | "kill: ${do_kill_p}, follow-child ${follow_child_p}" { | |
131 | test_reload ${do_kill_p} ${follow_child_p} | |
132 | } | |
133 | } | |
134 | } |