1 /* Low level interface to ptrace, for GDB when running under Unix.
2 Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
4 This file is part of GDB.
6 GDB 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 1, or (at your option)
11 GDB 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 GDB; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
26 #include <sys/types.h>
31 #include <sys/param.h>
38 #define TIOCGETP TCGETA
40 #define TIOCSETN TCSETA
42 #define TIOCSETP TCSETAF
43 #define TERMINAL struct termio
45 #include <sys/ioctl.h>
48 #define TERMINAL struct sgttyb
51 #ifdef SET_STACK_LIMIT_HUGE
53 #include <sys/resource.h>
54 extern int original_stack_limit;
55 #endif /* SET_STACK_LIMIT_HUGE */
59 /* Nonzero if we are debugging an attached outside process
60 rather than an inferior. */
65 /* Record terminal status separately for debugger and inferior. */
67 static TERMINAL sg_inferior;
68 static TERMINAL sg_ours;
70 static int tflags_inferior;
71 static int tflags_ours;
73 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
74 static struct tchars tc_inferior;
75 static struct tchars tc_ours;
79 static struct ltchars ltc_inferior;
80 static struct ltchars ltc_ours;
84 static int lmode_inferior;
85 static int lmode_ours;
89 static int pgrp_inferior;
92 static int (*sigint_ours) ();
93 static int (*sigquit_ours) ();
94 #endif /* TIOCGPGRP */
96 /* Copy of inferior_io_terminal when inferior was last started. */
97 static char *inferior_thisrun_terminal;
99 static void terminal_ours_1 ();
101 /* Nonzero if our terminal settings are in effect.
102 Zero if the inferior's settings are in effect. */
103 static int terminal_is_ours;
105 /* Initialize the terminal settings we record for the inferior,
106 before we actually run the inferior. */
109 terminal_init_inferior ()
111 if (remote_debugging)
114 sg_inferior = sg_ours;
115 tflags_inferior = tflags_ours;
117 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
118 tc_inferior = tc_ours;
122 ltc_inferior = ltc_ours;
126 lmode_inferior = lmode_ours;
130 pgrp_inferior = inferior_pid;
131 #endif /* TIOCGPGRP */
133 terminal_is_ours = 1;
136 /* Put the inferior's terminal settings into effect.
137 This is preparation for starting or resuming the inferior. */
142 if (remote_debugging)
145 if (terminal_is_ours) /* && inferior_thisrun_terminal == 0) */
147 fcntl (0, F_SETFL, tflags_inferior);
148 fcntl (0, F_SETFL, tflags_inferior);
149 ioctl (0, TIOCSETN, &sg_inferior);
151 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
152 ioctl (0, TIOCSETC, &tc_inferior);
155 ioctl (0, TIOCSLTC, <c_inferior);
158 ioctl (0, TIOCLSET, &lmode_inferior);
162 ioctl (0, TIOCSPGRP, &pgrp_inferior);
164 sigint_ours = (int (*) ()) signal (SIGINT, SIG_IGN);
165 sigquit_ours = (int (*) ()) signal (SIGQUIT, SIG_IGN);
166 #endif /* TIOCGPGRP */
168 terminal_is_ours = 0;
171 /* Put some of our terminal settings into effect,
172 enough to get proper results from our output,
173 but do not change into or out of RAW mode
174 so that no input is discarded.
176 After doing this, either terminal_ours or terminal_inferior
177 should be called to get back to a normal state of affairs. */
180 terminal_ours_for_output ()
182 if (remote_debugging)
188 /* Put our terminal settings into effect.
189 First record the inferior's terminal settings
190 so they can be restored properly later. */
195 if (remote_debugging)
202 terminal_ours_1 (output_only)
206 /* Ignore this signal since it will happen when we try to set the pgrp. */
208 #endif /* TIOCGPGRP */
210 if (!terminal_is_ours) /* && inferior_thisrun_terminal == 0) */
212 terminal_is_ours = 1;
215 osigttou = (int (*) ()) signal (SIGTTOU, SIG_IGN);
217 ioctl (0, TIOCGPGRP, &pgrp_inferior);
218 ioctl (0, TIOCSPGRP, &pgrp_ours);
220 signal (SIGTTOU, osigttou);
222 signal (SIGINT, sigint_ours);
223 signal (SIGQUIT, sigquit_ours);
224 #endif /* TIOCGPGRP */
226 tflags_inferior = fcntl (0, F_GETFL, 0);
227 ioctl (0, TIOCGETP, &sg_inferior);
229 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
230 ioctl (0, TIOCGETC, &tc_inferior);
233 ioctl (0, TIOCGLTC, <c_inferior);
236 ioctl (0, TIOCLGET, &lmode_inferior);
241 sg_ours.c_lflag |= ICANON;
242 if (output_only && !(sg_inferior.c_lflag & ICANON))
243 sg_ours.c_lflag &= ~ICANON;
244 #else /* not HAVE_TERMIO */
245 sg_ours.sg_flags &= ~RAW & ~CBREAK;
247 sg_ours.sg_flags |= (RAW | CBREAK) & sg_inferior.sg_flags;
248 #endif /* not HAVE_TERMIO */
250 fcntl (0, F_SETFL, tflags_ours);
251 fcntl (0, F_SETFL, tflags_ours);
252 ioctl (0, TIOCSETN, &sg_ours);
254 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
255 ioctl (0, TIOCSETC, &tc_ours);
258 ioctl (0, TIOCSLTC, <c_ours);
261 ioctl (0, TIOCLSET, &lmode_ours);
265 sg_ours.c_lflag |= ICANON;
266 #else /* not HAVE_TERMIO */
267 sg_ours.sg_flags &= ~RAW & ~CBREAK;
268 #endif /* not HAVE_TERMIO */
272 term_status_command ()
276 if (remote_debugging)
278 printf_filtered ("No terminal status when remote debugging.\n");
282 printf_filtered ("Inferior's terminal status (currently saved by GDB):\n");
286 printf_filtered ("fcntl flags = 0x%x, c_iflag = 0x%x, c_oflag = 0x%x,\n",
287 tflags_inferior, sg_inferior.c_iflag, sg_inferior.c_oflag);
288 printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n",
289 sg_inferior.c_cflag, sg_inferior.c_lflag, sg_inferior.c_line);
290 printf_filtered ("c_cc: ");
291 for (i = 0; (i < NCC); i += 1)
292 printf_filtered ("0x%x ", sg_inferior.c_cc[i]);
293 printf_filtered ("\n");
295 #else /* not HAVE_TERMIO */
297 printf_filtered ("fcntl flags = 0x%x, sgttyb.sg_flags = 0x%x, owner pid = %d.\n",
298 tflags_inferior, sg_inferior.sg_flags, pgrp_inferior);
300 #endif /* not HAVE_TERMIO */
302 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
303 printf_filtered ("tchars: ");
304 for (i = 0; i < sizeof (struct tchars); i++)
305 printf_filtered ("0x%x ", ((char *)&tc_inferior)[i]);
306 printf_filtered ("\n");
310 printf_filtered ("ltchars: ");
311 for (i = 0; i < sizeof (struct ltchars); i++)
312 printf_filtered ("0x%x ", ((char *)<c_inferior)[i]);
313 printf_filtered ("\n");
314 ioctl (0, TIOCSLTC, <c_ours);
318 printf_filtered ("lmode: %x\n", lmode_inferior);
330 /* Disconnect the child process from our controlling terminal. */
331 tty = open("/dev/tty", O_RDWR);
334 ioctl(tty, TIOCNOTTY, 0);
339 /* Now open the specified new terminal. */
341 tty = open(ttyname, O_RDWR);
345 /* Avoid use of dup2; doesn't exist on all systems. */
347 { close (0); dup (tty); }
349 { close (1); dup (tty); }
351 { close (2); dup (tty); }
356 /* Start an inferior process and returns its pid.
357 ALLARGS is a string containing shell command to run the program.
358 ENV is the environment vector to pass. */
361 #define SHELL_FILE "/bin/sh"
365 create_inferior (allargs, env)
372 extern char *sys_errlist[];
375 /* If desired, concat something onto the front of ALLARGS.
376 SHELL_COMMAND is the result. */
377 #ifdef SHELL_COMMAND_CONCAT
378 shell_command = (char *) alloca (strlen (SHELL_COMMAND_CONCAT) + strlen (allargs) + 1);
379 strcpy (shell_command, SHELL_COMMAND_CONCAT);
380 strcat (shell_command, allargs);
382 shell_command = allargs;
385 /* exec is said to fail if the executable is open. */
388 #if defined(USG) && !defined(HAVE_VFORK)
395 perror_with_name ("vfork");
400 /* Run inferior in a separate process group. */
401 setpgrp (getpid (), getpid ());
402 #endif /* TIOCGPGRP */
404 #ifdef SET_STACK_LIMIT_HUGE
405 /* Reset the stack limit back to what it was. */
409 getrlimit (RLIMIT_STACK, &rlim);
410 rlim.rlim_cur = original_stack_limit;
411 setrlimit (RLIMIT_STACK, &rlim);
413 #endif /* SET_STACK_LIMIT_HUGE */
416 inferior_thisrun_terminal = inferior_io_terminal;
417 if (inferior_io_terminal != 0)
418 new_tty (inferior_io_terminal);
420 /* It seems that changing the signal handlers for the inferior after
421 a vfork also changes them for the superior. See comments in
422 initialize_signals for how we get the right signal handlers
424 /* Not needed on Sun, at least, and loses there
425 because it clobbers the superior. */
426 /*??? signal (SIGQUIT, SIG_DFL);
427 signal (SIGINT, SIG_DFL); */
430 execle (SHELL_FILE, "sh", "-c", shell_command, 0, env);
432 fprintf (stderr, "Cannot exec %s: %s.\n", SHELL_FILE,
433 errno < sys_nerr ? sys_errlist[errno] : "unknown error");
438 #ifdef CREATE_INFERIOR_HOOK
439 CREATE_INFERIOR_HOOK (pid);
444 /* Kill the inferior process. Make us have no inferior. */
449 if (remote_debugging)
451 if (inferior_pid == 0)
452 error ("The program is not being run.");
453 if (!query ("Kill the inferior process? "))
454 error ("Not confirmed.");
463 mark_breakpoints_out ();
464 select_frame ((FRAME) 0, -1);
466 if (have_core_file_p ())
467 set_current_frame ( create_new_frame (read_register (FP_REGNUM),
470 set_current_frame (0);
474 /* This function is just for testing, and on some systems (Sony NewsOS
475 3.2) <sys/user.h> also includes <sys/time.h> which leads to errors
476 (since on this system at least sys/time.h is not protected against
477 multiple inclusion). */
479 try_writing_regs_command ()
485 if (inferior_pid == 0)
486 error ("There is no inferior process now.");
488 /* A Sun 3/50 or 3/60 (at least) running SunOS 4.0.3 will have a
489 kernel panic if we try to write past the end of the user area.
490 Presumably Sun will fix this bug (it has been reported), but it
491 is tacky to crash the system, so at least on SunOS4 we need to
492 stop writing when we hit the end of the user area. */
493 for (i = 0; i < sizeof (struct user); i += 2)
497 value = call_ptrace (3, inferior_pid, i, 0);
498 call_ptrace (6, inferior_pid, i, value);
501 printf (" Succeeded with address 0x%x; value 0x%x (%d).\n",
504 else if ((i & 0377) == 0)
505 printf (" Failed at 0x%x.\n", i);
511 _initialize_inflow ()
513 add_com ("term-status", class_obscure, term_status_command,
514 "Print info on inferior's saved terminal status.");
517 add_com ("try-writing-regs", class_obscure, try_writing_regs_command,
518 "Try writing all locations in inferior's system block.\n\
519 Report which ones can be written.");
522 add_com ("kill", class_run, kill_command,
523 "Kill execution of program being debugged.");
527 ioctl (0, TIOCGETP, &sg_ours);
528 fcntl (0, F_GETFL, tflags_ours);
530 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
531 ioctl (0, TIOCGETC, &tc_ours);
534 ioctl (0, TIOCGLTC, <c_ours);
537 ioctl (0, TIOCLGET, &lmode_ours);
541 ioctl (0, TIOCGPGRP, &pgrp_ours);
542 #endif /* TIOCGPGRP */
544 terminal_is_ours = 1;