📄 infrun.c
字号:
target_remove_breakpoint (step_resume_break_address, step_resume_break_shadow);}int signal_stop_state (signo) int signo;{ return ((signo >= 0 && signo < NSIG) ? signal_stop[signo] : 0);}int signal_print_state (signo) int signo;{ return ((signo >= 0 && signo < NSIG) ? signal_print[signo] : 0);}int signal_pass_state (signo) int signo;{ return ((signo >= 0 && signo < NSIG) ? signal_program[signo] : 0);}static voidsig_print_header (){ printf_filtered ("Signal\t\tStop\tPrint\tPass to program\tDescription\n");}static voidsig_print_info (number) int number;{ char *name; if ((name = strsigno (number)) == NULL) printf_filtered ("%d\t\t", number); else printf_filtered ("%s (%d)\t", name, number); printf_filtered ("%s\t", signal_stop[number] ? "Yes" : "No"); printf_filtered ("%s\t", signal_print[number] ? "Yes" : "No"); printf_filtered ("%s\t\t", signal_program[number] ? "Yes" : "No"); printf_filtered ("%s\n", safe_strsignal (number));}/* Specify how various signals in the inferior should be handled. */static voidhandle_command (args, from_tty) char *args; int from_tty;{ char **argv; int digits, wordlen; int sigfirst, signum, siglast; int allsigs; int nsigs; unsigned char *sigs; struct cleanup *old_chain; if (args == NULL) { error_no_arg ("signal to handle"); } /* Allocate and zero an array of flags for which signals to handle. */ nsigs = signo_max () + 1; sigs = (unsigned char *) alloca (nsigs); memset (sigs, 0, nsigs); /* Break the command line up into args. */ argv = buildargv (args); if (argv == NULL) { nomem (0); } old_chain = make_cleanup (freeargv, (char *) argv); /* Walk through the args, looking for signal numbers, signal names, and actions. Signal numbers and signal names may be interspersed with actions, with the actions being performed for all signals cumulatively specified. Signal ranges can be specified as <LOW>-<HIGH>. */ while (*argv != NULL) { wordlen = strlen (*argv); for (digits = 0; isdigit ((*argv)[digits]); digits++) {;} allsigs = 0; sigfirst = siglast = -1; if (wordlen >= 1 && !strncmp (*argv, "all", wordlen)) { /* Apply action to all signals except those used by the debugger. Silently skip those. */ allsigs = 1; sigfirst = 0; siglast = nsigs - 1; } else if (wordlen >= 1 && !strncmp (*argv, "stop", wordlen)) { SET_SIGS (nsigs, sigs, signal_stop); SET_SIGS (nsigs, sigs, signal_print); } else if (wordlen >= 1 && !strncmp (*argv, "ignore", wordlen)) { UNSET_SIGS (nsigs, sigs, signal_program); } else if (wordlen >= 2 && !strncmp (*argv, "print", wordlen)) { SET_SIGS (nsigs, sigs, signal_print); } else if (wordlen >= 2 && !strncmp (*argv, "pass", wordlen)) { SET_SIGS (nsigs, sigs, signal_program); } else if (wordlen >= 3 && !strncmp (*argv, "nostop", wordlen)) { UNSET_SIGS (nsigs, sigs, signal_stop); } else if (wordlen >= 3 && !strncmp (*argv, "noignore", wordlen)) { SET_SIGS (nsigs, sigs, signal_program); } else if (wordlen >= 4 && !strncmp (*argv, "noprint", wordlen)) { UNSET_SIGS (nsigs, sigs, signal_print); UNSET_SIGS (nsigs, sigs, signal_stop); } else if (wordlen >= 4 && !strncmp (*argv, "nopass", wordlen)) { UNSET_SIGS (nsigs, sigs, signal_program); } else if (digits > 0) { sigfirst = siglast = atoi (*argv); if ((*argv)[digits] == '-') { siglast = atoi ((*argv) + digits + 1); } if (sigfirst > siglast) { /* Bet he didn't figure we'd think of this case... */ signum = sigfirst; sigfirst = siglast; siglast = signum; } if (sigfirst < 0 || sigfirst >= nsigs) { error ("Signal %d not in range 0-%d", sigfirst, nsigs - 1); } if (siglast < 0 || siglast >= nsigs) { error ("Signal %d not in range 0-%d", siglast, nsigs - 1); } } else if ((signum = strtosigno (*argv)) != 0) { sigfirst = siglast = signum; } else { /* Not a number and not a recognized flag word => complain. */ error ("Unrecognized or ambiguous flag word: \"%s\".", *argv); } /* If any signal numbers or symbol names were found, set flags for which signals to apply actions to. */ for (signum = sigfirst; signum >= 0 && signum <= siglast; signum++) { switch (signum) { case SIGTRAP: case SIGINT: if (!allsigs && !sigs[signum]) { if (query ("%s is used by the debugger.\nAre you sure you want to change it? ", strsigno (signum))) { sigs[signum] = 1; } else { printf ("Not confirmed, unchanged.\n"); fflush (stdout); } } break; default: sigs[signum] = 1; break; } } argv++; } target_notice_signals(); if (from_tty) { /* Show the results. */ sig_print_header (); for (signum = 0; signum < nsigs; signum++) { if (sigs[signum]) { sig_print_info (signum); } } } do_cleanups (old_chain);}/* Print current contents of the tables set by the handle command. */static voidsignals_info (signum_exp, from_tty) char *signum_exp; int from_tty;{ register int i; sig_print_header (); if (signum_exp) { /* First see if this is a symbol name. */ i = strtosigno (signum_exp); if (i == 0) { /* Nope, maybe it's an address which evaluates to a signal number. */ i = parse_and_eval_address (signum_exp); if (i >= NSIG || i < 0) error ("Signal number out of bounds."); } sig_print_info (i); return; } printf_filtered ("\n"); for (i = 0; i < NSIG; i++) { QUIT; sig_print_info (i); } printf_filtered ("\nUse the \"handle\" command to change these tables.\n");}/* Save all of the information associated with the inferior<==>gdb connection. INF_STATUS is a pointer to a "struct inferior_status" (defined in inferior.h). */voidsave_inferior_status (inf_status, restore_stack_info) struct inferior_status *inf_status; int restore_stack_info;{ inf_status->pc_changed = pc_changed; inf_status->stop_signal = stop_signal; inf_status->stop_pc = stop_pc; inf_status->stop_frame_address = stop_frame_address; inf_status->stop_step = stop_step; inf_status->stop_stack_dummy = stop_stack_dummy; inf_status->stopped_by_random_signal = stopped_by_random_signal; inf_status->trap_expected = trap_expected; inf_status->step_range_start = step_range_start; inf_status->step_range_end = step_range_end; inf_status->step_frame_address = step_frame_address; inf_status->step_over_calls = step_over_calls; inf_status->step_resume_break_address = step_resume_break_address; inf_status->stop_after_trap = stop_after_trap; inf_status->stop_soon_quietly = stop_soon_quietly; /* Save original bpstat chain here; replace it with copy of chain. If caller's caller is walking the chain, they'll be happier if we hand them back the original chain when restore_i_s is called. */ inf_status->stop_bpstat = stop_bpstat; stop_bpstat = bpstat_copy (stop_bpstat); inf_status->breakpoint_proceeded = breakpoint_proceeded; inf_status->restore_stack_info = restore_stack_info; read_register_bytes(0, inf_status->register_context, REGISTER_BYTES); record_selected_frame (&(inf_status->selected_frame_address), &(inf_status->selected_level)); return;}voidrestore_inferior_status (inf_status) struct inferior_status *inf_status;{ FRAME fid; int level = inf_status->selected_level; pc_changed = inf_status->pc_changed; stop_signal = inf_status->stop_signal; stop_pc = inf_status->stop_pc; stop_frame_address = inf_status->stop_frame_address; stop_step = inf_status->stop_step; stop_stack_dummy = inf_status->stop_stack_dummy; stopped_by_random_signal = inf_status->stopped_by_random_signal; trap_expected = inf_status->trap_expected; step_range_start = inf_status->step_range_start; step_range_end = inf_status->step_range_end; step_frame_address = inf_status->step_frame_address; step_over_calls = inf_status->step_over_calls; step_resume_break_address = inf_status->step_resume_break_address; stop_after_trap = inf_status->stop_after_trap; stop_soon_quietly = inf_status->stop_soon_quietly; bpstat_clear (&stop_bpstat); stop_bpstat = inf_status->stop_bpstat; breakpoint_proceeded = inf_status->breakpoint_proceeded; write_register_bytes(0, inf_status->register_context, REGISTER_BYTES); /* The inferior can be gone if the user types "print exit(0)" (and perhaps other times). */ if (target_has_stack && inf_status->restore_stack_info) { fid = find_relative_frame (get_current_frame (), &level); /* If inf_status->selected_frame_address is NULL, there was no previously selected frame. */ if (fid == 0 || FRAME_FP (fid) != inf_status->selected_frame_address || level != 0) {#if 1 /* I'm not sure this error message is a good idea. I have only seen it occur after "Can't continue previously requested operation" (we get called from do_cleanups), in which case it just adds insult to injury (one confusing error message after another. Besides which, does the user really care if we can't restore the previously selected frame? */ fprintf (stderr, "Unable to restore previously selected frame.\n");#endif select_frame (get_current_frame (), 0); return; } select_frame (fid, inf_status->selected_level); }}void_initialize_infrun (){ register int i; register int numsigs; add_info ("signals", signals_info, "What debugger does when program gets various signals.\n\Specify a signal number as argument to print info on that signal only."); add_info_alias ("handle", "signals", 0); add_com ("handle", class_run, handle_command, "Specify how to handle a signal.\n\Args are signal numbers and actions to apply to those signals.\n\Signal numbers may be numeric (ex. 11) or symbolic (ex. SIGSEGV).\n\Numeric ranges may be specified with the form LOW-HIGH (ex. 14-21).\n\The special arg \"all\" is recognized to mean all signals except those\n\used by the debugger, typically SIGTRAP and SIGINT.\n\Recognized actions include \"stop\", \"nostop\", \"print\", \"noprint\",\n\\"pass\", \"nopass\", \"ignore\", or \"noignore\".\n\Stop means reenter debugger if this signal happens (implies print).\n\Print means print a message if this signal happens.\n\Pass means let program see this signal; otherwise program doesn't know.\n\Ignore is a synonym for nopass and noignore is a synonym for pass.\n\Pass and Stop may be combined."); stop_command = add_cmd ("stop", class_obscure, not_just_help_class_command, "There is no `stop' command, but you can set a hook on `stop'.\n\This allows you to set a list of commands to be run each time execution\n\of the inferior program stops.", &cmdlist); numsigs = signo_max () + 1; signal_stop = (unsigned char *) xmalloc (sizeof (signal_stop[0]) * numsigs); signal_print = (unsigned char *) xmalloc (sizeof (signal_print[0]) * numsigs); signal_program = (unsigned char *) xmalloc (sizeof (signal_program[0]) * numsigs); for (i = 0; i < numsigs; i++) { signal_stop[i] = 1; signal_print[i] = 1; signal_program[i] = 1; } /* Signals caused by debugger's own actions should not be given to the program afterwards. */ signal_program[SIGTRAP] = 0; signal_program[SIGINT] = 0; /* Signals that are not errors should not normally enter the debugger. */#ifdef SIGALRM signal_stop[SIGALRM] = 0; signal_print[SIGALRM] = 0;#endif /* SIGALRM */#ifdef SIGVTALRM signal_stop[SIGVTALRM] = 0; signal_print[SIGVTALRM] = 0;#endif /* SIGVTALRM */#ifdef SIGPROF signal_stop[SIGPROF] = 0; signal_print[SIGPROF] = 0;#endif /* SIGPROF */#ifdef SIGCHLD signal_stop[SIGCHLD] = 0; signal_print[SIGCHLD] = 0;#endif /* SIGCHLD */#ifdef SIGCLD signal_stop[SIGCLD] = 0; signal_print[SIGCLD] = 0;#endif /* SIGCLD */#ifdef SIGIO signal_stop[SIGIO] = 0; signal_print[SIGIO] = 0;#endif /* SIGIO */#ifdef SIGURG signal_stop[SIGURG] = 0; signal_print[SIGURG] = 0;#endif /* SIGURG */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -