gdb-3.4
[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 "defs.h"
21 #include "param.h"
22 #include "frame.h"
23 #include "inferior.h"
24
25 #ifdef USG
26 #include <sys/types.h>
27 #include <fcntl.h>
28 #endif
29
30 #include <stdio.h>
31 #include <sys/param.h>
32 #include <sys/dir.h>
33 #include <signal.h>
34
35 #ifdef HAVE_TERMIO
36 #include <termio.h>
37 #undef TIOCGETP
38 #define TIOCGETP TCGETA
39 #undef TIOCSETN
40 #define TIOCSETN TCSETA
41 #undef TIOCSETP
42 #define TIOCSETP TCSETAF
43 #define TERMINAL struct termio
44 #else
45 #include <sys/ioctl.h>
46 #include <fcntl.h>
47 #include <sgtty.h>
48 #define TERMINAL struct sgttyb
49 #endif
50
51 #ifdef SET_STACK_LIMIT_HUGE
52 #include <sys/time.h>
53 #include <sys/resource.h>
54 extern int original_stack_limit;
55 #endif /* SET_STACK_LIMIT_HUGE */
56
57 extern int errno;
58
59 /* Nonzero if we are debugging an attached outside process
60 rather than an inferior. */
61
62 int attach_flag;
63
64 \f
65 /* Record terminal status separately for debugger and inferior. */
66
67 static TERMINAL sg_inferior;
68 static TERMINAL sg_ours;
69
70 static int tflags_inferior;
71 static int tflags_ours;
72
73 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
74 static struct tchars tc_inferior;
75 static struct tchars tc_ours;
76 #endif
77
78 #ifdef TIOCGLTC
79 static struct ltchars ltc_inferior;
80 static struct ltchars ltc_ours;
81 #endif
82
83 #ifdef TIOCLGET
84 static int lmode_inferior;
85 static int lmode_ours;
86 #endif
87
88 #ifdef TIOCGPGRP
89 static int pgrp_inferior;
90 static int pgrp_ours;
91 #else
92 static int (*sigint_ours) ();
93 static int (*sigquit_ours) ();
94 #endif /* TIOCGPGRP */
95
96 /* Copy of inferior_io_terminal when inferior was last started. */
97 static char *inferior_thisrun_terminal;
98
99 static void terminal_ours_1 ();
100
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;
104
105 /* Initialize the terminal settings we record for the inferior,
106 before we actually run the inferior. */
107
108 void
109 terminal_init_inferior ()
110 {
111 if (remote_debugging)
112 return;
113
114 sg_inferior = sg_ours;
115 tflags_inferior = tflags_ours;
116
117 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
118 tc_inferior = tc_ours;
119 #endif
120
121 #ifdef TIOCGLTC
122 ltc_inferior = ltc_ours;
123 #endif
124
125 #ifdef TIOCLGET
126 lmode_inferior = lmode_ours;
127 #endif
128
129 #ifdef TIOCGPGRP
130 pgrp_inferior = inferior_pid;
131 #endif /* TIOCGPGRP */
132
133 terminal_is_ours = 1;
134 }
135
136 /* Put the inferior's terminal settings into effect.
137 This is preparation for starting or resuming the inferior. */
138
139 void
140 terminal_inferior ()
141 {
142 if (remote_debugging)
143 return;
144
145 if (terminal_is_ours) /* && inferior_thisrun_terminal == 0) */
146 {
147 fcntl (0, F_SETFL, tflags_inferior);
148 fcntl (0, F_SETFL, tflags_inferior);
149 ioctl (0, TIOCSETN, &sg_inferior);
150
151 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
152 ioctl (0, TIOCSETC, &tc_inferior);
153 #endif
154 #ifdef TIOCGLTC
155 ioctl (0, TIOCSLTC, &ltc_inferior);
156 #endif
157 #ifdef TIOCLGET
158 ioctl (0, TIOCLSET, &lmode_inferior);
159 #endif
160
161 #ifdef TIOCGPGRP
162 ioctl (0, TIOCSPGRP, &pgrp_inferior);
163 #else
164 sigint_ours = (int (*) ()) signal (SIGINT, SIG_IGN);
165 sigquit_ours = (int (*) ()) signal (SIGQUIT, SIG_IGN);
166 #endif /* TIOCGPGRP */
167 }
168 terminal_is_ours = 0;
169 }
170
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.
175
176 After doing this, either terminal_ours or terminal_inferior
177 should be called to get back to a normal state of affairs. */
178
179 void
180 terminal_ours_for_output ()
181 {
182 if (remote_debugging)
183 return;
184
185 terminal_ours_1 (1);
186 }
187
188 /* Put our terminal settings into effect.
189 First record the inferior's terminal settings
190 so they can be restored properly later. */
191
192 void
193 terminal_ours ()
194 {
195 if (remote_debugging)
196 return;
197
198 terminal_ours_1 (0);
199 }
200
201 static void
202 terminal_ours_1 (output_only)
203 int output_only;
204 {
205 #ifdef TIOCGPGRP
206 /* Ignore this signal since it will happen when we try to set the pgrp. */
207 int (*osigttou) ();
208 #endif /* TIOCGPGRP */
209
210 if (!terminal_is_ours) /* && inferior_thisrun_terminal == 0) */
211 {
212 terminal_is_ours = 1;
213
214 #ifdef TIOCGPGRP
215 osigttou = (int (*) ()) signal (SIGTTOU, SIG_IGN);
216
217 ioctl (0, TIOCGPGRP, &pgrp_inferior);
218 ioctl (0, TIOCSPGRP, &pgrp_ours);
219
220 signal (SIGTTOU, osigttou);
221 #else
222 signal (SIGINT, sigint_ours);
223 signal (SIGQUIT, sigquit_ours);
224 #endif /* TIOCGPGRP */
225
226 tflags_inferior = fcntl (0, F_GETFL, 0);
227 ioctl (0, TIOCGETP, &sg_inferior);
228
229 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
230 ioctl (0, TIOCGETC, &tc_inferior);
231 #endif
232 #ifdef TIOCGLTC
233 ioctl (0, TIOCGLTC, &ltc_inferior);
234 #endif
235 #ifdef TIOCLGET
236 ioctl (0, TIOCLGET, &lmode_inferior);
237 #endif
238 }
239
240 #ifdef HAVE_TERMIO
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;
246 if (output_only)
247 sg_ours.sg_flags |= (RAW | CBREAK) & sg_inferior.sg_flags;
248 #endif /* not HAVE_TERMIO */
249
250 fcntl (0, F_SETFL, tflags_ours);
251 fcntl (0, F_SETFL, tflags_ours);
252 ioctl (0, TIOCSETN, &sg_ours);
253
254 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
255 ioctl (0, TIOCSETC, &tc_ours);
256 #endif
257 #ifdef TIOCGLTC
258 ioctl (0, TIOCSLTC, &ltc_ours);
259 #endif
260 #ifdef TIOCLGET
261 ioctl (0, TIOCLSET, &lmode_ours);
262 #endif
263
264 #ifdef HAVE_TERMIO
265 sg_ours.c_lflag |= ICANON;
266 #else /* not HAVE_TERMIO */
267 sg_ours.sg_flags &= ~RAW & ~CBREAK;
268 #endif /* not HAVE_TERMIO */
269 }
270
271 static void
272 term_status_command ()
273 {
274 register int i;
275
276 if (remote_debugging)
277 {
278 printf_filtered ("No terminal status when remote debugging.\n");
279 return;
280 }
281
282 printf_filtered ("Inferior's terminal status (currently saved by GDB):\n");
283
284 #ifdef HAVE_TERMIO
285
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");
294
295 #else /* not HAVE_TERMIO */
296
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);
299
300 #endif /* not HAVE_TERMIO */
301
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");
307 #endif
308
309 #ifdef TIOCGLTC
310 printf_filtered ("ltchars: ");
311 for (i = 0; i < sizeof (struct ltchars); i++)
312 printf_filtered ("0x%x ", ((char *)&ltc_inferior)[i]);
313 printf_filtered ("\n");
314 ioctl (0, TIOCSLTC, &ltc_ours);
315 #endif
316
317 #ifdef TIOCLGET
318 printf_filtered ("lmode: %x\n", lmode_inferior);
319 #endif
320 }
321 \f
322 static void
323 new_tty (ttyname)
324 char *ttyname;
325 {
326 register int tty;
327 register int fd;
328
329 #ifdef TIOCNOTTY
330 /* Disconnect the child process from our controlling terminal. */
331 tty = open("/dev/tty", O_RDWR);
332 if (tty > 0)
333 {
334 ioctl(tty, TIOCNOTTY, 0);
335 close(tty);
336 }
337 #endif
338
339 /* Now open the specified new terminal. */
340
341 tty = open(ttyname, O_RDWR);
342 if (tty == -1)
343 _exit(1);
344
345 /* Avoid use of dup2; doesn't exist on all systems. */
346 if (tty != 0)
347 { close (0); dup (tty); }
348 if (tty != 1)
349 { close (1); dup (tty); }
350 if (tty != 2)
351 { close (2); dup (tty); }
352 if (tty > 2)
353 close(tty);
354 }
355 \f
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. */
359
360 #ifndef SHELL_FILE
361 #define SHELL_FILE "/bin/sh"
362 #endif
363
364 int
365 create_inferior (allargs, env)
366 char *allargs;
367 char **env;
368 {
369 int pid;
370 char *shell_command;
371 extern int sys_nerr;
372 extern char *sys_errlist[];
373 extern int errno;
374
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);
381 #else
382 shell_command = allargs;
383 #endif
384
385 /* exec is said to fail if the executable is open. */
386 close_exec_file ();
387
388 #if defined(USG) && !defined(HAVE_VFORK)
389 pid = fork ();
390 #else
391 pid = vfork ();
392 #endif
393
394 if (pid < 0)
395 perror_with_name ("vfork");
396
397 if (pid == 0)
398 {
399 #ifdef TIOCGPGRP
400 /* Run inferior in a separate process group. */
401 setpgrp (getpid (), getpid ());
402 #endif /* TIOCGPGRP */
403
404 #ifdef SET_STACK_LIMIT_HUGE
405 /* Reset the stack limit back to what it was. */
406 {
407 struct rlimit rlim;
408
409 getrlimit (RLIMIT_STACK, &rlim);
410 rlim.rlim_cur = original_stack_limit;
411 setrlimit (RLIMIT_STACK, &rlim);
412 }
413 #endif /* SET_STACK_LIMIT_HUGE */
414
415
416 inferior_thisrun_terminal = inferior_io_terminal;
417 if (inferior_io_terminal != 0)
418 new_tty (inferior_io_terminal);
419
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
423 for the inferior. */
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); */
428
429 call_ptrace (0);
430 execle (SHELL_FILE, "sh", "-c", shell_command, 0, env);
431
432 fprintf (stderr, "Cannot exec %s: %s.\n", SHELL_FILE,
433 errno < sys_nerr ? sys_errlist[errno] : "unknown error");
434 fflush (stderr);
435 _exit (0177);
436 }
437
438 #ifdef CREATE_INFERIOR_HOOK
439 CREATE_INFERIOR_HOOK (pid);
440 #endif
441 return pid;
442 }
443
444 /* Kill the inferior process. Make us have no inferior. */
445
446 static void
447 kill_command ()
448 {
449 if (remote_debugging)
450 return;
451 if (inferior_pid == 0)
452 error ("The program is not being run.");
453 if (!query ("Kill the inferior process? "))
454 error ("Not confirmed.");
455 kill_inferior ();
456 }
457
458 void
459 inferior_died ()
460 {
461 inferior_pid = 0;
462 attach_flag = 0;
463 mark_breakpoints_out ();
464 select_frame ((FRAME) 0, -1);
465 reopen_exec_file ();
466 if (have_core_file_p ())
467 set_current_frame ( create_new_frame (read_register (FP_REGNUM),
468 read_pc ()));
469 else
470 set_current_frame (0);
471 }
472 \f
473 #if 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). */
478 static void
479 try_writing_regs_command ()
480 {
481 register int i;
482 register int value;
483 extern int errno;
484
485 if (inferior_pid == 0)
486 error ("There is no inferior process now.");
487
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)
494 {
495 QUIT;
496 errno = 0;
497 value = call_ptrace (3, inferior_pid, i, 0);
498 call_ptrace (6, inferior_pid, i, value);
499 if (errno == 0)
500 {
501 printf (" Succeeded with address 0x%x; value 0x%x (%d).\n",
502 i, value, value);
503 }
504 else if ((i & 0377) == 0)
505 printf (" Failed at 0x%x.\n", i);
506 }
507 }
508 #endif
509 \f
510 void
511 _initialize_inflow ()
512 {
513 add_com ("term-status", class_obscure, term_status_command,
514 "Print info on inferior's saved terminal status.");
515
516 #if 0
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.");
520 #endif
521
522 add_com ("kill", class_run, kill_command,
523 "Kill execution of program being debugged.");
524
525 inferior_pid = 0;
526
527 ioctl (0, TIOCGETP, &sg_ours);
528 fcntl (0, F_GETFL, tflags_ours);
529
530 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
531 ioctl (0, TIOCGETC, &tc_ours);
532 #endif
533 #ifdef TIOCGLTC
534 ioctl (0, TIOCGLTC, &ltc_ours);
535 #endif
536 #ifdef TIOCLGET
537 ioctl (0, TIOCLGET, &lmode_ours);
538 #endif
539
540 #ifdef TIOCGPGRP
541 ioctl (0, TIOCGPGRP, &pgrp_ours);
542 #endif /* TIOCGPGRP */
543
544 terminal_is_ours = 1;
545 }
546