gdb-3.5
[binutils-gdb.git] / gdb / inflow.c
1 /* Low level interface to ptrace, for GDB when running under Unix.
2 Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
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)
9 any later version.
10
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.
15
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. */
19
20 #include <stdio.h>
21 #include "defs.h"
22 #include "param.h"
23 #include "frame.h"
24 #include "inferior.h"
25
26 #ifdef USG
27 #include <sys/types.h>
28 #endif
29
30 /* Some USG-esque systems (some of which are BSD-esque enough so that USG
31 is not defined) want this header, and it won't do any harm. */
32 #include <fcntl.h>
33
34 #include <sys/param.h>
35 #include <sys/dir.h>
36 #include <signal.h>
37
38 #ifdef HAVE_TERMIO
39 #include <termio.h>
40 #undef TIOCGETP
41 #define TIOCGETP TCGETA
42 #undef TIOCSETN
43 #define TIOCSETN TCSETA
44 #undef TIOCSETP
45 #define TIOCSETP TCSETAF
46 #define TERMINAL struct termio
47 #else
48 #include <sys/ioctl.h>
49 #include <fcntl.h>
50 #include <sgtty.h>
51 #define TERMINAL struct sgttyb
52 #endif
53
54 #ifdef SET_STACK_LIMIT_HUGE
55 #include <sys/time.h>
56 #include <sys/resource.h>
57 extern int original_stack_limit;
58 #endif /* SET_STACK_LIMIT_HUGE */
59
60 extern int errno;
61
62 /* Nonzero if we are debugging an attached outside process
63 rather than an inferior. */
64
65 int attach_flag;
66
67 \f
68 /* Record terminal status separately for debugger and inferior. */
69
70 static TERMINAL sg_inferior;
71 static TERMINAL sg_ours;
72
73 static int tflags_inferior;
74 static int tflags_ours;
75
76 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
77 static struct tchars tc_inferior;
78 static struct tchars tc_ours;
79 #endif
80
81 #ifdef TIOCGLTC
82 static struct ltchars ltc_inferior;
83 static struct ltchars ltc_ours;
84 #endif
85
86 #ifdef TIOCLGET
87 static int lmode_inferior;
88 static int lmode_ours;
89 #endif
90
91 #ifdef TIOCGPGRP
92 static int pgrp_inferior;
93 static int pgrp_ours;
94 #else
95 static int (*sigint_ours) ();
96 static int (*sigquit_ours) ();
97 #endif /* TIOCGPGRP */
98
99 /* Copy of inferior_io_terminal when inferior was last started. */
100 static char *inferior_thisrun_terminal;
101
102 static void terminal_ours_1 ();
103
104 /* Nonzero if our terminal settings are in effect.
105 Zero if the inferior's settings are in effect. */
106 static int terminal_is_ours;
107
108 /* Initialize the terminal settings we record for the inferior,
109 before we actually run the inferior. */
110
111 void
112 terminal_init_inferior ()
113 {
114 if (remote_debugging)
115 return;
116
117 sg_inferior = sg_ours;
118 tflags_inferior = tflags_ours;
119
120 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
121 tc_inferior = tc_ours;
122 #endif
123
124 #ifdef TIOCGLTC
125 ltc_inferior = ltc_ours;
126 #endif
127
128 #ifdef TIOCLGET
129 lmode_inferior = lmode_ours;
130 #endif
131
132 #ifdef TIOCGPGRP
133 pgrp_inferior = inferior_pid;
134 #endif /* TIOCGPGRP */
135
136 terminal_is_ours = 1;
137 }
138
139 /* Put the inferior's terminal settings into effect.
140 This is preparation for starting or resuming the inferior. */
141
142 void
143 terminal_inferior ()
144 {
145 if (remote_debugging)
146 return;
147
148 if (terminal_is_ours) /* && inferior_thisrun_terminal == 0) */
149 {
150 fcntl (0, F_SETFL, tflags_inferior);
151 fcntl (0, F_SETFL, tflags_inferior);
152 ioctl (0, TIOCSETN, &sg_inferior);
153
154 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
155 ioctl (0, TIOCSETC, &tc_inferior);
156 #endif
157 #ifdef TIOCGLTC
158 ioctl (0, TIOCSLTC, &ltc_inferior);
159 #endif
160 #ifdef TIOCLGET
161 ioctl (0, TIOCLSET, &lmode_inferior);
162 #endif
163
164 #ifdef TIOCGPGRP
165 ioctl (0, TIOCSPGRP, &pgrp_inferior);
166 #else
167 sigint_ours = (int (*) ()) signal (SIGINT, SIG_IGN);
168 sigquit_ours = (int (*) ()) signal (SIGQUIT, SIG_IGN);
169 #endif /* TIOCGPGRP */
170 }
171 terminal_is_ours = 0;
172 }
173
174 /* Put some of our terminal settings into effect,
175 enough to get proper results from our output,
176 but do not change into or out of RAW mode
177 so that no input is discarded.
178
179 After doing this, either terminal_ours or terminal_inferior
180 should be called to get back to a normal state of affairs. */
181
182 void
183 terminal_ours_for_output ()
184 {
185 if (remote_debugging)
186 return;
187
188 terminal_ours_1 (1);
189 }
190
191 /* Put our terminal settings into effect.
192 First record the inferior's terminal settings
193 so they can be restored properly later. */
194
195 void
196 terminal_ours ()
197 {
198 if (remote_debugging)
199 return;
200
201 terminal_ours_1 (0);
202 }
203
204 static void
205 terminal_ours_1 (output_only)
206 int output_only;
207 {
208 #ifdef TIOCGPGRP
209 /* Ignore this signal since it will happen when we try to set the pgrp. */
210 int (*osigttou) ();
211 #endif /* TIOCGPGRP */
212
213 if (!terminal_is_ours) /* && inferior_thisrun_terminal == 0) */
214 {
215 terminal_is_ours = 1;
216
217 #ifdef TIOCGPGRP
218 osigttou = (int (*) ()) signal (SIGTTOU, SIG_IGN);
219
220 ioctl (0, TIOCGPGRP, &pgrp_inferior);
221 ioctl (0, TIOCSPGRP, &pgrp_ours);
222
223 signal (SIGTTOU, osigttou);
224 #else
225 signal (SIGINT, sigint_ours);
226 signal (SIGQUIT, sigquit_ours);
227 #endif /* TIOCGPGRP */
228
229 tflags_inferior = fcntl (0, F_GETFL, 0);
230 ioctl (0, TIOCGETP, &sg_inferior);
231
232 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
233 ioctl (0, TIOCGETC, &tc_inferior);
234 #endif
235 #ifdef TIOCGLTC
236 ioctl (0, TIOCGLTC, &ltc_inferior);
237 #endif
238 #ifdef TIOCLGET
239 ioctl (0, TIOCLGET, &lmode_inferior);
240 #endif
241 }
242
243 #ifdef HAVE_TERMIO
244 sg_ours.c_lflag |= ICANON;
245 if (output_only && !(sg_inferior.c_lflag & ICANON))
246 sg_ours.c_lflag &= ~ICANON;
247 #else /* not HAVE_TERMIO */
248 sg_ours.sg_flags &= ~RAW & ~CBREAK;
249 if (output_only)
250 sg_ours.sg_flags |= (RAW | CBREAK) & sg_inferior.sg_flags;
251 #endif /* not HAVE_TERMIO */
252
253 fcntl (0, F_SETFL, tflags_ours);
254 fcntl (0, F_SETFL, tflags_ours);
255 ioctl (0, TIOCSETN, &sg_ours);
256
257 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
258 ioctl (0, TIOCSETC, &tc_ours);
259 #endif
260 #ifdef TIOCGLTC
261 ioctl (0, TIOCSLTC, &ltc_ours);
262 #endif
263 #ifdef TIOCLGET
264 ioctl (0, TIOCLSET, &lmode_ours);
265 #endif
266
267 #ifdef HAVE_TERMIO
268 sg_ours.c_lflag |= ICANON;
269 #else /* not HAVE_TERMIO */
270 sg_ours.sg_flags &= ~RAW & ~CBREAK;
271 #endif /* not HAVE_TERMIO */
272 }
273
274 static void
275 term_status_command ()
276 {
277 register int i;
278
279 if (remote_debugging)
280 {
281 printf_filtered ("No terminal status when remote debugging.\n");
282 return;
283 }
284
285 printf_filtered ("Inferior's terminal status (currently saved by GDB):\n");
286
287 #ifdef HAVE_TERMIO
288
289 printf_filtered ("fcntl flags = 0x%x, c_iflag = 0x%x, c_oflag = 0x%x,\n",
290 tflags_inferior, sg_inferior.c_iflag, sg_inferior.c_oflag);
291 printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n",
292 sg_inferior.c_cflag, sg_inferior.c_lflag, sg_inferior.c_line);
293 printf_filtered ("c_cc: ");
294 for (i = 0; (i < NCC); i += 1)
295 printf_filtered ("0x%x ", sg_inferior.c_cc[i]);
296 printf_filtered ("\n");
297
298 #else /* not HAVE_TERMIO */
299
300 printf_filtered ("fcntl flags = 0x%x, sgttyb.sg_flags = 0x%x, owner pid = %d.\n",
301 tflags_inferior, sg_inferior.sg_flags, pgrp_inferior);
302
303 #endif /* not HAVE_TERMIO */
304
305 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
306 printf_filtered ("tchars: ");
307 for (i = 0; i < sizeof (struct tchars); i++)
308 printf_filtered ("0x%x ", ((char *)&tc_inferior)[i]);
309 printf_filtered ("\n");
310 #endif
311
312 #ifdef TIOCGLTC
313 printf_filtered ("ltchars: ");
314 for (i = 0; i < sizeof (struct ltchars); i++)
315 printf_filtered ("0x%x ", ((char *)&ltc_inferior)[i]);
316 printf_filtered ("\n");
317 ioctl (0, TIOCSLTC, &ltc_ours);
318 #endif
319
320 #ifdef TIOCLGET
321 printf_filtered ("lmode: %x\n", lmode_inferior);
322 #endif
323 }
324 \f
325 static void
326 new_tty (ttyname)
327 char *ttyname;
328 {
329 register int tty;
330 register int fd;
331
332 #ifdef TIOCNOTTY
333 /* Disconnect the child process from our controlling terminal. */
334 tty = open("/dev/tty", O_RDWR);
335 if (tty > 0)
336 {
337 ioctl(tty, TIOCNOTTY, 0);
338 close(tty);
339 }
340 #endif
341
342 /* Now open the specified new terminal. */
343
344 tty = open(ttyname, O_RDWR);
345 if (tty == -1)
346 _exit(1);
347
348 /* Avoid use of dup2; doesn't exist on all systems. */
349 if (tty != 0)
350 { close (0); dup (tty); }
351 if (tty != 1)
352 { close (1); dup (tty); }
353 if (tty != 2)
354 { close (2); dup (tty); }
355 if (tty > 2)
356 close(tty);
357 }
358 \f
359 /* Start an inferior process and returns its pid.
360 ALLARGS is a string containing shell command to run the program.
361 ENV is the environment vector to pass. */
362
363 #ifndef SHELL_FILE
364 #define SHELL_FILE "/bin/sh"
365 #endif
366
367 int
368 create_inferior (allargs, env)
369 char *allargs;
370 char **env;
371 {
372 int pid;
373 char *shell_command;
374 extern int sys_nerr;
375 extern char *sys_errlist[];
376 extern int errno;
377
378 /* If desired, concat something onto the front of ALLARGS.
379 SHELL_COMMAND is the result. */
380 #ifdef SHELL_COMMAND_CONCAT
381 shell_command = (char *) alloca (strlen (SHELL_COMMAND_CONCAT) + strlen (allargs) + 1);
382 strcpy (shell_command, SHELL_COMMAND_CONCAT);
383 strcat (shell_command, allargs);
384 #else
385 shell_command = allargs;
386 #endif
387
388 /* exec is said to fail if the executable is open. */
389 close_exec_file ();
390
391 #if defined(USG) && !defined(HAVE_VFORK)
392 pid = fork ();
393 #else
394 pid = vfork ();
395 #endif
396
397 if (pid < 0)
398 perror_with_name ("vfork");
399
400 if (pid == 0)
401 {
402 #ifdef TIOCGPGRP
403 /* Run inferior in a separate process group. */
404 setpgrp (getpid (), getpid ());
405 #endif /* TIOCGPGRP */
406
407 #ifdef SET_STACK_LIMIT_HUGE
408 /* Reset the stack limit back to what it was. */
409 {
410 struct rlimit rlim;
411
412 getrlimit (RLIMIT_STACK, &rlim);
413 rlim.rlim_cur = original_stack_limit;
414 setrlimit (RLIMIT_STACK, &rlim);
415 }
416 #endif /* SET_STACK_LIMIT_HUGE */
417
418
419 inferior_thisrun_terminal = inferior_io_terminal;
420 if (inferior_io_terminal != 0)
421 new_tty (inferior_io_terminal);
422
423 /* It seems that changing the signal handlers for the inferior after
424 a vfork also changes them for the superior. See comments in
425 initialize_signals for how we get the right signal handlers
426 for the inferior. */
427 /* Not needed on Sun, at least, and loses there
428 because it clobbers the superior. */
429 /*??? signal (SIGQUIT, SIG_DFL);
430 signal (SIGINT, SIG_DFL); */
431
432 call_ptrace (0);
433 execle (SHELL_FILE, "sh", "-c", shell_command, 0, env);
434
435 fprintf (stderr, "Cannot exec %s: %s.\n", SHELL_FILE,
436 errno < sys_nerr ? sys_errlist[errno] : "unknown error");
437 fflush (stderr);
438 _exit (0177);
439 }
440
441 #ifdef CREATE_INFERIOR_HOOK
442 CREATE_INFERIOR_HOOK (pid);
443 #endif
444 return pid;
445 }
446
447 /* Kill the inferior process. Make us have no inferior. */
448
449 static void
450 kill_command ()
451 {
452 if (remote_debugging)
453 return;
454 if (inferior_pid == 0)
455 error ("The program is not being run.");
456 if (!query ("Kill the inferior process? "))
457 error ("Not confirmed.");
458 kill_inferior ();
459 }
460
461 void
462 inferior_died ()
463 {
464 inferior_pid = 0;
465 attach_flag = 0;
466 mark_breakpoints_out ();
467 select_frame ((FRAME) 0, -1);
468 reopen_exec_file ();
469 if (have_core_file_p ())
470 set_current_frame ( create_new_frame (read_register (FP_REGNUM),
471 read_pc ()));
472 else
473 set_current_frame (0);
474 }
475 \f
476 #if 0
477 /* This function is just for testing, and on some systems (Sony NewsOS
478 3.2) <sys/user.h> also includes <sys/time.h> which leads to errors
479 (since on this system at least sys/time.h is not protected against
480 multiple inclusion). */
481 static void
482 try_writing_regs_command ()
483 {
484 register int i;
485 register int value;
486 extern int errno;
487
488 if (inferior_pid == 0)
489 error ("There is no inferior process now.");
490
491 /* A Sun 3/50 or 3/60 (at least) running SunOS 4.0.3 will have a
492 kernel panic if we try to write past the end of the user area.
493 Presumably Sun will fix this bug (it has been reported), but it
494 is tacky to crash the system, so at least on SunOS4 we need to
495 stop writing when we hit the end of the user area. */
496 for (i = 0; i < sizeof (struct user); i += 2)
497 {
498 QUIT;
499 errno = 0;
500 value = call_ptrace (3, inferior_pid, i, 0);
501 call_ptrace (6, inferior_pid, i, value);
502 if (errno == 0)
503 {
504 printf (" Succeeded with address 0x%x; value 0x%x (%d).\n",
505 i, value, value);
506 }
507 else if ((i & 0377) == 0)
508 printf (" Failed at 0x%x.\n", i);
509 }
510 }
511 #endif
512 \f
513 void
514 _initialize_inflow ()
515 {
516 add_com ("term-status", class_obscure, term_status_command,
517 "Print info on inferior's saved terminal status.");
518
519 #if 0
520 add_com ("try-writing-regs", class_obscure, try_writing_regs_command,
521 "Try writing all locations in inferior's system block.\n\
522 Report which ones can be written.");
523 #endif
524
525 add_com ("kill", class_run, kill_command,
526 "Kill execution of program being debugged.");
527
528 inferior_pid = 0;
529
530 ioctl (0, TIOCGETP, &sg_ours);
531 fcntl (0, F_GETFL, tflags_ours);
532
533 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
534 ioctl (0, TIOCGETC, &tc_ours);
535 #endif
536 #ifdef TIOCGLTC
537 ioctl (0, TIOCGLTC, &ltc_ours);
538 #endif
539 #ifdef TIOCLGET
540 ioctl (0, TIOCLGET, &lmode_ours);
541 #endif
542
543 #ifdef TIOCGPGRP
544 ioctl (0, TIOCGPGRP, &pgrp_ours);
545 #endif /* TIOCGPGRP */
546
547 terminal_is_ours = 1;
548 }
549