mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-10-17 21:03:55 +08:00
* linux-fork.c (linux_fork_detach): New.
* linux-fork.h (linux_fork_detach): Declare. * linux-nat.c (linux_child_follow_fork): When following the fork child, add the child inferior before possibly detaching from the parent. Don't reinstall ourselves. (linux_nat_detach): Call linux_fork_detach if there are other forks to debug. * linux-thread-db.c (thread_db_detach): Don't call target_mourn_inferior. Instead inline the necessary bits. * inf-ptrace.c (inf_ptrace_detach): Don't unpush the target if there are other inferiors to debug.
This commit is contained in:
@ -1,3 +1,17 @@
|
|||||||
|
2008-12-28 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
|
* linux-fork.c (linux_fork_detach): New.
|
||||||
|
* linux-fork.h (linux_fork_detach): Declare.
|
||||||
|
* linux-nat.c (linux_child_follow_fork): When following the fork
|
||||||
|
child, add the child inferior before possibly detaching from the
|
||||||
|
parent. Don't reinstall ourselves.
|
||||||
|
(linux_nat_detach): Call linux_fork_detach if there are other
|
||||||
|
forks to debug.
|
||||||
|
* linux-thread-db.c (thread_db_detach): Don't call
|
||||||
|
target_mourn_inferior. Instead inline the necessary bits.
|
||||||
|
* inf-ptrace.c (inf_ptrace_detach): Don't unpush the target if
|
||||||
|
there are other inferiors to debug.
|
||||||
|
|
||||||
2008-12-28 Jan Kratochvil <jan.kratochvil@redhat.com>
|
2008-12-28 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
|
||||||
Fix TYPE_HIGH_BOUND for TYPE_CODE_RANGE using arbitrary TYPE_NFIELDS in
|
Fix TYPE_HIGH_BOUND for TYPE_CODE_RANGE using arbitrary TYPE_NFIELDS in
|
||||||
|
@ -309,7 +309,9 @@ inf_ptrace_detach (struct target_ops *ops, char *args, int from_tty)
|
|||||||
|
|
||||||
inferior_ptid = null_ptid;
|
inferior_ptid = null_ptid;
|
||||||
detach_inferior (pid);
|
detach_inferior (pid);
|
||||||
unpush_target (ops);
|
|
||||||
|
if (!have_inferiors ())
|
||||||
|
unpush_target (ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Kill the inferior. */
|
/* Kill the inferior. */
|
||||||
|
@ -387,6 +387,40 @@ linux_fork_mourn_inferior (void)
|
|||||||
delete_fork (inferior_ptid);
|
delete_fork (inferior_ptid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The current inferior_ptid is being detached, but there are other
|
||||||
|
viable forks to debug. Detach and delete it and context-switch to
|
||||||
|
the first available. */
|
||||||
|
|
||||||
|
extern void
|
||||||
|
linux_fork_detach (char *args, int from_tty)
|
||||||
|
{
|
||||||
|
/* OK, inferior_ptid is the one we are detaching from. We need to
|
||||||
|
delete it from the fork_list, and switch to the next available
|
||||||
|
fork. */
|
||||||
|
|
||||||
|
if (ptrace (PTRACE_DETACH, PIDGET (inferior_ptid), 0, 0))
|
||||||
|
error (_("Unable to detach %s"), target_pid_to_str (inferior_ptid));
|
||||||
|
|
||||||
|
delete_fork (inferior_ptid);
|
||||||
|
/* Delete process from GDB's inferior list. */
|
||||||
|
delete_inferior (ptid_get_pid (inferior_ptid));
|
||||||
|
|
||||||
|
/* There should still be a fork - if there's only one left,
|
||||||
|
delete_fork won't remove it, because we haven't updated
|
||||||
|
inferior_ptid yet. */
|
||||||
|
gdb_assert (fork_list);
|
||||||
|
|
||||||
|
fork_load_infrun_state (fork_list);
|
||||||
|
|
||||||
|
if (from_tty)
|
||||||
|
printf_filtered (_("[Switching to %s]\n"),
|
||||||
|
target_pid_to_str (inferior_ptid));
|
||||||
|
|
||||||
|
/* If there's only one fork, switch back to non-fork mode. */
|
||||||
|
if (fork_list->next == NULL)
|
||||||
|
delete_fork (inferior_ptid);
|
||||||
|
}
|
||||||
|
|
||||||
/* Fork list <-> user interface. */
|
/* Fork list <-> user interface. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -23,6 +23,7 @@ extern struct fork_info *find_fork_pid (pid_t);
|
|||||||
extern void fork_save_infrun_state (struct fork_info *, int);
|
extern void fork_save_infrun_state (struct fork_info *, int);
|
||||||
extern void linux_fork_killall (void);
|
extern void linux_fork_killall (void);
|
||||||
extern void linux_fork_mourn_inferior (void);
|
extern void linux_fork_mourn_inferior (void);
|
||||||
|
extern void linux_fork_detach (char *, int);
|
||||||
extern int forks_exist_p (void);
|
extern int forks_exist_p (void);
|
||||||
|
|
||||||
struct fork_info *fork_list;
|
struct fork_info *fork_list;
|
||||||
|
@ -826,6 +826,11 @@ linux_child_follow_fork (struct target_ops *ops, int follow_child)
|
|||||||
child_pid);
|
child_pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add the new inferior first, so that the target_detach below
|
||||||
|
doesn't unpush the target. */
|
||||||
|
|
||||||
|
add_inferior (child_pid);
|
||||||
|
|
||||||
/* If we're vforking, we may want to hold on to the parent until
|
/* If we're vforking, we may want to hold on to the parent until
|
||||||
the child exits or execs. At exec time we can remove the old
|
the child exits or execs. At exec time we can remove the old
|
||||||
breakpoints from the parent and detach it; at exit time we
|
breakpoints from the parent and detach it; at exit time we
|
||||||
@ -868,12 +873,7 @@ linux_child_follow_fork (struct target_ops *ops, int follow_child)
|
|||||||
target_detach (NULL, 0);
|
target_detach (NULL, 0);
|
||||||
|
|
||||||
inferior_ptid = ptid_build (child_pid, child_pid, 0);
|
inferior_ptid = ptid_build (child_pid, child_pid, 0);
|
||||||
add_inferior (child_pid);
|
|
||||||
|
|
||||||
/* Reinstall ourselves, since we might have been removed in
|
|
||||||
target_detach (which does other necessary cleanup). */
|
|
||||||
|
|
||||||
push_target (ops);
|
|
||||||
linux_nat_switch_fork (inferior_ptid);
|
linux_nat_switch_fork (inferior_ptid);
|
||||||
check_for_thread_db ();
|
check_for_thread_db ();
|
||||||
|
|
||||||
@ -1621,12 +1621,24 @@ linux_nat_detach (struct target_ops *ops, char *args, int from_tty)
|
|||||||
/* Destroy LWP info; it's no longer valid. */
|
/* Destroy LWP info; it's no longer valid. */
|
||||||
init_lwp_list ();
|
init_lwp_list ();
|
||||||
|
|
||||||
pid = GET_PID (inferior_ptid);
|
pid = ptid_get_pid (inferior_ptid);
|
||||||
inferior_ptid = pid_to_ptid (pid);
|
|
||||||
linux_ops->to_detach (ops, args, from_tty);
|
|
||||||
|
|
||||||
if (target_can_async_p ())
|
if (target_can_async_p ())
|
||||||
drain_queued_events (pid);
|
drain_queued_events (pid);
|
||||||
|
|
||||||
|
if (forks_exist_p ())
|
||||||
|
{
|
||||||
|
/* Multi-fork case. The current inferior_ptid is being detached
|
||||||
|
from, but there are other viable forks to debug. Detach from
|
||||||
|
the current fork, and context-switch to the first
|
||||||
|
available. */
|
||||||
|
linux_fork_detach (args, from_tty);
|
||||||
|
|
||||||
|
if (non_stop && target_can_async_p ())
|
||||||
|
target_async (inferior_event_handler, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
linux_ops->to_detach (ops, args, from_tty);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resume LP. */
|
/* Resume LP. */
|
||||||
|
@ -784,10 +784,15 @@ thread_db_detach (struct target_ops *ops, char *args, int from_tty)
|
|||||||
{
|
{
|
||||||
disable_thread_event_reporting ();
|
disable_thread_event_reporting ();
|
||||||
|
|
||||||
target_beneath->to_detach (target_beneath, args, from_tty);
|
/* Forget about the child's process ID. We shouldn't need it
|
||||||
|
anymore. */
|
||||||
|
proc_handle.pid = 0;
|
||||||
|
|
||||||
/* Should this be done by detach_command? */
|
/* Detach thread_db target ops. */
|
||||||
target_mourn_inferior ();
|
unpush_target (&thread_db_ops);
|
||||||
|
using_thread_db = 0;
|
||||||
|
|
||||||
|
target_beneath->to_detach (target_beneath, args, from_tty);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if PID is currently stopped at the location of a thread event
|
/* Check if PID is currently stopped at the location of a thread event
|
||||||
|
Reference in New Issue
Block a user