1 /* Low level interface to ptrace, for GDB when running under Unix.
2 Copyright (C) 1986, 1987, 1989, 1991 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
30 #include <sys/types.h>
33 /* Some USG-esque systems (some of which are BSD-esque enough so that USG
34 is not defined) want this header, and it won't do any harm. */
37 #include <sys/param.h>
41 extern char *strerror(); /* strings corresponding to errno */
43 extern struct target_ops child_ops;
45 /* Nonzero if we are debugging an attached outside process
46 rather than an inferior. */
51 /* Record terminal status separately for debugger and inferior. */
53 /* Does GDB have a terminal (on stdin)? */
54 int gdb_has_a_terminal;
56 static TERMINAL sg_inferior;
57 static TERMINAL sg_ours;
59 static int tflags_inferior;
60 static int tflags_ours;
62 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
63 static struct tchars tc_inferior;
64 static struct tchars tc_ours;
67 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
68 static struct ltchars ltc_inferior;
69 static struct ltchars ltc_ours;
73 static int lmode_inferior;
74 static int lmode_ours;
79 static short pgrp_inferior;
80 static short pgrp_ours;
81 # else /* not def SHORT_PGRP */
82 static int pgrp_inferior;
84 # endif /* not def SHORT_PGRP */
85 #else /* not def TIOCGPGRP */
86 static void (*sigint_ours) ();
87 static void (*sigquit_ours) ();
88 #endif /* TIOCGPGRP */
90 /* The name of the tty (from the `tty' command) that we gave to the inferior
91 when it was last started. */
93 static char *inferior_thisrun_terminal;
95 /* Nonzero if our terminal settings are in effect.
96 Zero if the inferior's settings are in effect. */
98 static int terminal_is_ours;
100 /* Macro for printing errors from ioctl operations */
102 #define OOPSY(what) \
104 fprintf(stderr, "[%s failed in terminal_inferior: %s]\n", \
105 what, strerror (errno))
107 static void terminal_ours_1 ();
109 /* Initialize the terminal settings we record for the inferior,
110 before we actually run the inferior. */
113 terminal_init_inferior ()
115 sg_inferior = sg_ours;
116 tflags_inferior = tflags_ours;
118 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
119 tc_inferior = tc_ours;
122 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
123 ltc_inferior = ltc_ours;
127 lmode_inferior = lmode_ours;
131 pgrp_inferior = inferior_pid;
132 #endif /* TIOCGPGRP */
134 terminal_is_ours = 1;
137 /* Put the inferior's terminal settings into effect.
138 This is preparation for starting or resuming the inferior. */
145 if (gdb_has_a_terminal && terminal_is_ours && inferior_thisrun_terminal == 0)
147 result = fcntl (0, F_SETFL, tflags_inferior);
148 result = fcntl (0, F_SETFL, tflags_inferior);
149 OOPSY ("fcntl F_SETFL");
150 result = ioctl (0, TIOCSETN, &sg_inferior);
151 OOPSY ("ioctl TIOCSETN");
153 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
154 result = ioctl (0, TIOCSETC, &tc_inferior);
155 OOPSY ("ioctl TIOCSETC");
157 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
158 result = ioctl (0, TIOCSLTC, <c_inferior);
159 OOPSY ("ioctl TIOCSLTC");
162 result = ioctl (0, TIOCLSET, &lmode_inferior);
163 OOPSY ("ioctl TIOCLSET");
167 result = ioctl (0, TIOCSPGRP, &pgrp_inferior);
168 /* If we attached to the process, we might or might not be sharing
169 a terminal. Avoid printing error msg if we are unable to set our
170 terminal's process group to his process group ID. */
172 OOPSY ("ioctl TIOCSPGRP");
175 sigint_ours = (void (*) ()) signal (SIGINT, SIG_IGN);
176 sigquit_ours = (void (*) ()) signal (SIGQUIT, SIG_IGN);
177 #endif /* TIOCGPGRP */
179 terminal_is_ours = 0;
182 /* Put some of our terminal settings into effect,
183 enough to get proper results from our output,
184 but do not change into or out of RAW mode
185 so that no input is discarded.
187 After doing this, either terminal_ours or terminal_inferior
188 should be called to get back to a normal state of affairs. */
191 terminal_ours_for_output ()
196 /* Put our terminal settings into effect.
197 First record the inferior's terminal settings
198 so they can be restored properly later. */
207 terminal_ours_1 (output_only)
212 /* Ignore this signal since it will happen when we try to set the pgrp. */
214 #endif /* TIOCGPGRP */
216 /* Checking inferior_thisrun_terminal is necessary so that
217 if GDB is running in the background, it won't block trying
218 to do the ioctl()'s below. Checking gdb_has_a_terminal
219 avoids attempting all the ioctl's when running in batch. */
220 if (inferior_thisrun_terminal != 0 || gdb_has_a_terminal == 0)
223 if (!terminal_is_ours)
225 terminal_is_ours = 1;
228 osigttou = (void (*) ()) signal (SIGTTOU, SIG_IGN);
230 result = ioctl (0, TIOCGPGRP, &pgrp_inferior);
231 result = ioctl (0, TIOCSPGRP, &pgrp_ours);
233 signal (SIGTTOU, osigttou);
235 signal (SIGINT, sigint_ours);
236 signal (SIGQUIT, sigquit_ours);
237 #endif /* TIOCGPGRP */
239 tflags_inferior = fcntl (0, F_GETFL, 0);
240 result = ioctl (0, TIOCGETP, &sg_inferior);
242 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
243 result = ioctl (0, TIOCGETC, &tc_inferior);
245 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
246 result = ioctl (0, TIOCGLTC, <c_inferior);
249 result = ioctl (0, TIOCLGET, &lmode_inferior);
254 sg_ours.c_lflag |= ICANON;
255 if (output_only && !(sg_inferior.c_lflag & ICANON))
256 sg_ours.c_lflag &= ~ICANON;
257 #else /* not HAVE_TERMIO */
258 sg_ours.sg_flags &= ~RAW & ~CBREAK;
260 sg_ours.sg_flags |= (RAW | CBREAK) & sg_inferior.sg_flags;
261 #endif /* not HAVE_TERMIO */
263 result = fcntl (0, F_SETFL, tflags_ours);
264 result = fcntl (0, F_SETFL, tflags_ours);
265 result = ioctl (0, TIOCSETN, &sg_ours);
267 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
268 result = ioctl (0, TIOCSETC, &tc_ours);
270 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
271 result = ioctl (0, TIOCSLTC, <c_ours);
274 result = ioctl (0, TIOCLSET, &lmode_ours);
278 sg_ours.c_lflag |= ICANON;
279 #else /* not HAVE_TERMIO */
280 sg_ours.sg_flags &= ~RAW & ~CBREAK;
281 #endif /* not HAVE_TERMIO */
286 term_info (arg, from_tty)
290 target_terminal_info (arg, from_tty);
295 child_terminal_info (args, from_tty)
301 if (!gdb_has_a_terminal) {
302 printf_filtered ("This GDB does not control a terminal.\n");
307 printf_filtered ("Inferior's terminal status (currently saved by GDB):\n");
309 printf_filtered ("owner pgrp = %d, fcntl flags = 0x%x.\n",
310 pgrp_inferior, tflags_inferior);
311 #endif /* TIOCGPGRP */
315 printf_filtered ("c_iflag = 0x%x, c_oflag = 0x%x,\n",
316 sg_inferior.c_iflag, sg_inferior.c_oflag);
317 printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n",
318 sg_inferior.c_cflag, sg_inferior.c_lflag, sg_inferior.c_line);
319 printf_filtered ("c_cc: ");
320 for (i = 0; (i < NCC); i += 1)
321 printf_filtered ("0x%x ", sg_inferior.c_cc[i]);
322 printf_filtered ("\n");
324 #else /* not HAVE_TERMIO */
326 printf_filtered ("sgttyb.sg_flags = 0x%x.\n", sg_inferior.sg_flags);
328 #endif /* not HAVE_TERMIO */
330 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
331 printf_filtered ("tchars: ");
332 for (i = 0; i < (int)sizeof (struct tchars); i++)
333 printf_filtered ("0x%x ", ((unsigned char *)&tc_inferior)[i]);
334 printf_filtered ("\n");
337 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
338 printf_filtered ("ltchars: ");
339 for (i = 0; i < (int)sizeof (struct ltchars); i++)
340 printf_filtered ("0x%x ", ((unsigned char *)<c_inferior)[i]);
341 printf_filtered ("\n");
345 printf_filtered ("lmode: 0x%x\n", lmode_inferior);
349 /* NEW_TTY_PREFORK is called before forking a new child process,
350 so we can record the state of ttys in the child to be formed.
351 TTYNAME is null if we are to share the terminal with gdb;
352 or points to a string containing the name of the desired tty.
354 NEW_TTY is called in new child processes under Unix, which will
355 become debugger target processes. This actually switches to
356 the terminal specified in the NEW_TTY_PREFORK call. */
359 new_tty_prefork (ttyname)
362 /* Save the name for later, for determining whether we and the child
363 are sharing a tty. */
364 inferior_thisrun_terminal = ttyname;
372 if (inferior_thisrun_terminal == 0)
376 /* Disconnect the child process from our controlling terminal. */
377 tty = open("/dev/tty", O_RDWR);
380 ioctl(tty, TIOCNOTTY, 0);
385 /* Now open the specified new terminal. */
388 tty = open(inferior_thisrun_terminal, O_RDWR | O_NOCTTY);
390 tty = open(inferior_thisrun_terminal, O_RDWR);
394 print_sys_errmsg (inferior_thisrun_terminal, errno);
398 /* Avoid use of dup2; doesn't exist on all systems. */
400 { close (0); dup (tty); }
402 { close (1); dup (tty); }
404 { close (2); dup (tty); }
409 /* Kill the inferior process. Make us have no inferior. */
413 kill_command (arg, from_tty)
417 if (inferior_pid == 0)
418 error ("The program is not being run.");
419 if (!query ("Kill the inferior process? "))
420 error ("Not confirmed.");
421 target_kill (arg, from_tty);
423 /* Killing off the inferior can leave us with a core file. If so,
424 print the state we are left in. */
425 if (target_has_stack) {
426 printf_filtered ("In %s,\n", current_target->to_longname);
427 if (selected_frame == NULL)
428 fputs_filtered ("No selected stack frame.\n", stdout);
430 print_stack_frame (selected_frame, selected_frame_level, 1);
434 /* The inferior process has died. Long live the inferior! */
437 generic_mourn_inferior ()
441 mark_breakpoints_out ();
442 registers_changed ();
444 #ifdef CLEAR_DEFERRED_STORES
445 /* Delete any pending stores to the inferior... */
446 CLEAR_DEFERRED_STORES;
450 if (target_has_stack) {
451 set_current_frame ( create_new_frame (read_register (FP_REGNUM),
453 select_frame (get_current_frame (), 0);
455 set_current_frame (0);
456 select_frame ((FRAME) 0, -1);
458 /* It is confusing to the user for ignore counts to stick around
459 from previous runs of the inferior. So clear them. */
460 breakpoint_clear_ignore_counts ();
464 child_mourn_inferior ()
466 unpush_target (&child_ops);
467 generic_mourn_inferior ();
471 /* This function is just for testing, and on some systems (Sony NewsOS
472 3.2) <sys/user.h> also includes <sys/time.h> which leads to errors
473 (since on this system at least sys/time.h is not protected against
474 multiple inclusion). */
477 try_writing_regs_command (arg, from_tty)
484 if (inferior_pid == 0)
485 error ("There is no inferior process now.");
487 /* A Sun 3/50 or 3/60 (at least) running SunOS 4.0.3 will have a
488 kernel panic if we try to write past the end of the user area.
489 Presumably Sun will fix this bug (it has been reported), but it
490 is tacky to crash the system, so at least on SunOS4 we need to
491 stop writing when we hit the end of the user area. */
492 for (i = 0; i < sizeof (struct user); i += 2)
496 value = call_ptrace (3, inferior_pid, i, 0);
497 call_ptrace (6, inferior_pid, i, value);
500 printf (" Succeeded with address 0x%x; value 0x%x (%d).\n",
503 else if ((i & 0377) == 0)
504 printf (" Failed at 0x%x.\n", i);
510 _initialize_inflow ()
514 add_info ("terminal", term_info,
515 "Print inferior's saved terminal status.");
518 add_com ("try-writing-regs", class_obscure, try_writing_regs_command,
519 "Try writing all locations in inferior's system block.\n\
520 Report which ones can be written.");
523 add_com ("kill", class_run, kill_command,
524 "Kill execution of program being debugged.");
528 /* Get all the current tty settings (including whether we have a tty at
531 tflags_ours = fcntl (0, F_GETFL, 0);
532 OOPSY ("fcntl F_GETFL"); /* Should always work */
534 result = ioctl (0, TIOCGETP, &sg_ours);
536 gdb_has_a_terminal = 1;
537 /* Get the rest of the tty settings, then... */
538 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
539 ioctl (0, TIOCGETC, &tc_ours);
541 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
542 ioctl (0, TIOCGLTC, <c_ours);
545 ioctl (0, TIOCLGET, &lmode_ours);
548 ioctl (0, TIOCGPGRP, &pgrp_ours);
549 #endif /* TIOCGPGRP */
551 gdb_has_a_terminal = 0;
554 terminal_is_ours = 1;