b->inserted = 0;
#ifdef BREAKPOINT_DEBUG
printf ("Removed breakpoint at %s",
- local_hex_string(b->address));
+ local_hex_string((unsigned long) b->address));
printf (", shadow %s",
- local_hex_string(b->shadow_contents[0]));
+ local_hex_string((unsigned long) b->shadow_contents[0]));
printf (", %s.\n",
- local_hex_string(b->shadow_contents[1]));
+ local_hex_string((unsigned long) b->shadow_contents[1]));
#endif /* BREAKPOINT_DEBUG */
}
return 0;
}
-/* Clear the "inserted" flag in all breakpoints.
- This is done when the inferior is loaded. */
+/* Clear the "inserted" flag in all breakpoints. */
void
mark_breakpoints_out ()
b->inserted = 0;
}
+/* Clear the "inserted" flag in all breakpoints and delete any breakpoints
+ which should go away between runs of the program. */
+
+void
+breakpoint_init_inferior ()
+{
+ register struct breakpoint *b, *temp;
+
+ ALL_BREAKPOINTS_SAFE (b, temp)
+ {
+ b->inserted = 0;
+
+ /* If the call dummy breakpoint is at the entry point it will
+ cause problems when the inferior is rerun, so we better
+ get rid of it. */
+ if (b->type == bp_call_dummy)
+ delete_breakpoint (b);
+ }
+}
+
/* breakpoint_here_p (PC) returns 1 if an enabled breakpoint exists at PC.
When continuing from a location with a breakpoint,
we actually single step once before calling insert_breakpoints. */
{
bpstat p = NULL;
bpstat tmp;
- bpstat retval;
+ bpstat retval = NULL;
if (bs == NULL)
return bs;
{
/* We use value_{,free_to_}mark because it could be a
*long* time before we return to the command level and
- call free_all_values. */
- /* But couldn't we just call free_all_values instead? */
+ call free_all_values. We can't call free_all_values because
+ we might be in the middle of evaluating a function call. */
value mark = value_mark ();
value new_val = evaluate_expression (bs->breakpoint_at->exp);
return -1;
}
+/* Get a bpstat associated with having just stopped at address *PC
+ and frame address FRAME_ADDRESS. Update *PC to point at the
+ breakpoint (if we hit a breakpoint). NOT_A_BREAKPOINT is nonzero
+ if this is known to not be a real breakpoint (it could still be a
+ watchpoint, though). */
+
/* Determine whether we stopped at a breakpoint, etc, or whether we
don't understand this stop. Result is a chain of bpstat's such that:
if we don't understand the stop, the result is a null pointer.
- if we understand why we stopped, the result is not null, and
- the first element of the chain contains summary "stop" and
- "print" flags for the whole chain.
+ if we understand why we stopped, the result is not null.
Each element of the chain refers to a particular breakpoint or
watchpoint at which we have stopped. (We may have stopped for
*/
-
bpstat
-bpstat_stop_status (pc, frame_address)
+bpstat_stop_status (pc, frame_address, not_a_breakpoint)
CORE_ADDR *pc;
FRAME_ADDR frame_address;
+ int not_a_breakpoint;
{
register struct breakpoint *b;
CORE_ADDR bp_addr;
if (b->type != bp_watchpoint && b->address != bp_addr)
continue;
+ if (b->type != bp_watchpoint && not_a_breakpoint)
+ continue;
+
/* Come here if it's a watchpoint, or if the break address matches */
bs = bpstat_alloc (b, bs); /* Alloc a bpstat to explain stop */
bs->stop = 0;
else
{
- int value_is_zero;
+ int value_is_zero = 0;
if (b->cond)
{
{
*pc = bp_addr;
#if defined (SHIFT_INST_REGS)
- {
- CORE_ADDR pc = read_register (PC_REGNUM);
- CORE_ADDR npc = read_register (NPC_REGNUM);
- if (pc != npc)
- {
- write_register (NNPC_REGNUM, npc);
- write_register (NPC_REGNUM, pc);
- }
- }
+ SHIFT_INST_REGS();
#else /* No SHIFT_INST_REGS. */
write_pc (bp_addr);
#endif /* No SHIFT_INST_REGS. */
#define err BPSTAT_WHAT_STOP_NOISY
/* Given an old action and a class, come up with a new action. */
+ /* One interesting property of this table is that wp_silent is the same
+ as bp_silent and wp_noisy is the same as bp_noisy. That is because
+ after stopping, the check for whether to step over a breakpoint
+ (BPSTAT_WHAT_SINGLE type stuff) is handled in proceed() without
+ reference to how we stopped. We retain separate wp_silent and bp_silent
+ codes in case we want to change that someday. */
static const enum bpstat_what_main_action
table[(int)class_last][(int)BPSTAT_WHAT_LAST] =
{
#undef clrlrs
#undef err
enum bpstat_what_main_action current_action = BPSTAT_WHAT_KEEP_CHECKING;
- int found_step_resume = 0;
+ struct bpstat_what retval;
+ retval.call_dummy = 0;
+ retval.step_resume = 0;
for (; bs != NULL; bs = bs->next)
{
- enum class bs_class;
+ enum class bs_class = no_effect;
if (bs->breakpoint_at == NULL)
/* I suspect this can happen if it was a momentary breakpoint
which has since been deleted. */
if (bs->stop)
{
#endif
- found_step_resume = 1;
+ retval.step_resume = 1;
/* We don't handle this via the main_action. */
bs_class = no_effect;
#if 0
bs_class = bp_nostop;
#endif
break;
+ case bp_call_dummy:
+ /* Make sure the action is stop (silent or noisy), so infrun.c
+ pops the dummy frame. */
+ bs_class = bp_silent;
+ retval.call_dummy = 1;
+ break;
}
current_action = table[(int)bs_class][(int)current_action];
}
- {
- struct bpstat_what retval;
- retval.main_action = current_action;
- retval.step_resume = found_step_resume;
- return retval;
- }
+ retval.main_action = current_action;
+ return retval;
}
/* Nonzero if we should step constantly (e.g. watchpoints on machines
CORE_ADDR last_addr = (CORE_ADDR)-1;
int found_a_breakpoint = 0;
static char *bptypes[] = {"breakpoint", "until", "finish", "watchpoint",
- "longjmp", "longjmp resume"};
+ "longjmp", "longjmp resume", "step resume",
+ "call dummy" };
static char *bpdisps[] = {"del", "dis", "keep"};
static char bpenables[] = "ny";
char wrap_indent[80];
- if (!breakpoint_chain)
- {
- printf_filtered ("No breakpoints or watchpoints.\n");
- return;
- }
-
ALL_BREAKPOINTS (b)
if (bnum == -1
|| bnum == b->number)
case bp_watchpoint:
print_expression (b->exp, stdout);
break;
+
case bp_breakpoint:
case bp_until:
case bp_finish:
case bp_longjmp:
case bp_longjmp_resume:
+ case bp_step_resume:
+ case bp_call_dummy:
if (addressprint)
- printf_filtered ("%s ", local_hex_string_custom(b->address, "08"));
+ printf_filtered ("%s ", local_hex_string_custom ((unsigned long) b->address, "08l"));
last_addr = b->address;
if (b->source_file)
}
else
print_address_symbolic (b->address, stdout, demangle, " ");
+ break;
}
printf_filtered ("\n");
if (b->frame)
printf_filtered ("\tstop only in stack frame at %s\n",
- local_hex_string(b->frame));
+ local_hex_string((unsigned long) b->frame));
if (b->cond)
{
printf_filtered ("\tstop only if ");
}
}
- if (!found_a_breakpoint
- && bnum != -1)
- printf_filtered ("No breakpoint or watchpoint number %d.\n", bnum);
+ if (!found_a_breakpoint)
+ {
+ if (bnum == -1)
+ printf_filtered ("No breakpoints or watchpoints.\n");
+ else
+ printf_filtered ("No breakpoint or watchpoint number %d.\n", bnum);
+ }
else
/* Compare against (CORE_ADDR)-1 in case some compiler decides
that a comparison of an unsigned with -1 is always false. */
(b->enable == disabled) ? " (disabled)" : "",
(others > 1) ? "," : ((others == 1) ? " and" : ""));
}
- printf ("also set at pc %s.\n", local_hex_string(pc));
+ printf ("also set at pc %s.\n", local_hex_string((unsigned long) pc));
}
}
\f
break;
case bp_breakpoint:
printf_filtered ("Breakpoint %d at %s", b->number,
- local_hex_string(b->address));
+ local_hex_string((unsigned long) b->address));
if (b->source_file)
printf_filtered (": file %s, line %d.",
b->source_file, b->line_number);
case bp_finish:
case bp_longjmp:
case bp_longjmp_resume:
+ case bp_step_resume:
break;
}
printf_filtered ("\n");
/* Pointers in arg to the start, and one past the end, of the condition. */
char *cond_start = NULL;
- char *cond_end;
+ char *cond_end = NULL;
/* Pointers in arg to the start, and one past the end,
of the address part. */
char *addr_start = NULL;
- char *addr_end;
+ char *addr_end = NULL;
struct cleanup *old_chain;
- struct cleanup *canonical_strings_chain;
+ struct cleanup *canonical_strings_chain = NULL;
char **canonical = (char **)NULL;
int i;
bpstat bs;
{
for (; bs; bs = bs->next)
- if (bs->breakpoint_at && bs->breakpoint_at->disposition == delete)
+ if (bs->breakpoint_at && bs->breakpoint_at->disposition == delete
+ && bs->stop)
delete_breakpoint (bs->breakpoint_at);
}
if (bpt->inserted)
{
ALL_BREAKPOINTS (b)
- if (b->address == bpt->address && !b->duplicate)
+ if (b->address == bpt->address
+ && !b->duplicate
+ && b->enable != disabled)
{
int val;
val = target_insert_breakpoint (b->address, b->shadow_contents);
for (i = 0; i < sals.nelts; i++)
{
resolve_sal_pc (&sals.sals[i]);
+
+ /* Reparse conditions, they might contain references to the
+ old symtab. */
+ if (b->cond_string != NULL)
+ {
+ s = b->cond_string;
+ if (b->cond)
+ free ((PTR)b->cond);
+ b->cond = parse_exp_1 (&s, block_for_pc (sals.sals[i].pc), 0);
+ }
+
+ /* We need to re-set the breakpoint if the address changes...*/
if (b->address != sals.sals[i].pc
+ /* ...or new and old breakpoints both have source files, and
+ the source file name or the line number changes... */
|| (b->source_file != NULL
&& sals.sals[i].symtab != NULL
&& (!STREQ (b->source_file, sals.sals[i].symtab->filename)
|| b->line_number != sals.sals[i].line)
- ))
+ )
+ /* ...or we switch between having a source file and not having
+ one. */
+ || ((b->source_file == NULL) != (sals.sals[i].symtab == NULL))
+ )
{
if (b->source_file != NULL)
free (b->source_file);
strlen (sals.sals[i].symtab->filename));
b->line_number = sals.sals[i].line;
b->address = sals.sals[i].pc;
-
- if (b->cond_string != NULL)
- {
- s = b->cond_string;
- if (b->cond)
- free ((PTR)b->cond);
- b->cond = parse_exp_1 (&s, block_for_pc (sals.sals[i].pc), 0);
- }
check_duplicates (b->address);
case bp_finish:
case bp_longjmp:
case bp_longjmp_resume:
+ case bp_call_dummy:
delete_breakpoint (b);
break;
}
enable_breakpoint (bpt)
struct breakpoint *bpt;
{
- FRAME save_selected_frame;
+ FRAME save_selected_frame = NULL;
int save_selected_frame_level = -1;
bpt->enable = enabled;