123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- /* Fork a Unix child process, and set up to debug it, for GDB.
- Copyright (C) 1990-2022 Free Software Foundation, Inc.
- Contributed by Cygnus Support.
- This file is part of GDB.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
- #include "defs.h"
- #include "inferior.h"
- #include "gdbcmd.h"
- #include "terminal.h"
- #include "gdbthread.h"
- #include "top.h"
- #include "gdbsupport/job-control.h"
- #include "gdbsupport/filestuff.h"
- #include "nat/fork-inferior.h"
- #include "gdbsupport/common-inferior.h"
- /* The exec-wrapper, if any, that will be used when starting the
- inferior. */
- static std::string exec_wrapper;
- /* See gdbsupport/common-inferior.h. */
- const char *
- get_exec_wrapper ()
- {
- return !exec_wrapper.empty () ? exec_wrapper.c_str () : nullptr;
- }
- /* See nat/fork-inferior.h. */
- void
- gdb_flush_out_err ()
- {
- gdb_flush (main_ui->m_gdb_stdout);
- gdb_flush (main_ui->m_gdb_stderr);
- }
- /* The ui structure that will be saved on 'prefork_hook' and
- restored on 'postfork_hook'. */
- static struct ui *saved_ui = NULL;
- /* See nat/fork-inferior.h. */
- void
- prefork_hook (const char *args)
- {
- gdb_assert (saved_ui == NULL);
- /* Retain a copy of our UI, since the child will replace this value
- and if we're vforked, we have to restore it. */
- saved_ui = current_ui;
- /* Tell the terminal handling subsystem what tty we plan to run on;
- it will just record the information for later. */
- new_tty_prefork (current_inferior ()->tty ());
- }
- /* See nat/fork-inferior.h. */
- void
- postfork_hook (pid_t pid)
- {
- inferior *inf = current_inferior ();
- inferior_appeared (inf, pid);
- gdb_assert (saved_ui != NULL);
- current_ui = saved_ui;
- saved_ui = NULL;
- new_tty_postfork ();
- }
- /* See nat/fork-inferior.h. */
- void
- postfork_child_hook ()
- {
- /* This is set to the result of setpgrp, which if vforked, will be
- visible to you in the parent process. It's only used by humans
- for debugging. */
- static int debug_setpgrp = 657473;
- /* Make sure we switch to main_ui here in order to be able to
- use the gdb_printf/warning/error functions. */
- current_ui = main_ui;
- /* Create a new session for the inferior process, if necessary.
- It will also place the inferior in a separate process group. */
- if (create_tty_session () <= 0)
- {
- /* No session was created, but we still want to run the inferior
- in a separate process group. */
- debug_setpgrp = gdb_setpgid ();
- if (debug_setpgrp == -1)
- perror (_("setpgrp failed in child"));
- }
- /* Ask the tty subsystem to switch to the one we specified
- earlier (or to share the current terminal, if none was
- specified). */
- new_tty ();
- }
- /* See inferior.h. */
- ptid_t
- gdb_startup_inferior (pid_t pid, int num_traps)
- {
- inferior *inf = current_inferior ();
- process_stratum_target *proc_target = inf->process_target ();
- ptid_t ptid = startup_inferior (proc_target, pid, num_traps, NULL, NULL);
- /* Mark all threads non-executing. */
- set_executing (proc_target, ptid, false);
- return ptid;
- }
- /* Implement the "unset exec-wrapper" command. */
- static void
- unset_exec_wrapper_command (const char *args, int from_tty)
- {
- exec_wrapper.clear ();
- }
- static void
- show_startup_with_shell (struct ui_file *file, int from_tty,
- struct cmd_list_element *c, const char *value)
- {
- gdb_printf (file,
- _("Use of shell to start subprocesses is %s.\n"),
- value);
- }
- void _initialize_fork_child ();
- void
- _initialize_fork_child ()
- {
- add_setshow_filename_cmd ("exec-wrapper", class_run, &exec_wrapper, _("\
- Set a wrapper for running programs.\n\
- The wrapper prepares the system and environment for the new program."),
- _("\
- Show the wrapper for running programs."), NULL,
- NULL, NULL,
- &setlist, &showlist);
- add_cmd ("exec-wrapper", class_run, unset_exec_wrapper_command,
- _("Disable use of an execution wrapper."),
- &unsetlist);
- add_setshow_boolean_cmd ("startup-with-shell", class_support,
- &startup_with_shell, _("\
- Set use of shell to start subprocesses. The default is on."), _("\
- Show use of shell to start subprocesses."), NULL,
- NULL,
- show_startup_with_shell,
- &setlist, &showlist);
- }
|