Skip to content

Commit fdeef5e

Browse files
committed
fbsd-nat: Stop a process if it is running before killing it.
In addition, detach from any child processes implicitly attached to by the kernel due to fork following that have not yet been processed by GDB's core.
1 parent 57c28d4 commit fdeef5e

File tree

2 files changed

+78
-17
lines changed

2 files changed

+78
-17
lines changed

gdb/fbsd-nat.c

Lines changed: 76 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,31 @@ fbsd_is_child_pending (pid_t pid)
11401140
return null_ptid;
11411141
}
11421142

1143+
/* Wait for a child of a fork to report its stop. Returns the PTID of
1144+
the new child process. */
1145+
1146+
static ptid_t
1147+
fbsd_wait_for_fork_child (pid_t pid)
1148+
{
1149+
ptid_t ptid = fbsd_is_child_pending (pid);
1150+
if (ptid != null_ptid)
1151+
return ptid;
1152+
1153+
int status;
1154+
pid_t wpid = waitpid (pid, &status, 0);
1155+
if (wpid == -1)
1156+
perror_with_name (("waitpid"));
1157+
1158+
gdb_assert (wpid == pid);
1159+
1160+
struct ptrace_lwpinfo pl;
1161+
if (ptrace (PT_LWPINFO, wpid, (caddr_t) &pl, sizeof pl) == -1)
1162+
perror_with_name (("ptrace (PT_LWPINFO)"));
1163+
1164+
gdb_assert (pl.pl_flags & PL_FLAG_CHILD);
1165+
return ptid_t (wpid, pl.pl_lwpid);
1166+
}
1167+
11431168
#ifndef PTRACE_VFORK
11441169
/* Record a pending vfork done event. */
11451170

@@ -1447,23 +1472,7 @@ fbsd_nat_target::wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
14471472
#endif
14481473

14491474
/* Make sure the other end of the fork is stopped too. */
1450-
child_ptid = fbsd_is_child_pending (child);
1451-
if (child_ptid == null_ptid)
1452-
{
1453-
int status;
1454-
1455-
pid = waitpid (child, &status, 0);
1456-
if (pid == -1)
1457-
perror_with_name (("waitpid"));
1458-
1459-
gdb_assert (pid == child);
1460-
1461-
if (ptrace (PT_LWPINFO, child, (caddr_t) &pl, sizeof pl) == -1)
1462-
perror_with_name (("ptrace (PT_LWPINFO)"));
1463-
1464-
gdb_assert (pl.pl_flags & PL_FLAG_CHILD);
1465-
child_ptid = ptid_t (child, pl.pl_lwpid);
1466-
}
1475+
child_ptid = fbsd_wait_for_fork_child (child);
14671476

14681477
/* Enable additional events on the child process. */
14691478
fbsd_enable_proc_events (child_ptid.pid ());
@@ -2105,6 +2114,56 @@ fbsd_nat_target::detach (inferior *inf, int from_tty)
21052114
detach_success (inf);
21062115
}
21072116

2117+
/* Implement the "kill" target method. */
2118+
2119+
void
2120+
fbsd_nat_target::kill ()
2121+
{
2122+
pid_t pid = inferior_ptid.pid ();
2123+
if (pid == 0)
2124+
return;
2125+
2126+
inferior *inf = current_inferior ();
2127+
stop_process (inf);
2128+
2129+
if (detach_fork_children (inf)) {
2130+
/* No need to kill now. */
2131+
target_mourn_inferior (inferior_ptid);
2132+
2133+
return;
2134+
}
2135+
2136+
#ifdef TDP_RFPPWAIT
2137+
/* If there are any threads that have forked a new child but not yet
2138+
reported it because other threads reported events first, detach
2139+
from the children before killing the parent. */
2140+
auto lambda = [] (const struct ptrace_lwpinfo &pl)
2141+
{
2142+
if (pl.pl_flags & PL_FLAG_FORKED)
2143+
{
2144+
pid_t child = pl.pl_child_pid;
2145+
2146+
/* If the child hasn't reported its stop yet, wait for it to
2147+
stop. */
2148+
fbsd_wait_for_fork_child (child);
2149+
2150+
/* Detach from the child. */
2151+
(void) ptrace (PT_DETACH, child, (caddr_t) 1, 0);
2152+
}
2153+
return false;
2154+
};
2155+
iterate_other_ptrace_events (pid, gdb::make_function_view (lambda));
2156+
#endif
2157+
2158+
if (ptrace (PT_KILL, pid, NULL, 0) == -1)
2159+
perror_with_name (("ptrace (PT_KILL)"));
2160+
2161+
int status;
2162+
waitpid (pid, &status, 0);
2163+
2164+
target_mourn_inferior (inferior_ptid);
2165+
}
2166+
21082167
void
21092168
fbsd_nat_target::mourn_inferior ()
21102169
{

gdb/fbsd-nat.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ class fbsd_nat_target : public inf_ptrace_target
8383

8484
void detach (inferior *, int) override;
8585

86+
void kill () override;
87+
8688
void mourn_inferior () override;
8789

8890
void resume (ptid_t, int, enum gdb_signal) override;

0 commit comments

Comments
 (0)