This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[RFA] Fix GDB's handling of the inferior controlling terminal.
- From: Thiago Jung Bauermann <bauerman at br dot ibm dot com>
- To: gdb-patches <gdb-patches at sourceware dot org>
- Date: Mon, 10 Mar 2008 14:41:56 -0300
- Subject: [RFA] Fix GDB's handling of the inferior controlling terminal.
Hi,
With the current CVS version, if the user specifies a different terminal
for the inferior to run on, GDB doesn't set it as the inferior's
controlling terminal.
This leads to some problems. For instance, the inferior will not
get SIGINT sent to the terminal. Also, if the inferior is GDB itself,
the following message is shown in the inferior GDB's debugging session:
[tcsetpgrp failed in terminal_inferior: Inappropriate ioctl for device]
The attached patch makes GDB set the inferior's controlling terminal,
fixing both of the symptoms above. If the user specifies a different
inferior terminal, GDB will now create a new session right after forking
to run the inferior, and use the TIOCSCTTY ioctl to set the controlling
terminal.
Ran testsuite, no regressions found. Is this ok?
--
[]'s
Thiago Jung Bauermann
Software Engineer
IBM Linux Technology Center
2008-03-10 Thiago Jung Bauermann <bauerman.ibm.com>
* configure.ac (AC_CHECK_FUNCS): Add check for setsid.
* config.in, configure: Regenerate.
* fork-child.c (fork_inferior): Call create_tty_session.
* inflow.c (new_tty): Set controlling terminal with TIOCSCTTY.
(create_tty_session): New function.
* terminal.h: Declare create_tty_session.
=== modified file 'gdb/config.in'
--- gdb/config.in 2008-01-21 02:31:01 +0000
+++ gdb/config.in 2008-01-21 02:51:22 +0000
@@ -278,6 +278,9 @@
/* Define to 1 if you have the `setpgrp' function. */
#undef HAVE_SETPGRP
+/* Define to 1 if you have the `setsid' function. */
+#undef HAVE_SETSID
+
/* Define to 1 if you have the <sgtty.h> header file. */
#undef HAVE_SGTTY_H
=== modified file 'gdb/configure'
--- gdb/configure 2008-01-21 02:31:01 +0000
+++ gdb/configure 2008-01-21 02:51:22 +0000
@@ -18503,7 +18503,8 @@ done
-for ac_func in setpgid setpgrp
+
+for ac_func in setpgid setpgrp setsid
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
=== modified file 'gdb/configure.ac'
--- gdb/configure.ac 2008-01-21 02:31:02 +0000
+++ gdb/configure.ac 2008-01-21 02:51:22 +0000
@@ -603,7 +603,7 @@ AC_CHECK_FUNCS(getuid getgid)
AC_CHECK_FUNCS(poll)
AC_CHECK_FUNCS(pread64)
AC_CHECK_FUNCS(sbrk)
-AC_CHECK_FUNCS(setpgid setpgrp)
+AC_CHECK_FUNCS(setpgid setpgrp setsid)
AC_CHECK_FUNCS(sigaction sigprocmask sigsetmask)
AC_CHECK_FUNCS(socketpair)
AC_CHECK_FUNCS(syscall)
=== modified file 'gdb/fork-child.c'
--- gdb/fork-child.c 2008-03-01 21:54:26 +0000
+++ gdb/fork-child.c 2008-03-01 22:11:53 +0000
@@ -289,10 +289,16 @@ fork_inferior (char *exec_file_arg, char
if (debug_fork)
sleep (debug_fork);
- /* Run inferior in a separate process group. */
- debug_setpgrp = gdb_setpgid ();
- if (debug_setpgrp == -1)
- perror ("setpgrp failed in child");
+ /* 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
=== modified file 'gdb/inflow.c'
--- gdb/inflow.c 2008-01-01 22:53:11 +0000
+++ gdb/inflow.c 2008-01-21 02:51:38 +0000
@@ -557,6 +557,16 @@ new_tty (void)
close (2);
dup (tty);
}
+
+#ifdef TIOCSCTTY
+ /* Make tty our new controlling terminal. */
+ if (ioctl (tty, TIOCSCTTY, 0) == -1)
+ /* Mention GDB in warning because it will appear in the inferior's
+ terminal instead of GDB's. */
+ warning ("GDB: Failed to set controlling terminal: %s",
+ safe_strerror (errno));
+#endif
+
if (tty > 2)
close (tty);
#endif /* !go32 && !win32 */
@@ -683,6 +693,33 @@ clear_sigio_trap (void)
#endif /* No SIGIO. */
+/* Create a new session if the inferior will run in a different tty.
+ A session is UNIX's way of grouping processes that share a controlling
+ terminal, so a new one is needed if the inferior terminal will be
+ different from GDB's.
+
+ Returns the session id of the new session, 0 if no session was created
+ or -1 if an error occurred. */
+pid_t
+create_tty_session (void)
+{
+#ifdef HAVE_SETSID
+ pid_t ret;
+
+ if (!job_control || inferior_thisrun_terminal == 0)
+ return 0;
+
+ ret = setsid();
+ if (ret == -1)
+ warning ("Failed to create new terminal session: setsid: %s",
+ safe_strerror (errno));
+
+ return ret;
+#else
+ return 0;
+#endif /* HAVE_SETSID */
+}
+
/* This is here because this is where we figure out whether we (probably)
have job control. Just using job_control only does part of it because
setpgid or setpgrp might not exist on a system without job control.
=== modified file 'gdb/terminal.h'
--- gdb/terminal.h 2008-01-01 22:53:13 +0000
+++ gdb/terminal.h 2008-01-21 02:50:27 +0000
@@ -82,6 +82,8 @@ extern void new_tty (void);
a given run of GDB. In inflow.c. */
extern int job_control;
+extern int create_tty_session (void);
+
/* Set the process group of the caller to its own pid, or do nothing if
we lack job control. */
extern int gdb_setpgid (void);