📄 breakpoint.c
字号:
char *arg; int from_tty;{ break_command_1 (arg, 0, from_tty);}static voidtbreak_command (arg, from_tty) char *arg; int from_tty;{ break_command_1 (arg, 1, from_tty);}/* ARGSUSED */static voidwatch_command (arg, from_tty) char *arg; int from_tty;{ struct breakpoint *b; struct symtab_and_line sal; struct expression *exp; struct block *exp_valid_block; struct value *val; sal.pc = 0; sal.symtab = NULL; sal.line = 0; /* Parse arguments. */ innermost_block = NULL; exp = parse_expression (arg); exp_valid_block = innermost_block; val = evaluate_expression (exp); release_value (val); /* Now set up the breakpoint. */ b = set_raw_breakpoint (sal); set_breakpoint_count (breakpoint_count + 1); b->number = breakpoint_count; b->type = bp_watchpoint; b->disposition = donttouch; b->exp = exp; b->exp_valid_block = exp_valid_block; b->val = val; b->cond = 0; b->cond_string = NULL; mention (b);}/* * Helper routine for the until_command routine in infcmd.c. Here * because it uses the mechanisms of breakpoints. *//* ARGSUSED */voiduntil_break_command (arg, from_tty) char *arg; int from_tty;{ struct symtabs_and_lines sals; struct symtab_and_line sal; FRAME prev_frame = get_prev_frame (selected_frame); struct breakpoint *breakpoint; struct cleanup *old_chain; clear_proceed_status (); /* Set a breakpoint where the user wants it and at return from this function */ if (default_breakpoint_valid) sals = decode_line_1 (&arg, 1, default_breakpoint_symtab, default_breakpoint_line); else sals = decode_line_1 (&arg, 1, (struct symtab *)NULL, 0); if (sals.nelts != 1) error ("Couldn't get information on specified line."); sal = sals.sals[0]; free ((PTR)sals.sals); /* malloc'd, so freed */ if (*arg) error ("Junk at end of arguments."); resolve_sal_pc (&sal); breakpoint = set_momentary_breakpoint (sal, selected_frame, bp_until); old_chain = make_cleanup(delete_breakpoint, breakpoint); /* Keep within the current frame */ if (prev_frame) { struct frame_info *fi; fi = get_frame_info (prev_frame); sal = find_pc_line (fi->pc, 0); sal.pc = fi->pc; breakpoint = set_momentary_breakpoint (sal, prev_frame, bp_until); make_cleanup(delete_breakpoint, breakpoint); } proceed (-1, -1, 0); do_cleanups(old_chain);}#if 0/* These aren't used; I don't konw what they were for. *//* Set a breakpoint at the catch clause for NAME. */static intcatch_breakpoint (name) char *name;{}static intdisable_catch_breakpoint (){}static intdelete_catch_breakpoint (){}static intenable_catch_breakpoint (){}#endif /* 0 */struct sal_chain{ struct sal_chain *next; struct symtab_and_line sal;};#if 0/* This isn't used; I don't know what it was for. *//* For each catch clause identified in ARGS, run FUNCTION with that clause as an argument. */static struct symtabs_and_linesmap_catch_names (args, function) char *args; int (*function)();{ register char *p = args; register char *p1; struct symtabs_and_lines sals;#if 0 struct sal_chain *sal_chain = 0;#endif if (p == 0) error_no_arg ("one or more catch names"); sals.nelts = 0; sals.sals = NULL; while (*p) { p1 = p; /* Don't swallow conditional part. */ if (p1[0] == 'i' && p1[1] == 'f' && (p1[2] == ' ' || p1[2] == '\t')) break; if (isalpha (*p1)) { p1++; while (isalnum (*p1) || *p1 == '_' || *p1 == '$') p1++; } if (*p1 && *p1 != ' ' && *p1 != '\t') error ("Arguments must be catch names."); *p1 = 0;#if 0 if (function (p)) { struct sal_chain *next = (struct sal_chain *)alloca (sizeof (struct sal_chain)); next->next = sal_chain; next->sal = get_catch_sal (p); sal_chain = next; goto win; }#endif printf ("No catch clause for exception %s.\n", p);#if 0 win:#endif p = p1; while (*p == ' ' || *p == '\t') p++; }}#endif /* 0 *//* This shares a lot of code with `print_frame_label_vars' from stack.c. */static struct symtabs_and_linesget_catch_sals (this_level_only) int this_level_only;{ register struct blockvector *bl; register struct block *block; int index, have_default = 0; struct frame_info *fi; CORE_ADDR pc; struct symtabs_and_lines sals; struct sal_chain *sal_chain = 0; char *blocks_searched; /* Not sure whether an error message is always the correct response, but it's better than a core dump. */ if (selected_frame == NULL) error ("No selected frame."); block = get_frame_block (selected_frame); fi = get_frame_info (selected_frame); pc = fi->pc; sals.nelts = 0; sals.sals = NULL; if (block == 0) error ("No symbol table info available.\n"); bl = blockvector_for_pc (BLOCK_END (block) - 4, &index); blocks_searched = (char *) alloca (BLOCKVECTOR_NBLOCKS (bl) * sizeof (char)); memset (blocks_searched, 0, BLOCKVECTOR_NBLOCKS (bl) * sizeof (char)); while (block != 0) { CORE_ADDR end = BLOCK_END (block) - 4; int last_index; if (bl != blockvector_for_pc (end, &index)) error ("blockvector blotch"); if (BLOCKVECTOR_BLOCK (bl, index) != block) error ("blockvector botch"); last_index = BLOCKVECTOR_NBLOCKS (bl); index += 1; /* Don't print out blocks that have gone by. */ while (index < last_index && BLOCK_END (BLOCKVECTOR_BLOCK (bl, index)) < pc) index++; while (index < last_index && BLOCK_END (BLOCKVECTOR_BLOCK (bl, index)) < end) { if (blocks_searched[index] == 0) { struct block *b = BLOCKVECTOR_BLOCK (bl, index); int nsyms; register int i; register struct symbol *sym; nsyms = BLOCK_NSYMS (b); for (i = 0; i < nsyms; i++) { sym = BLOCK_SYM (b, i); if (! strcmp (SYMBOL_NAME (sym), "default")) { if (have_default) continue; have_default = 1; } if (SYMBOL_CLASS (sym) == LOC_LABEL) { struct sal_chain *next = (struct sal_chain *) alloca (sizeof (struct sal_chain)); next->next = sal_chain; next->sal = find_pc_line (SYMBOL_VALUE_ADDRESS (sym), 0); sal_chain = next; } } blocks_searched[index] = 1; } index++; } if (have_default) break; if (sal_chain && this_level_only) break; /* After handling the function's top-level block, stop. Don't continue to its superblock, the block of per-file symbols. */ if (BLOCK_FUNCTION (block)) break; block = BLOCK_SUPERBLOCK (block); } if (sal_chain) { struct sal_chain *tmp_chain; /* Count the number of entries. */ for (index = 0, tmp_chain = sal_chain; tmp_chain; tmp_chain = tmp_chain->next) index++; sals.nelts = index; sals.sals = (struct symtab_and_line *) xmalloc (index * sizeof (struct symtab_and_line)); for (index = 0; sal_chain; sal_chain = sal_chain->next, index++) sals.sals[index] = sal_chain->sal; } return sals;}/* Commands to deal with catching exceptions. */static voidcatch_command_1 (arg, tempflag, from_tty) char *arg; int tempflag; int from_tty;{ /* First, translate ARG into something we can deal with in terms of breakpoints. */ struct symtabs_and_lines sals; struct symtab_and_line sal; register struct expression *cond = 0; register struct breakpoint *b; char *save_arg; int i; sal.line = sal.pc = sal.end = 0; sal.symtab = 0; /* If no arg given, or if first arg is 'if ', all active catch clauses are breakpointed. */ if (!arg || (arg[0] == 'i' && arg[1] == 'f' && (arg[2] == ' ' || arg[2] == '\t'))) { /* Grab all active catch clauses. */ sals = get_catch_sals (0); } else { /* Grab selected catch clauses. */ error ("catch NAME not implemeneted");#if 0 /* This isn't used; I don't know what it was for. */ sals = map_catch_names (arg, catch_breakpoint);#endif } if (! sals.nelts) return; save_arg = arg; for (i = 0; i < sals.nelts; i++) { resolve_sal_pc (&sals.sals[i]); while (arg && *arg) { if (arg[0] == 'i' && arg[1] == 'f' && (arg[2] == ' ' || arg[2] == '\t')) cond = parse_exp_1 ((arg += 2, &arg), block_for_pc (sals.sals[i].pc), 0); else error ("Junk at end of arguments."); } arg = save_arg; } for (i = 0; i < sals.nelts; i++) { sal = sals.sals[i]; if (from_tty) describe_other_breakpoints (sal.pc); b = set_raw_breakpoint (sal); set_breakpoint_count (breakpoint_count + 1); b->number = breakpoint_count; b->type = bp_breakpoint; b->cond = cond; b->enable = enabled; b->disposition = tempflag ? delete : donttouch; printf ("Breakpoint %d at %s", b->number, local_hex_string(b->address)); if (b->symtab) printf (": file %s, line %d.", b->symtab->filename, b->line_number); printf ("\n"); } if (sals.nelts > 1) { printf ("Multiple breakpoints were set.\n"); printf ("Use the \"delete\" command to delete unwanted breakpoints.\n"); } free ((PTR)sals.sals);}#if 0/* These aren't used; I don't know what they were for. *//* Disable breakpoints on all catch clauses described in ARGS. */static voiddisable_catch (args) char *args;{ /* Map the disable command to catch clauses described in ARGS. */}/* Enable breakpoints on all catch clauses described in ARGS. */static voidenable_catch (args) char *args;{ /* Map the disable command to catch clauses described in ARGS. */}/* Delete breakpoints on all catch clauses in the active scope. */static voiddelete_catch (args) char *args;{ /* Map the delete command to catch clauses described in ARGS. */}#endif /* 0 */static voidcatch_command (arg, from_tty) char *arg; int from_tty;{ catch_command_1 (arg, 0, from_tty);}static voidclear_command (arg, from_tty) char *arg; int from_tty;{ register struct breakpoint *b, *b1; struct symtabs_and_lines sals; struct symtab_and_line sal; register struct breakpoint *found; int i; if (arg) { sals = decode_line_spec (arg, 1); } else { sals.sals = (struct symtab_and_line *) xmalloc (sizeof (struct symtab_and_line)); sal.line = default_breakpoint_line; sal.symtab = default_breakpoint_symtab; sal.pc = 0; if (sal.symtab == 0) error ("No source file specified."); sals.sals[0] = sal; sals.nelts = 1; } for (i = 0; i < sals.nelts; i++) { /* If exact pc given, clear bpts at that pc. But if sal.pc is zero, clear all bpts on specified line. */ sal = sals.sals[i]; found = (struct breakpoint *) 0; while (breakpoint_chain && (sal.pc ? breakpoint_chain->address == sal.pc : (breakpoint_chain->symtab == sal.symtab && breakpoint_chain->line_number == sal.line))) { b1 = breakpoint_chain; breakpoint_chain = b1->next; b1->next = found; found = b1; } ALL_BREAKPOINTS (b) while (b->next && b->next->type != bp_watchpoint && (sal.pc ? b->next->address == sal.pc : (b->next->symtab == sal.symtab && b->next->line_number == sal.line))) { b1 = b->next; b->next = b1->next; b1->next = found; found = b1; } if (found == 0) { if (arg) error ("No breakpoint at %s.", arg); else error ("No breakpoint at this line."); } if (found->next) from_tty = 1; /* Always report if deleted more than one */ if (from_tty) printf ("Deleted breakpoint%s ", found->next ? "s" : ""); while (found) { if (from_tty) printf ("%d ", found->number); b1 = found->next; delete_breakpoint (found); found = b1; } if (from_tty) putchar ('\n'); } free ((PTR)sals.sals);}/* Delete breakpoint in BS if they are `delete' breakpoints. This is called after any breakpoint is hit, or after errors. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -