static void gdbsim_kill (void) { if (sr_get_debug ()) printf_filtered ("gdbsim_kill\n"); /* There is no need to `kill' running simulator - the simulator is not running. Mourning it is enough. */ target_mourn_inferior (); }
static void gdbsim_kill (struct target_ops *ops) { if (remote_debug) printf_filtered ("gdbsim_kill\n"); /* There is no need to `kill' running simulator - the simulator is not running. Mourning it is enough. */ target_mourn_inferior (); }
static void inf_ptrace_kill (void) { pid_t pid = ptid_get_pid (inferior_ptid); int status; if (pid == 0) return; ptrace (PT_KILL, pid, (PTRACE_TYPE_ARG3)0, 0); waitpid (pid, &status, 0); target_mourn_inferior (); }
void inf_ptrace_target::kill () { pid_t pid = inferior_ptid.pid (); int status; if (pid == 0) return; ptrace (PT_KILL, pid, (PTRACE_TYPE_ARG3)0, 0); waitpid (pid, &status, 0); target_mourn_inferior (inferior_ptid); }
static void inf_ptrace_kill (struct target_ops *ops) { pid_t pid = ptid_get_pid (inferior_ptid); int status; if (pid == FAKE_PROCESS_ID) return; ptrace (PT_KILL, pid, (PTRACE_TYPE_ARG3)0, 0); waitpid (pid, &status, 0); target_mourn_inferior (); }
static void haiku_child_kill_inferior (void) { status_t err; thread_id teamID = ptid_get_pid(inferior_ptid); TRACE(("haiku_child_kill_inferior()\n")); err = kill_team(teamID); if (err != B_OK) { printf_unfiltered ("Failed to kill team %ld: %s\n", teamID, strerror(err)); return; } target_mourn_inferior(); }
void kill_inferior (void) { int status; int pid = PIDGET (inferior_ptid); if (pid == 0) return; /* This once used to call "kill" to kill the inferior just in case the inferior was still running. As others have noted in the past (kingdon) there shouldn't be any way to get here if the inferior is still running -- else there's a major problem elsewere in gdb and it needs to be fixed. The kill call causes problems under hpux10, so it's been removed; if this causes problems we'll deal with them as they arise. */ ptrace (PT_KILL, pid, (PTRACE_TYPE_ARG3) 0, 0); wait (&status); target_mourn_inferior (); }
void startup_inferior (int ntraps) { int pending_execs = ntraps; int terminal_initted = 0; ptid_t resume_ptid; if (target_supports_multi_process ()) resume_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid)); else resume_ptid = minus_one_ptid; /* The process was started by the fork that created it, but it will have stopped one instruction after execing the shell. Here we must get it up to actual execution of the real program. */ if (exec_wrapper) pending_execs++; while (1) { enum target_signal resume_signal = TARGET_SIGNAL_0; ptid_t event_ptid; struct target_waitstatus ws; memset (&ws, 0, sizeof (ws)); event_ptid = target_wait (resume_ptid, &ws, 0); if (ws.kind == TARGET_WAITKIND_IGNORE) /* The inferior didn't really stop, keep waiting. */ continue; switch (ws.kind) { case TARGET_WAITKIND_SPURIOUS: case TARGET_WAITKIND_LOADED: case TARGET_WAITKIND_FORKED: case TARGET_WAITKIND_VFORKED: case TARGET_WAITKIND_SYSCALL_ENTRY: case TARGET_WAITKIND_SYSCALL_RETURN: /* Ignore gracefully during startup of the inferior. */ switch_to_thread (event_ptid); break; case TARGET_WAITKIND_SIGNALLED: target_terminal_ours (); target_mourn_inferior (); error (_("During startup program terminated with signal %s, %s."), target_signal_to_name (ws.value.sig), target_signal_to_string (ws.value.sig)); return; case TARGET_WAITKIND_EXITED: target_terminal_ours (); target_mourn_inferior (); if (ws.value.integer) error (_("During startup program exited with code %d."), ws.value.integer); else error (_("During startup program exited normally.")); return; case TARGET_WAITKIND_EXECD: /* Handle EXEC signals as if they were SIGTRAP signals. */ xfree (ws.value.execd_pathname); resume_signal = TARGET_SIGNAL_TRAP; switch_to_thread (event_ptid); break; case TARGET_WAITKIND_STOPPED: resume_signal = ws.value.sig; switch_to_thread (event_ptid); break; } if (resume_signal != TARGET_SIGNAL_TRAP) { /* Let shell child handle its own signals in its own way. */ target_resume (resume_ptid, 0, resume_signal); } else { /* We handle SIGTRAP, however; it means child did an exec. */ if (!terminal_initted) { /* Now that the child has exec'd we know it has already set its process group. On POSIX systems, tcsetpgrp will fail with EPERM if we try it before the child's setpgid. */ /* Set up the "saved terminal modes" of the inferior based on what modes we are starting it with. */ target_terminal_init (); /* Install inferior's terminal modes. */ target_terminal_inferior (); terminal_initted = 1; } if (--pending_execs == 0) break; /* Just make it go on. */ target_resume (resume_ptid, 0, TARGET_SIGNAL_0); } } /* Mark all threads non-executing. */ set_executing (resume_ptid, 0); }
/* An inferior Unix process CHILD_PID has been created by a call to fork() (or variants like vfork). It is presently stopped, and waiting to be resumed. clone_and_follow_inferior will fork the debugger, and that clone will "follow" (attach to) CHILD_PID. The original copy of the debugger will not touch CHILD_PID again. Also, the original debugger will set FOLLOWED_CHILD FALSE, while the clone will set it TRUE. */ void clone_and_follow_inferior (int child_pid, int *followed_child) { int debugger_pid; int status; char pid_spelling[100]; /* Arbitrary but sufficient length. */ /* This semaphore is used to coordinate the two debuggers' handoff of CHILD_PID. The original debugger will detach from CHILD_PID, and then the clone debugger will attach to it. (It must be done this way because on some targets, only one process at a time can trace another. Thus, the original debugger must relinquish its tracing rights before the clone can pick them up.) */ #define SEM_TALK (1) #define SEM_LISTEN (0) int handoff_semaphore[2]; /* Original "talks" to [1], clone "listens" to [0] */ int talk_value = 99; int listen_value; /* Set debug_fork then attach to the child while it sleeps, to debug. */ static int debug_fork = 0; /* It is generally good practice to flush any possible pending stdio output prior to doing a fork, to avoid the possibility of both the parent and child flushing the same data after the fork. */ gdb_flush (gdb_stdout); gdb_flush (gdb_stderr); /* Open the semaphore pipes. */ status = pipe (handoff_semaphore); if (status < 0) error ("error getting pipe for handoff semaphore"); /* Clone the debugger. Note that the apparent call to vfork() below *might* actually be a call to fork() due to the fact that autoconf will ``#define vfork fork'' on certain platforms. */ if (debug_fork) debugger_pid = fork (); else debugger_pid = vfork (); if (debugger_pid < 0) perror_with_name ("fork"); /* Are we the original debugger? If so, we must relinquish all claims to CHILD_PID. */ if (debugger_pid != 0) { char signal_spelling[100]; /* Arbitrary but sufficient length */ /* Detach from CHILD_PID. Deliver a "stop" signal when we do, though, so that it remains stopped until the clone debugger can attach to it. */ detach_breakpoints (child_pid); sprintf (signal_spelling, "%d", target_signal_to_host (TARGET_SIGNAL_STOP)); target_require_detach (child_pid, signal_spelling, 1); /* Notify the clone debugger that it should attach to CHILD_PID. */ write (handoff_semaphore[SEM_TALK], &talk_value, sizeof (talk_value)); *followed_child = 0; } /* We're the child. */ else { if (debug_fork) sleep (debug_fork); /* The child (i.e., the cloned debugger) must now attach to CHILD_PID. inferior_ptid is presently set to the parent process of the fork, while CHILD_PID should be the child process of the fork. Wait until the original debugger relinquishes control of CHILD_PID, though. */ read (handoff_semaphore[SEM_LISTEN], &listen_value, sizeof (listen_value)); /* Note that we DON'T want to actually detach from inferior_ptid, because that would allow it to run free. The original debugger wants to retain control of the process. So, we just reset inferior_ptid to CHILD_PID, and then ensure that all breakpoints are really set in CHILD_PID. */ target_mourn_inferior (); /* Ask the tty subsystem to switch to the one we specified earlier (or to share the current terminal, if none was specified). */ new_tty (); dont_repeat (); sprintf (pid_spelling, "%d", child_pid); target_require_attach (pid_spelling, 1); /* Perform any necessary cleanup, after attachment. (This form of attaching can behave differently on some targets than the standard method, where a process formerly not under debugger control was suddenly attached to..) */ target_post_follow_inferior_by_clone (); *followed_child = 1; } /* Discard the handoff sempahore. */ (void) close (handoff_semaphore[SEM_LISTEN]); (void) close (handoff_semaphore[SEM_TALK]); }