e980cec16208ac7e12203e620ce19ef14a899636
[deliverable/binutils-gdb.git] / gdb / infrun.c
1 /* Start and stop the inferior process, for GDB.
2 Copyright (C) 1986, 1987 Free Software Foundation, Inc.
3
4 GDB is distributed in the hope that it will be useful, but WITHOUT ANY
5 WARRANTY. No author or distributor accepts responsibility to anyone
6 for the consequences of using it or for whether it serves any
7 particular purpose or works at all, unless he says so in writing.
8 Refer to the GDB General Public License for full details.
9
10 Everyone is granted permission to copy, modify and redistribute GDB,
11 but only under the conditions described in the GDB General Public
12 License. A copy of this license is supposed to have been given to you
13 along with GDB so you can know your rights and responsibilities. It
14 should be in a file named COPYING. Among other things, the copyright
15 notice and this notice must be preserved on all copies.
16
17 In other words, go ahead and share GDB, but don't try to stop
18 anyone else from sharing it farther. Help stamp out software hoarding!
19 */
20
21 #include "defs.h"
22 #include "initialize.h"
23 #include "param.h"
24 #include "symtab.h"
25 #include "frame.h"
26 #include "inferior.h"
27 #include "wait.h"
28
29 #include <stdio.h>
30 #include <signal.h>
31 #include <a.out.h>
32
33 #ifdef UMAX_PTRACE
34 #include <sys/param.h>
35 #include <sys/ptrace.h>
36 #endif UMAX_PTRACE
37
38 extern char *sys_siglist[];
39 extern int errno;
40
41 /* Tables of how to react to signals; the user sets them. */
42
43 static char signal_stop[NSIG];
44 static char signal_print[NSIG];
45 static char signal_program[NSIG];
46
47 /* Nonzero if breakpoints are now inserted in the inferior. */
48
49 static int breakpoints_inserted;
50
51 /* Function inferior was in as of last step command. */
52
53 static struct symbol *step_start_function;
54
55 /* This is the sequence of bytes we insert for a breakpoint. */
56
57 static char break_insn[] = BREAKPOINT;
58
59 /* Nonzero => address for special breakpoint for resuming stepping. */
60
61 static CORE_ADDR step_resume_break_address;
62
63 /* Original contents of the byte where the special breakpoint is. */
64
65 static char step_resume_break_shadow[sizeof break_insn];
66
67 /* Nonzero means the special breakpoint is a duplicate
68 so it has not itself been inserted. */
69
70 static int step_resume_break_duplicate;
71
72 /* Nonzero if we are expecting a trace trap and should proceed from it.
73 2 means expecting 2 trace traps and should continue both times.
74 That occurs when we tell sh to exec the program: we will get
75 a trap after the exec of sh and a second when the program is exec'd. */
76
77 static int trap_expected;
78
79 /* Nonzero means expecting a trace trap
80 and should stop the inferior and return silently when it happens. */
81
82 static int stop_after_trap;
83
84 /* Nonzero means expecting a trace trap due to attaching to a process. */
85
86 static int stop_after_attach;
87
88 /* Nonzero if pc has been changed by the debugger
89 since the inferior stopped. */
90
91 int pc_changed;
92
93 /* Save register contents here when about to pop a stack dummy frame. */
94
95 char stop_registers[REGISTER_BYTES];
96
97 /* Nonzero if program stopped due to error trying to insert breakpoints. */
98
99 static int breakpoints_failed;
100
101 /* Nonzero if inferior is in sh before our program got exec'd. */
102
103 static int running_in_shell;
104
105 /* Nonzero after stop if current stack frame should be printed. */
106
107 static int stop_print_frame;
108
109 static void insert_step_breakpoint ();
110 static void remove_step_breakpoint ();
111 static void wait_for_inferior ();
112 static void normal_stop ();
113
114 START_FILE
115 \f
116 /* Clear out all variables saying what to do when inferior is continued.
117 First do this, then set the ones you want, then call `proceed'. */
118
119 void
120 clear_proceed_status ()
121 {
122 trap_expected = 0;
123 step_range_start = 0;
124 step_range_end = 0;
125 step_frame = 0;
126 step_over_calls = -1;
127 step_resume_break_address = 0;
128 stop_after_trap = 0;
129 stop_after_attach = 0;
130
131 /* Discard any remaining commands left by breakpoint we had stopped at. */
132 clear_breakpoint_commands ();
133 }
134
135 /* Basic routine for continuing the program in various fashions.
136
137 ADDR is the address to resume at, or -1 for resume where stopped.
138 SIGNAL is the signal to give it, or 0 for none,
139 or -1 for act according to how it stopped.
140 STEP is nonzero if should trap after one instruction.
141 -1 means return after that and print nothing.
142 You should probably set various step_... variables
143 before calling here, if you are stepping.
144
145 You should call clear_proceed_status before calling proceed. */
146
147 void
148 proceed (addr, signal, step)
149 CORE_ADDR addr;
150 int signal;
151 int step;
152 {
153 int oneproc = 0;
154
155 if (step > 0)
156 step_start_function = find_pc_function (read_pc ());
157 if (step < 0)
158 stop_after_trap = 1;
159
160 if (addr == -1)
161 {
162 /* If there is a breakpoint at the address we will resume at,
163 step one instruction before inserting breakpoints
164 so that we do not stop right away. */
165
166 if (!pc_changed && breakpoint_here_p (read_pc ()))
167 {
168 oneproc = 1;
169 /* We will get a trace trap after one instruction.
170 Continue it automatically and insert breakpoints then. */
171 trap_expected = 1;
172 }
173 }
174 else
175 write_register (PC_REGNUM, addr);
176
177 if (!oneproc)
178 {
179 int temp = insert_breakpoints ();
180 if (temp)
181 {
182 print_sys_errmsg ("ptrace", temp);
183 error ("Cannot insert breakpoints.\n\
184 The same program may be running in another process.");
185 }
186 breakpoints_inserted = 1;
187 }
188
189 /* Install inferior's terminal modes. */
190 terminal_inferior ();
191
192 if (signal >= 0)
193 stop_signal = signal;
194 /* If this signal should not be seen by program,
195 give it zero. Used for debugging signals. */
196 else if (stop_signal < NSIG && !signal_program[stop_signal])
197 stop_signal= 0;
198
199 /* Resume inferior. */
200 resume (oneproc || step, stop_signal);
201
202 /* Wait for it to stop (if not standalone)
203 and in any case decode why it stopped, and act accordingly. */
204
205 wait_for_inferior ();
206 normal_stop ();
207 }
208
209 /* Writing the inferior pc as a register calls this function
210 to inform infrun that the pc has been set in the debugger. */
211
212 writing_pc (val)
213 CORE_ADDR val;
214 {
215 stop_pc = val;
216 pc_changed = 1;
217 }
218
219 /* Start an inferior process for the first time.
220 Actually it was started by the fork that created it,
221 but it will have stopped one instruction after execing sh.
222 Here we must get it up to actual execution of the real program. */
223
224 start_inferior ()
225 {
226 /* We will get a trace trap after one instruction.
227 Continue it automatically. Eventually (after shell does an exec)
228 it will get another trace trap. Then insert breakpoints and continue. */
229 trap_expected = 2;
230 running_in_shell = 0; /* Set to 1 at first SIGTRAP, 0 at second. */
231 breakpoints_inserted = 0;
232 mark_breakpoints_out ();
233
234 /* Set up the "saved terminal modes" of the inferior
235 based on what modes we are starting it with. */
236 terminal_init_inferior ();
237
238 /* Install inferior's terminal modes. */
239 terminal_inferior ();
240
241 wait_for_inferior ();
242 normal_stop ();
243 }
244
245 #ifdef ATTACH_DETACH
246
247 /* Attach to process PID, then initialize for debugging it
248 and wait for the trace-trap that results from attaching. */
249
250 void
251 attach_program (pid)
252 int pid;
253 {
254 attach (pid);
255 inferior_pid = pid;
256
257 mark_breakpoints_out ();
258 terminal_init_inferior ();
259 clear_proceed_status ();
260 stop_after_attach = 1;
261 /*proceed (-1, 0, -2);*/
262 wait_for_inferior ();
263 normal_stop ();
264 }
265 #endif /* ATTACH_DETACH */
266 \f
267 /* Wait for control to return from inferior to debugger.
268 If inferior gets a signal, we may decide to start it up again
269 instead of returning. That is why there is a loop in this function.
270 When this function actually returns it means the inferior
271 should be left stopped and GDB should read more commands. */
272
273 static void
274 wait_for_inferior ()
275 {
276 register int pid;
277 WAITTYPE w;
278 CORE_ADDR pc;
279 int tem;
280 int another_trap;
281 int random_signal;
282 CORE_ADDR stop_sp;
283 int stop_step_resume_break;
284 int newmisc;
285 int newfun_pc;
286 struct symbol *newfun;
287 struct symtab_and_line sal;
288 int prev_pc;
289
290 while (1)
291 {
292 prev_pc = read_pc ();
293 pid = wait (&w);
294 pc_changed = 0;
295 fetch_inferior_registers ();
296 stop_pc = read_pc ();
297 set_current_frame (read_register (FP_REGNUM));
298 stop_frame = get_current_frame ();
299 stop_sp = read_register (SP_REGNUM);
300 another_trap = 0;
301 stop_breakpoint = 0;
302 stop_step = 0;
303 stop_stack_dummy = 0;
304 stop_print_frame = 1;
305 stop_step_resume_break = 0;
306 random_signal = 0;
307 breakpoints_failed = 0;
308
309 /* Look at the cause of the stop, and decide what to do.
310 The alternatives are:
311 1) break; to really stop and return to the debugger,
312 2) drop through to start up again
313 (set another_trap to 1 to single step once)
314 3) set random_signal to 1, and the decision between 1 and 2
315 will be made according to the signal handling tables. */
316
317 if (WIFEXITED (w))
318 {
319 terminal_ours_for_output ();
320 if (WRETCODE (w))
321 printf ("\nProgram exited with code 0%o.\n", WRETCODE (w));
322 else
323 printf ("\nProgram exited normally.\n");
324 fflush (stdout);
325 inferior_died ();
326 stop_print_frame = 0;
327 break;
328 }
329 else if (!WIFSTOPPED (w))
330 {
331 kill_inferior ();
332 stop_print_frame = 0;
333 stop_signal = WTERMSIG (w);
334 terminal_ours_for_output ();
335 printf ("\nProgram terminated with signal %d, %s\n",
336 stop_signal,
337 stop_signal < NSIG
338 ? sys_siglist[stop_signal]
339 : "(undocumented)");
340 printf ("The inferior process no longer exists.\n");
341 fflush (stdout);
342 break;
343 }
344 else
345 {
346 stop_signal = WSTOPSIG (w);
347
348 /* First, distinguish signals caused by the debugger from signals
349 that have to do with the program's own actions.
350 Note that breakpoint insns may cause SIGTRAP or SIGILL
351 or SIGEMT, depending on the operating system version.
352 Here we detect when a SIGILL or SIGEMT is really a breakpoint
353 and change it to SIGTRAP. */
354
355 if (stop_signal == SIGTRAP
356 || (breakpoints_inserted &&
357 (stop_signal == SIGILL
358 || stop_signal == SIGEMT))
359 || stop_after_attach)
360 {
361 if (stop_signal == SIGTRAP && stop_after_trap)
362 {
363 stop_print_frame = 0;
364 break;
365 }
366 if (stop_after_attach)
367 break;
368 /* Don't even think about breakpoints
369 if still running the shell that will exec the program
370 or if just proceeded over a breakpoint. */
371 if (stop_signal == SIGTRAP && trap_expected)
372 stop_breakpoint = 0;
373 else
374 /* See if there is a breakpoint at the current PC. */
375 #if DECR_PC_AFTER_BREAK
376 /* Notice the case of stepping through a jump
377 that leads just after a breakpoint.
378 Don't confuse that with hitting the breakpoint.
379 What we check for is that 1) stepping is going on
380 and 2) the pc before the last insn does not match
381 the address of the breakpoint before the current pc. */
382 if (!(prev_pc != stop_pc - DECR_PC_AFTER_BREAK
383 && step_range_end && !step_resume_break_address))
384 #endif /* DECR_PC_AFTER_BREAK not zero */
385 {
386 select_frame (stop_frame, 0); /* For condition exprs. */
387 stop_breakpoint = breakpoint_stop_status (stop_pc, stop_frame);
388 /* Following in case break condition called a function. */
389 stop_print_frame = 1;
390 if (stop_breakpoint && DECR_PC_AFTER_BREAK)
391 {
392 stop_pc -= DECR_PC_AFTER_BREAK;
393 write_register (PC_REGNUM, stop_pc);
394 pc_changed = 0;
395 }
396 }
397 /* See if we stopped at the special breakpoint for
398 stepping over a subroutine call. */
399 if (stop_pc - DECR_PC_AFTER_BREAK == step_resume_break_address)
400 {
401 stop_step_resume_break = 1;
402 if (DECR_PC_AFTER_BREAK)
403 {
404 stop_pc -= DECR_PC_AFTER_BREAK;
405 write_register (PC_REGNUM, stop_pc);
406 pc_changed = 0;
407 }
408 }
409
410 if (stop_signal == SIGTRAP)
411 random_signal
412 = !(stop_breakpoint || trap_expected
413 || stop_step_resume_break
414 || (stop_sp INNER_THAN stop_pc && stop_pc INNER_THAN stop_frame)
415 || (step_range_end && !step_resume_break_address));
416 else
417 {
418 random_signal
419 = !(stop_breakpoint || stop_step_resume_break);
420 if (!random_signal)
421 stop_signal = SIGTRAP;
422 }
423 }
424 else
425 random_signal = 1;
426
427 /* For the program's own signals, act according to
428 the signal handling tables. */
429
430 if (random_signal
431 && !(running_in_shell && stop_signal == SIGSEGV))
432 {
433 /* Signal not for debugging purposes. */
434 int printed = 0;
435
436 if (stop_signal >= NSIG
437 || signal_print[stop_signal])
438 {
439 printed = 1;
440 terminal_ours_for_output ();
441 printf ("\nProgram received signal %d, %s\n",
442 stop_signal,
443 stop_signal < NSIG
444 ? sys_siglist[stop_signal]
445 : "(undocumented)");
446 fflush (stdout);
447 }
448 if (stop_signal >= NSIG
449 || signal_stop[stop_signal])
450 break;
451 /* If not going to stop, give terminal back
452 if we took it away. */
453 else if (printed)
454 terminal_inferior ();
455 }
456
457 /* Handle cases caused by hitting a breakpoint. */
458
459 if (!random_signal
460 && (stop_breakpoint || stop_step_resume_break))
461 {
462 /* Does a breakpoint want us to stop? */
463 if (stop_breakpoint && stop_breakpoint != -1)
464 {
465 /* 0x1000000 is set in stop_breakpoint as returned by
466 breakpoint_status_p to indicate a silent breakpoint. */
467 if (stop_breakpoint > 0 && stop_breakpoint & 0x1000000)
468 {
469 stop_breakpoint &= ~0x1000000;
470 stop_print_frame = 0;
471 }
472 break;
473 }
474 /* But if we have hit the step-resumption breakpoint,
475 remove it. It has done its job getting us here. */
476 if (stop_step_resume_break
477 && (step_frame == 0 || stop_frame == step_frame))
478 {
479 remove_step_breakpoint ();
480 step_resume_break_address = 0;
481 }
482 /* Otherwise, must remove breakpoints and single-step
483 to get us past the one we hit. */
484 else
485 {
486 remove_breakpoints ();
487 remove_step_breakpoint ();
488 breakpoints_inserted = 0;
489 another_trap = 1;
490 }
491
492 /* We come here if we hit a breakpoint but should not
493 stop for it. Possibly we also were stepping
494 and should stop for that. So fall through and
495 test for stepping. But, if not stepping,
496 do not stop. */
497 }
498
499 /* If this is the breakpoint at the end of a stack dummy,
500 just stop silently. */
501 if (stop_sp INNER_THAN stop_pc && stop_pc INNER_THAN stop_frame)
502 {
503 stop_print_frame = 0;
504 stop_stack_dummy = 1;
505 break;
506 }
507
508 if (step_resume_break_address)
509 /* Having a step-resume breakpoint overrides anything
510 else having to do with stepping commands until
511 that breakpoint is reached. */
512 ;
513 /* If stepping through a line, keep going if still within it. */
514 else if (!random_signal
515 && step_range_end
516 && stop_pc >= step_range_start
517 && stop_pc < step_range_end)
518 {
519 /* Don't step through the return from a function
520 unless that is the first instruction stepped through. */
521 if (ABOUT_TO_RETURN (stop_pc))
522 {
523 stop_step = 1;
524 break;
525 }
526 }
527
528 /* We stepped out of the stepping range. See if that was due
529 to a subroutine call that we should proceed to the end of. */
530 else if (!random_signal && step_range_end)
531 {
532 newfun = find_pc_function (stop_pc);
533 if (newfun)
534 {
535 newfun_pc = BLOCK_START (SYMBOL_BLOCK_VALUE (newfun))
536 + FUNCTION_START_OFFSET;
537 }
538 else
539 {
540 newmisc = find_pc_misc_function (stop_pc);
541 if (newmisc >= 0)
542 newfun_pc = misc_function_vector[newmisc].address
543 + FUNCTION_START_OFFSET;
544 else newfun_pc = 0;
545 }
546 if (stop_pc == newfun_pc
547 && (step_over_calls > 0 || (step_over_calls && newfun == 0)))
548 {
549 /* A subroutine call has happened. */
550 /* Set a special breakpoint after the return */
551 step_resume_break_address = SAVED_PC_AFTER_CALL (stop_frame);
552 step_resume_break_duplicate
553 = breakpoint_here_p (step_resume_break_address);
554 if (breakpoints_inserted)
555 insert_step_breakpoint ();
556 }
557 /* Subroutine call with source code we should not step over.
558 Do step to the first line of code in it. */
559 else if (stop_pc == newfun_pc && step_over_calls)
560 {
561 SKIP_PROLOGUE (newfun_pc);
562 sal = find_pc_line (newfun_pc, 0);
563 /* Use the step_resume_break to step until
564 the end of the prologue, even if that involves jumps
565 (as it seems to on the vax under 4.2). */
566 /* If the prologue ends in the middle of a source line,
567 continue to the end of that source line.
568 Otherwise, just go to end of prologue. */
569 if (sal.end && sal.pc != newfun_pc)
570 step_resume_break_address = sal.end;
571 else
572 step_resume_break_address = newfun_pc;
573
574 step_resume_break_duplicate
575 = breakpoint_here_p (step_resume_break_address);
576 if (breakpoints_inserted)
577 insert_step_breakpoint ();
578 /* Do not specify what the fp should be when we stop
579 since on some machines the prologue
580 is where the new fp value is established. */
581 step_frame = 0;
582 /* And make sure stepping stops right away then. */
583 step_range_end = step_range_start;
584 }
585 /* No subroutince call; stop now. */
586 else
587 {
588 stop_step = 1;
589 break;
590 }
591 }
592 }
593
594 /* If we did not do break;, it means we should keep
595 running the inferior and not return to debugger. */
596
597 /* If trap_expected is 2, it means continue once more
598 and insert breakpoints at the next trap.
599 If trap_expected is 1 and the signal was SIGSEGV, it means
600 the shell is doing some memory allocation--just resume it
601 with SIGSEGV.
602 Otherwise insert breakpoints now, and possibly single step. */
603
604 if (trap_expected > 1)
605 {
606 trap_expected--;
607 running_in_shell = 1;
608 resume (0, 0);
609 }
610 else if (running_in_shell && stop_signal == SIGSEGV)
611 {
612 resume (0, SIGSEGV);
613 }
614 else
615 {
616 /* Here, we are not awaiting another exec to get
617 the program we really want to debug.
618 Insert breakpoints now, unless we are trying
619 to one-proceed past a breakpoint. */
620 running_in_shell = 0;
621 if (!breakpoints_inserted && !another_trap)
622 {
623 insert_step_breakpoint ();
624 breakpoints_failed = insert_breakpoints ();
625 if (breakpoints_failed)
626 break;
627 breakpoints_inserted = 1;
628 }
629
630 trap_expected = another_trap;
631
632 if (stop_signal == SIGTRAP)
633 stop_signal = 0;
634
635 resume ((step_range_end && !step_resume_break_address)
636 || trap_expected,
637 stop_signal);
638 }
639 }
640 }
641 \f
642 /* Here to return control to GDB when the inferior stops for real.
643 Print appropriate messages, remove breakpoints, give terminal our modes.
644
645 RUNNING_IN_SHELL nonzero means the shell got a signal before
646 exec'ing the program we wanted to run.
647 STOP_PRINT_FRAME nonzero means print the executing frame
648 (pc, function, args, file, line number and line text).
649 BREAKPOINTS_FAILED nonzero means stop was due to error
650 attempting to insert breakpoints. */
651
652 static void
653 normal_stop ()
654 {
655 if (breakpoints_failed)
656 {
657 terminal_ours_for_output ();
658 print_sys_errmsg ("ptrace", breakpoints_failed);
659 printf ("Stopped; cannot insert breakpoints.\n\
660 The same program may be running in another process.\n");
661 }
662
663 if (inferior_pid)
664 remove_step_breakpoint ();
665
666 if (inferior_pid && breakpoints_inserted)
667 if (remove_breakpoints ())
668 {
669 terminal_ours_for_output ();
670 printf ("Cannot remove breakpoints because program is no longer writable.\n\
671 It must be running in another process.\n\
672 Further execution is probably impossible.\n");
673 }
674
675 breakpoints_inserted = 0;
676
677 /* Delete the breakpoint we stopped at, if it wants to be deleted.
678 Delete any breakpoint that is to be deleted at the next stop. */
679
680 breakpoint_auto_delete (stop_breakpoint);
681
682 if (step_multi && stop_step)
683 return;
684
685 terminal_ours ();
686
687 if (running_in_shell)
688 {
689 if (stop_signal == SIGSEGV)
690 printf ("\
691 You have just encountered a bug in \"sh\". GDB starts your program\n\
692 by running \"sh\" with a command to exec your program.\n\
693 This is so that \"sh\" will process wildcards and I/O redirection.\n\
694 This time, \"sh\" crashed.\n\
695 \n\
696 One known bug in \"sh\" bites when the environment takes up a lot of space.\n\
697 Try \"info env\" to see the environment; then use \"unset-env\" to kill\n\
698 some variables whose values are large; then do \"run\" again.\n\
699 \n\
700 If that works, you might want to put those \"unset-env\" commands\n\
701 into a \".gdbinit\" file in this directory so they will happen every time.\n");
702 /* Don't confuse user with his program's symbols on sh's data. */
703 stop_print_frame = 0;
704 }
705
706 if (inferior_pid == 0)
707 return;
708
709 /* Select innermost stack frame except on return from a stack dummy routine,
710 or if the program has exited. */
711 if (!stop_stack_dummy)
712 {
713 select_frame (stop_frame, 0);
714
715 if (stop_print_frame)
716 {
717 if (stop_breakpoint > 0)
718 printf ("\nBpt %d, ", stop_breakpoint);
719 print_sel_frame (stop_step
720 && step_frame == stop_frame
721 && step_start_function == find_pc_function (stop_pc));
722 /* Display the auto-display expressions. */
723 do_displays ();
724 }
725 }
726
727 /* Save the function value return registers
728 We might be about to restore their previous contents. */
729 read_register_bytes (0, stop_registers, REGISTER_BYTES);
730
731 if (stop_stack_dummy)
732 {
733 /* Pop the empty frame that contains the stack dummy. */
734 POP_FRAME;
735 select_frame (read_register (FP_REGNUM), 0);
736 }
737 }
738 \f
739 static void
740 insert_step_breakpoint ()
741 {
742 if (step_resume_break_address && !step_resume_break_duplicate)
743 {
744 read_memory (step_resume_break_address,
745 step_resume_break_shadow, sizeof break_insn);
746 write_memory (step_resume_break_address,
747 break_insn, sizeof break_insn);
748 }
749 }
750
751 static void
752 remove_step_breakpoint ()
753 {
754 if (step_resume_break_address && !step_resume_break_duplicate)
755 write_memory (step_resume_break_address, step_resume_break_shadow,
756 sizeof break_insn);
757 }
758 \f
759 /* Specify how various signals in the inferior should be handled. */
760
761 static void
762 handle_command (args, from_tty)
763 char *args;
764 int from_tty;
765 {
766 register char *p = args;
767 int signum;
768 register int digits, wordlen;
769
770 if (!args)
771 error_no_arg ("signal to handle");
772
773 while (*p)
774 {
775 /* Find the end of the next word in the args. */
776 for (wordlen = 0; p[wordlen] && p[wordlen] != ' ' && p[wordlen] != '\t';
777 wordlen++);
778 for (digits = 0; p[digits] >= '0' && p[digits] <= '9'; digits++);
779
780 /* If it is all digits, it is signal number to operate on. */
781 if (digits == wordlen)
782 {
783 signum = atoi (p);
784 if (signum == SIGTRAP || signum == SIGINT)
785 {
786 if (!query ("Signal %d is used by the debugger.\nAre you sure you want to change it? ", signum))
787 error ("Not confirmed.");
788 }
789 }
790 else if (signum == 0)
791 error ("First argument is not a signal number.");
792
793 /* Else, if already got a signal number, look for flag words
794 saying what to do for it. */
795 else if (!strncmp (p, "stop", wordlen))
796 {
797 signal_stop[signum] = 1;
798 signal_print[signum] = 1;
799 }
800 else if (wordlen >= 2 && !strncmp (p, "print", wordlen))
801 signal_print[signum] = 1;
802 else if (wordlen >= 2 && !strncmp (p, "pass", wordlen))
803 signal_program[signum] = 1;
804 else if (!strncmp (p, "ignore", wordlen))
805 signal_program[signum] = 0;
806 else if (wordlen >= 3 && !strncmp (p, "nostop", wordlen))
807 signal_stop[signum] = 0;
808 else if (wordlen >= 4 && !strncmp (p, "noprint", wordlen))
809 {
810 signal_print[signum] = 0;
811 signal_stop[signum] = 0;
812 }
813 else if (wordlen >= 4 && !strncmp (p, "nopass", wordlen))
814 signal_program[signum] = 0;
815 else if (wordlen >= 3 && !strncmp (p, "noignore", wordlen))
816 signal_program[signum] = 1;
817 /* Not a number and not a recognized flag word => complain. */
818 else
819 {
820 p[wordlen] = 0;
821 error ("Unrecognized flag word: \"%s\".", p);
822 }
823
824 /* Find start of next word. */
825 p += wordlen;
826 while (*p == ' ' || *p == '\t') p++;
827 }
828
829 if (from_tty)
830 {
831 /* Show the results. */
832 printf ("Number\tStop\tPrint\tPass to program\tDescription\n");
833 printf ("%d\t", signum);
834 printf ("%s\t", signal_stop[signum] ? "Yes" : "No");
835 printf ("%s\t", signal_print[signum] ? "Yes" : "No");
836 printf ("%s\t\t", signal_program[signum] ? "Yes" : "No");
837 printf ("%s\n", sys_siglist[signum]);
838 }
839 }
840
841 /* Print current contents of the tables set by the handle command. */
842
843 static void
844 signals_info (signum_exp)
845 char *signum_exp;
846 {
847 register int i;
848 printf ("Number\tStop\tPrint\tPass to program\tDescription\n");
849
850 if (signum_exp)
851 {
852 i = parse_and_eval_address (signum_exp);
853 printf ("%d\t", i);
854 printf ("%s\t", signal_stop[i] ? "Yes" : "No");
855 printf ("%s\t", signal_print[i] ? "Yes" : "No");
856 printf ("%s\t\t", signal_program[i] ? "Yes" : "No");
857 printf ("%s\n", sys_siglist[i]);
858 return;
859 }
860
861 printf ("\n");
862 for (i = 0; i < NSIG; i++)
863 {
864 QUIT;
865 if (i > 0 && i % 16 == 0)
866 {
867 printf ("[Type Return to see more]");
868 fflush (stdout);
869 read_line ();
870 }
871 printf ("%d\t", i);
872 printf ("%s\t", signal_stop[i] ? "Yes" : "No");
873 printf ("%s\t", signal_print[i] ? "Yes" : "No");
874 printf ("%s\t\t", signal_program[i] ? "Yes" : "No");
875 printf ("%s\n", sys_siglist[i]);
876 }
877
878 printf ("\nUse the \"handle\" command to change these tables.\n");
879 }
880 \f
881 static
882 initialize ()
883 {
884 register int i;
885
886 add_info ("signals", signals_info,
887 "What debugger does when program gets various signals.\n\
888 Specify a signal number as argument to print info on that signal only.");
889
890 add_com ("handle", class_run, handle_command,
891 "Specify how to handle a signal.\n\
892 Args are signal number followed by flags.\n\
893 Flags allowed are \"stop\", \"print\", \"pass\",\n\
894 \"nostop\", \"noprint\" or \"nopass\".\n\
895 Print means print a message if this signal happens.\n\
896 Stop means reenter debugger if this signal happens (implies print).\n\
897 Pass means let program see this signal; otherwise program doesn't know.\n\
898 Pass and Stop may be combined.");
899
900 for (i = 0; i < NSIG; i++)
901 {
902 signal_stop[i] = 1;
903 signal_print[i] = 1;
904 signal_program[i] = 1;
905 }
906
907 /* Signals caused by debugger's own actions
908 should not be given to the program afterwards. */
909 signal_program[SIGTRAP] = 0;
910 signal_program[SIGINT] = 0;
911
912 /* Signals that are not errors should not normally enter the debugger. */
913 #ifdef SIGALRM
914 signal_stop[SIGALRM] = 0;
915 signal_print[SIGALRM] = 0;
916 #endif /* SIGALRM */
917 #ifdef SIGVTALRM
918 signal_stop[SIGVTALRM] = 0;
919 signal_print[SIGVTALRM] = 0;
920 #endif /* SIGVTALRM */
921 #ifdef SIGPROF
922 signal_stop[SIGPROF] = 0;
923 signal_print[SIGPROF] = 0;
924 #endif /* SIGPROF */
925 #ifdef SIGCHLD
926 signal_stop[SIGCHLD] = 0;
927 signal_print[SIGCHLD] = 0;
928 #endif /* SIGCHLD */
929 #ifdef SIGCLD
930 signal_stop[SIGCLD] = 0;
931 signal_print[SIGCLD] = 0;
932 #endif /* SIGCLD */
933 #ifdef SIGIO
934 signal_stop[SIGIO] = 0;
935 signal_print[SIGIO] = 0;
936 #endif /* SIGIO */
937 #ifdef SIGURG
938 signal_stop[SIGURG] = 0;
939 signal_print[SIGURG] = 0;
940 #endif /* SIGURG */
941 }
942
943 END_FILE
This page took 0.052061 seconds and 4 git commands to generate.