/* Everything about breakpoints, for GDB.
- Copyright 1986, 87, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999
+ Copyright 1986, 87, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999, 2000
Free Software Foundation, Inc.
This file is part of GDB.
#include "annotate.h"
#include "symfile.h"
#include "objfiles.h"
+#ifdef UI_OUT
+#include "ui-out.h"
+#endif
#include "gdb-events.h"
static void until_break_command_continuation (struct continuation_arg *arg);
-static void
-catch_command_1 PARAMS ((char *, int, int));
+static void catch_command_1 (char *, int, int);
-static void
-enable_delete_command PARAMS ((char *, int));
+static void enable_delete_command (char *, int);
-static void
-enable_delete_breakpoint PARAMS ((struct breakpoint *));
+static void enable_delete_breakpoint (struct breakpoint *);
-static void
-enable_once_command PARAMS ((char *, int));
+static void enable_once_command (char *, int);
-static void
-enable_once_breakpoint PARAMS ((struct breakpoint *));
+static void enable_once_breakpoint (struct breakpoint *);
-static void
-disable_command PARAMS ((char *, int));
+static void disable_command (char *, int);
-static void
-enable_command PARAMS ((char *, int));
+static void enable_command (char *, int);
-static void
-map_breakpoint_numbers PARAMS ((char *, void (*)(struct breakpoint *)));
+static void map_breakpoint_numbers (char *, void (*)(struct breakpoint *));
-static void
-ignore_command PARAMS ((char *, int));
+static void ignore_command (char *, int);
-static int breakpoint_re_set_one PARAMS ((PTR));
+static int breakpoint_re_set_one (PTR);
-static void
-clear_command PARAMS ((char *, int));
+static void clear_command (char *, int);
-static void
-catch_command PARAMS ((char *, int));
+static void catch_command (char *, int);
-static void
-handle_gnu_4_16_catch_command PARAMS ((char *, int, int));
+static void handle_gnu_4_16_catch_command (char *, int, int);
-static struct symtabs_and_lines
-get_catch_sals PARAMS ((int));
+static struct symtabs_and_lines get_catch_sals (int);
-static void
-watch_command PARAMS ((char *, int));
+static void watch_command (char *, int);
-static int
-can_use_hardware_watchpoint PARAMS ((struct value *));
+static int can_use_hardware_watchpoint (struct value *);
-static void break_at_finish_command PARAMS ((char *, int));
-static void break_at_finish_at_depth_command PARAMS ((char *, int));
+static void break_at_finish_command (char *, int);
+static void break_at_finish_at_depth_command (char *, int);
-void
-tbreak_command PARAMS ((char *, int));
+void tbreak_command (char *, int);
-static void tbreak_at_finish_command PARAMS ((char *, int));
+static void tbreak_at_finish_command (char *, int);
-static void
-break_command_1 PARAMS ((char *, int, int));
+static void break_command_1 (char *, int, int);
-static void
-mention PARAMS ((struct breakpoint *));
+static void mention (struct breakpoint *);
-struct breakpoint *
- set_raw_breakpoint PARAMS ((struct symtab_and_line));
+struct breakpoint *set_raw_breakpoint (struct symtab_and_line);
-static void
-check_duplicates PARAMS ((CORE_ADDR, asection *));
+static void check_duplicates (CORE_ADDR, asection *);
-static void
-describe_other_breakpoints PARAMS ((CORE_ADDR, asection *));
+static void describe_other_breakpoints (CORE_ADDR, asection *);
-static void
-breakpoints_info PARAMS ((char *, int));
+static void breakpoints_info (char *, int);
-static void
-breakpoint_1 PARAMS ((int, int));
+static void breakpoint_1 (int, int);
-static bpstat
- bpstat_alloc PARAMS ((struct breakpoint *, bpstat));
+static bpstat bpstat_alloc (struct breakpoint *, bpstat);
-static int breakpoint_cond_eval PARAMS ((PTR));
+static int breakpoint_cond_eval (PTR);
-static void
-cleanup_executing_breakpoints PARAMS ((PTR));
+static void cleanup_executing_breakpoints (PTR);
-static void
-commands_command PARAMS ((char *, int));
+static void commands_command (char *, int);
-static void
-condition_command PARAMS ((char *, int));
+static void condition_command (char *, int);
-static int
-get_number_trailer PARAMS ((char **, int));
+static int get_number_trailer (char **, int);
-void
-set_breakpoint_count PARAMS ((int));
+void set_breakpoint_count (int);
#if 0
-static struct breakpoint *
- create_temp_exception_breakpoint PARAMS ((CORE_ADDR));
+static struct breakpoint *create_temp_exception_breakpoint (CORE_ADDR);
#endif
typedef enum
}
insertion_state_t;
-static int
-remove_breakpoint PARAMS ((struct breakpoint *, insertion_state_t));
+static int remove_breakpoint (struct breakpoint *, insertion_state_t);
-static enum print_stop_action print_it_typical PARAMS ((bpstat));
+static enum print_stop_action print_it_typical (bpstat);
static enum print_stop_action print_bp_stop_message (bpstat bs);
}
args_for_catchpoint_enable;
-static int watchpoint_check PARAMS ((PTR));
+static int watchpoint_check (PTR);
-static int cover_target_enable_exception_callback PARAMS ((PTR));
+static int cover_target_enable_exception_callback (PTR);
-static void maintenance_info_breakpoints PARAMS ((char *, int));
+static void maintenance_info_breakpoints (char *, int);
#ifdef GET_LONGJMP_TARGET
-static void create_longjmp_breakpoint PARAMS ((char *));
+static void create_longjmp_breakpoint (char *);
#endif
-static int hw_breakpoint_used_count PARAMS ((void));
+static int hw_breakpoint_used_count (void);
-static int hw_watchpoint_used_count PARAMS ((enum bptype, int *));
+static int hw_watchpoint_used_count (enum bptype, int *);
-static void hbreak_command PARAMS ((char *, int));
+static void hbreak_command (char *, int);
-static void thbreak_command PARAMS ((char *, int));
+static void thbreak_command (char *, int);
-static void watch_command_1 PARAMS ((char *, int, int));
+static void watch_command_1 (char *, int, int);
-static void rwatch_command PARAMS ((char *, int));
+static void rwatch_command (char *, int);
-static void awatch_command PARAMS ((char *, int));
+static void awatch_command (char *, int);
-static void do_enable_breakpoint PARAMS ((struct breakpoint *, enum bpdisp));
+static void do_enable_breakpoint (struct breakpoint *, enum bpdisp);
-static void solib_load_unload_1 PARAMS ((char *hookname,
- int tempflag,
- char *dll_pathname,
- char *cond_string,
- enum bptype bp_kind));
+static void solib_load_unload_1 (char *hookname,
+ int tempflag,
+ char *dll_pathname,
+ char *cond_string, enum bptype bp_kind);
-static void create_fork_vfork_event_catchpoint PARAMS ((int tempflag,
- char *cond_string,
- enum bptype bp_kind));
+static void create_fork_vfork_event_catchpoint (int tempflag,
+ char *cond_string,
+ enum bptype bp_kind);
-static void break_at_finish_at_depth_command_1 PARAMS ((char *arg,
- int flag,
- int from_tty));
+static void break_at_finish_at_depth_command_1 (char *arg,
+ int flag, int from_tty);
-static void break_at_finish_command_1 PARAMS ((char *arg,
- int flag,
- int from_tty));
+static void break_at_finish_command_1 (char *arg, int flag, int from_tty);
-static void stop_command PARAMS ((char *arg, int from_tty));
+static void stop_command (char *arg, int from_tty);
-static void stopin_command PARAMS ((char *arg, int from_tty));
+static void stopin_command (char *arg, int from_tty);
-static void stopat_command PARAMS ((char *arg, int from_tty));
+static void stopat_command (char *arg, int from_tty);
-static char *ep_find_event_name_end PARAMS ((char *arg));
+static char *ep_find_event_name_end (char *arg);
-static char *ep_parse_optional_if_clause PARAMS ((char **arg));
+static char *ep_parse_optional_if_clause (char **arg);
-static char *ep_parse_optional_filename PARAMS ((char **arg));
+static char *ep_parse_optional_filename (char **arg);
#if defined(CHILD_INSERT_EXEC_CATCHPOINT)
-static void catch_exec_command_1 PARAMS ((char *arg, int tempflag,
- int from_tty));
+static void catch_exec_command_1 (char *arg, int tempflag, int from_tty);
#endif
-static void create_exception_catchpoint
- PARAMS ((int tempflag, char *cond_string,
- enum exception_event_kind ex_event,
- struct symtab_and_line * sal));
+static void create_exception_catchpoint
+ (int tempflag, char *cond_string,
+ enum exception_event_kind ex_event, struct symtab_and_line *sal);
-static void catch_exception_command_1
- PARAMS ((enum exception_event_kind ex_event,
- char *arg, int tempflag, int from_tty));
+static void catch_exception_command_1
+ (enum exception_event_kind ex_event, char *arg, int tempflag, int from_tty);
-static void tcatch_command PARAMS ((char *arg, int from_tty));
+static void tcatch_command (char *arg, int from_tty);
-static void ep_skip_leading_whitespace PARAMS ((char **s));
+static void ep_skip_leading_whitespace (char **s);
/* Prototypes for exported functions. */
-static void
-awatch_command PARAMS ((char *, int));
+static void awatch_command (char *, int);
-static void
-do_enable_breakpoint PARAMS ((struct breakpoint *, enum bpdisp));
+static void do_enable_breakpoint (struct breakpoint *, enum bpdisp);
/* If FALSE, gdb will not use hardware support for watchpoints, even
if such is available. */
static int can_use_hw_watchpoints;
-void _initialize_breakpoint PARAMS ((void));
+void _initialize_breakpoint (void);
-void set_breakpoint_count PARAMS ((int));
+void set_breakpoint_count (int);
extern int addressprint; /* Print machine addresses? */
-#if defined (GET_LONGJMP_TARGET) || defined (SOLIB_ADD)
static int internal_breakpoint_number = -1;
-#endif
/* Are we executing breakpoint commands? */
static int executing_breakpoint_commands;
/* Set breakpoint count to NUM. */
void
-set_breakpoint_count (num)
- int num;
+set_breakpoint_count (int num)
{
breakpoint_count = num;
set_internalvar (lookup_internalvar ("bpnum"),
/* Used in run_command to zero the hit count when a new run starts. */
void
-clear_breakpoint_hit_counts ()
+clear_breakpoint_hit_counts (void)
{
struct breakpoint *b;
TRAILER is a character which can be found after the number; most
commonly this is `-'. If you don't want a trailer, use \0. */
static int
-get_number_trailer (pp, trailer)
- char **pp;
- int trailer;
+get_number_trailer (char **pp, int trailer)
{
int retval = 0; /* default */
char *p = *pp;
/* Like get_number_trailer, but don't allow a trailer. */
int
-get_number (pp)
- char **pp;
+get_number (char **pp)
{
return get_number_trailer (pp, '\0');
}
*/
int
-get_number_or_range (pp)
- char **pp;
+get_number_or_range (char **pp)
{
static int last_retval, end_value;
static char *end_ptr;
/* condition N EXP -- set break condition of breakpoint N to EXP. */
static void
-condition_command (arg, from_tty)
- char *arg;
- int from_tty;
+condition_command (char *arg, int from_tty)
{
register struct breakpoint *b;
char *p;
/* ARGSUSED */
static void
-commands_command (arg, from_tty)
- char *arg;
- int from_tty;
+commands_command (char *arg, int from_tty)
{
register struct breakpoint *b;
char *p;
shadow contents, not the breakpoints themselves. From breakpoint.c. */
int
-read_memory_nobpt (memaddr, myaddr, len)
- CORE_ADDR memaddr;
- char *myaddr;
- unsigned len;
+read_memory_nobpt (CORE_ADDR memaddr, char *myaddr, unsigned len)
{
int status;
struct breakpoint *b;
or an `errno' value if could not write the inferior. */
int
-insert_breakpoints ()
+insert_breakpoints (void)
{
register struct breakpoint *b, *temp;
int return_val = 0; /* return success code. */
b->type == bp_read_watchpoint ||
b->type == bp_access_watchpoint)
&& b->enable == enabled
+ && b->disposition != del_at_next_stop
&& !b->inserted
&& !b->duplicate)
{
if (VALUE_LVAL (v) == lval_memory
&& ! VALUE_LAZY (v))
{
- CORE_ADDR addr;
- int len, type;
-
- addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
- len = TYPE_LENGTH (VALUE_TYPE (v));
- type = hw_write;
- if (b->type == bp_read_watchpoint)
- type = hw_read;
- else if (b->type == bp_access_watchpoint)
- type = hw_access;
-
- val = target_insert_watchpoint (addr, len, type);
- if (val == -1)
+ struct type *vtype = check_typedef (VALUE_TYPE (v));
+
+ /* We only watch structs and arrays if user asked
+ for it explicitly, never if they just happen to
+ appear in the middle of some value chain. */
+ if (v == b->val_chain
+ || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
+ && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
{
- b->inserted = 0;
- break;
+ CORE_ADDR addr;
+ int len, type;
+
+ addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+ len = TYPE_LENGTH (VALUE_TYPE (v));
+ type = hw_write;
+ if (b->type == bp_read_watchpoint)
+ type = hw_read;
+ else if (b->type == bp_access_watchpoint)
+ type = hw_access;
+
+ val = target_insert_watchpoint (addr, len, type);
+ if (val == -1)
+ {
+ /* Don't exit the loop, try to insert
+ every value on the value chain. That's
+ because we will be removing all the
+ watches below, and removing a
+ watchpoint we didn't insert could have
+ adverse effects. */
+ b->inserted = 0;
+ }
+ val = 0;
}
- val = 0;
}
}
/* Failure to insert a watchpoint on any memory value in the
}
else
{
- printf_filtered ("Hardware watchpoint %d deleted", b->number);
+ printf_filtered ("Hardware watchpoint %d deleted ", b->number);
printf_filtered ("because the program has left the block \n");
printf_filtered ("in which its expression is valid.\n");
if (b->related_breakpoint)
/* Restore the frame and level. */
if ((saved_frame != selected_frame) ||
(saved_level != selected_frame_level))
- select_and_print_frame (saved_frame, saved_level);
+ select_frame (saved_frame, saved_level);
if (val)
return_val = val; /* remember failure */
int
-remove_breakpoints ()
+remove_breakpoints (void)
{
register struct breakpoint *b;
int val;
}
int
-reattach_breakpoints (pid)
- int pid;
+remove_hw_watchpoints (void)
+{
+ register struct breakpoint *b;
+ int val;
+
+ ALL_BREAKPOINTS (b)
+ {
+ if (b->inserted
+ && (b->type == bp_hardware_watchpoint
+ || b->type == bp_read_watchpoint
+ || b->type == bp_access_watchpoint))
+ {
+ val = remove_breakpoint (b, mark_uninserted);
+ if (val != 0)
+ return val;
+ }
+ }
+ return 0;
+}
+
+int
+reattach_breakpoints (int pid)
{
register struct breakpoint *b;
int val;
}
void
-update_breakpoints_after_exec ()
+update_breakpoints_after_exec (void)
{
struct breakpoint *b;
struct breakpoint *temp;
continue;
}
+ /* Thread event breakpoints must be set anew after an exec(). */
+ if (b->type == bp_thread_event)
+ {
+ delete_breakpoint (b);
+ continue;
+ }
+
/* Step-resume breakpoints are meaningless after an exec(). */
if (b->type == bp_step_resume)
{
}
int
-detach_breakpoints (pid)
- int pid;
+detach_breakpoints (int pid)
{
register struct breakpoint *b;
int val;
}
static int
-remove_breakpoint (b, is)
- struct breakpoint *b;
- insertion_state_t is;
+remove_breakpoint (struct breakpoint *b, insertion_state_t is)
{
int val;
if (VALUE_LVAL (v) == lval_memory
&& ! VALUE_LAZY (v))
{
- CORE_ADDR addr;
- int len, type;
-
- addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
- len = TYPE_LENGTH (VALUE_TYPE (v));
- type = hw_write;
- if (b->type == bp_read_watchpoint)
- type = hw_read;
- else if (b->type == bp_access_watchpoint)
- type = hw_access;
+ struct type *vtype = check_typedef (VALUE_TYPE (v));
- val = target_remove_watchpoint (addr, len, type);
- if (val == -1)
- b->inserted = 1;
- val = 0;
+ if (v == b->val_chain
+ || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
+ && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
+ {
+ CORE_ADDR addr;
+ int len, type;
+
+ addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+ len = TYPE_LENGTH (VALUE_TYPE (v));
+ type = hw_write;
+ if (b->type == bp_read_watchpoint)
+ type = hw_read;
+ else if (b->type == bp_access_watchpoint)
+ type = hw_access;
+
+ val = target_remove_watchpoint (addr, len, type);
+ if (val == -1)
+ b->inserted = 1;
+ val = 0;
+ }
}
}
/* Failure to remove any of the hardware watchpoints comes here. */
/* Clear the "inserted" flag in all breakpoints. */
void
-mark_breakpoints_out ()
+mark_breakpoints_out (void)
{
register struct breakpoint *b;
void
-breakpoint_init_inferior (context)
- enum inf_context context;
+breakpoint_init_inferior (enum inf_context context)
{
register struct breakpoint *b, *temp;
static int warning_needed = 0;
the target, to advance the PC past the breakpoint. */
enum breakpoint_here
-breakpoint_here_p (pc)
- CORE_ADDR pc;
+breakpoint_here_p (CORE_ADDR pc)
{
register struct breakpoint *b;
int any_breakpoint_here = 0;
at PC. */
int
-breakpoint_inserted_here_p (pc)
- CORE_ADDR pc;
+breakpoint_inserted_here_p (CORE_ADDR pc)
{
register struct breakpoint *b;
bp_call_dummy breakpoint. */
int
-frame_in_dummy (frame)
- struct frame_info *frame;
+frame_in_dummy (struct frame_info *frame)
{
struct breakpoint *b;
return 0;
}
-/* breakpoint_match_thread (PC, PID) returns true if the breakpoint at PC
- is valid for process/thread PID. */
+/* breakpoint_thread_match (PC, PID) returns true if the breakpoint at
+ PC is valid for process/thread PID. */
int
-breakpoint_thread_match (pc, pid)
- CORE_ADDR pc;
- int pid;
+breakpoint_thread_match (CORE_ADDR pc, int pid)
{
struct breakpoint *b;
int thread;
in breakpoint.h. */
int
-ep_is_catchpoint (ep)
- struct breakpoint *ep;
+ep_is_catchpoint (struct breakpoint *ep)
{
return
(ep->type == bp_catch_load)
}
int
-ep_is_shlib_catchpoint (ep)
- struct breakpoint *ep;
+ep_is_shlib_catchpoint (struct breakpoint *ep)
{
return
(ep->type == bp_catch_load)
}
int
-ep_is_exception_catchpoint (ep)
- struct breakpoint *ep;
+ep_is_exception_catchpoint (struct breakpoint *ep)
{
return
(ep->type == bp_catch_catch)
Also free any storage that is part of a bpstat. */
void
-bpstat_clear (bsp)
- bpstat *bsp;
+bpstat_clear (bpstat *bsp)
{
bpstat p;
bpstat q;
is part of the bpstat is copied as well. */
bpstat
-bpstat_copy (bs)
- bpstat bs;
+bpstat_copy (bpstat bs)
{
bpstat p = NULL;
bpstat tmp;
/* Find the bpstat associated with this breakpoint */
bpstat
-bpstat_find_breakpoint (bsp, breakpoint)
- bpstat bsp;
- struct breakpoint *breakpoint;
+bpstat_find_breakpoint (bpstat bsp, struct breakpoint *breakpoint)
{
if (bsp == NULL)
return NULL;
See wait_for_inferior's use of this function. */
struct breakpoint *
-bpstat_find_step_resume_breakpoint (bsp)
- bpstat bsp;
+bpstat_find_step_resume_breakpoint (bpstat bsp)
{
if (bsp == NULL)
error ("Internal error (bpstat_find_step_resume_breakpoint)");
Return 0 if passed a bpstat which does not indicate any breakpoints. */
int
-bpstat_num (bsp)
- bpstat *bsp;
+bpstat_num (bpstat *bsp)
{
struct breakpoint *b;
/* Modify BS so that the actions will not be performed. */
void
-bpstat_clear_actions (bs)
- bpstat bs;
+bpstat_clear_actions (bpstat bs)
{
for (; bs != NULL; bs = bs->next)
{
/* Stub for cleaning up our state if we error-out of a breakpoint command */
/* ARGSUSED */
static void
-cleanup_executing_breakpoints (ignore)
- PTR ignore;
+cleanup_executing_breakpoints (PTR ignore)
{
executing_breakpoint_commands = 0;
}
the global "breakpoint_proceeded" after each command. */
void
-bpstat_do_actions (bsp)
- bpstat *bsp;
+bpstat_do_actions (bpstat *bsp)
{
bpstat bs;
struct cleanup *old_chain;
analysis. */
static enum print_stop_action
-print_it_typical (bs)
- bpstat bs;
+print_it_typical (bpstat bs)
{
+#ifdef UI_OUT
+ struct cleanup *old_chain;
+ struct ui_stream *stb;
+ stb = ui_out_stream_new (uiout);
+ old_chain = make_cleanup_ui_out_stream_delete (stb);
+#endif /* UI_OUT */
/* bs->breakpoint_at can be NULL if it was a momentary breakpoint
which has since been deleted. */
if (bs->breakpoint_at == NULL)
{
case bp_breakpoint:
case bp_hardware_breakpoint:
+#ifdef UI_OUT
+ annotate_breakpoint (bs->breakpoint_at->number);
+ ui_out_text (uiout, "\nBreakpoint ");
+ if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+ ui_out_field_string (uiout, "reason", "breakpoint-hit");
+ ui_out_field_int (uiout, "bkptno", bs->breakpoint_at->number);
+ ui_out_text (uiout, ", ");
+ return PRINT_SRC_AND_LOC;
+#else
/* I think the user probably only wants to see one breakpoint
number, not all of them. */
annotate_breakpoint (bs->breakpoint_at->number);
printf_filtered ("\nBreakpoint %d, ", bs->breakpoint_at->number);
return PRINT_SRC_AND_LOC;
+#endif
break;
case bp_shlib_event:
return PRINT_NOTHING;
break;
+ case bp_thread_event:
+ /* Not sure how we will get here.
+ GDB should not stop for these breakpoints. */
+ printf_filtered ("Thread Event Breakpoint: gdb should not stop!\n");
+ return PRINT_NOTHING;
+ break;
+
case bp_catch_load:
annotate_catchpoint (bs->breakpoint_at->number);
printf_filtered ("\nCatchpoint %d (", bs->breakpoint_at->number);
if (bs->old_val != NULL)
{
annotate_watchpoint (bs->breakpoint_at->number);
+#ifdef UI_OUT
+ if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+ ui_out_field_string (uiout, "reason", "watchpoint-trigger");
+ mention (bs->breakpoint_at);
+ ui_out_list_begin (uiout, "value");
+ ui_out_text (uiout, "\nOld value = ");
+ value_print (bs->old_val, stb->stream, 0, Val_pretty_default);
+ ui_out_field_stream (uiout, "old", stb);
+ ui_out_text (uiout, "\nNew value = ");
+ value_print (bs->breakpoint_at->val, stb->stream, 0, Val_pretty_default);
+ ui_out_field_stream (uiout, "new", stb);
+ ui_out_list_end (uiout);
+ ui_out_text (uiout, "\n");
+#else
mention (bs->breakpoint_at);
printf_filtered ("\nOld value = ");
value_print (bs->old_val, gdb_stdout, 0, Val_pretty_default);
value_print (bs->breakpoint_at->val, gdb_stdout, 0,
Val_pretty_default);
printf_filtered ("\n");
+#endif
value_free (bs->old_val);
bs->old_val = NULL;
}
break;
case bp_read_watchpoint:
+#ifdef UI_OUT
+ if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+ ui_out_field_string (uiout, "reason", "read-watchpoint-trigger");
+ mention (bs->breakpoint_at);
+ ui_out_list_begin (uiout, "value");
+ ui_out_text (uiout, "\nValue = ");
+ value_print (bs->breakpoint_at->val, stb->stream, 0, Val_pretty_default);
+ ui_out_field_stream (uiout, "value", stb);
+ ui_out_list_end (uiout);
+ ui_out_text (uiout, "\n");
+#else
mention (bs->breakpoint_at);
printf_filtered ("\nValue = ");
value_print (bs->breakpoint_at->val, gdb_stdout, 0,
Val_pretty_default);
printf_filtered ("\n");
+#endif
return PRINT_UNKNOWN;
break;
case bp_access_watchpoint:
+#ifdef UI_OUT
+ if (bs->old_val != NULL)
+ {
+ annotate_watchpoint (bs->breakpoint_at->number);
+ if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+ ui_out_field_string (uiout, "reason", "access-watchpoint-trigger");
+ mention (bs->breakpoint_at);
+ ui_out_list_begin (uiout, "value");
+ ui_out_text (uiout, "\nOld value = ");
+ value_print (bs->old_val, stb->stream, 0, Val_pretty_default);
+ ui_out_field_stream (uiout, "old", stb);
+ value_free (bs->old_val);
+ bs->old_val = NULL;
+ ui_out_text (uiout, "\nNew value = ");
+ }
+ else
+ {
+ mention (bs->breakpoint_at);
+ if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+ ui_out_list_begin (uiout, "value");
+ ui_out_field_string (uiout, "reason", "access-watchpoint-trigger");
+ ui_out_text (uiout, "\nValue = ");
+ }
+ value_print (bs->breakpoint_at->val, stb->stream, 0,Val_pretty_default);
+ ui_out_field_stream (uiout, "new", stb);
+ ui_out_list_end (uiout);
+ ui_out_text (uiout, "\n");
+#else
if (bs->old_val != NULL)
{
annotate_watchpoint (bs->breakpoint_at->number);
value_print (bs->breakpoint_at->val, gdb_stdout, 0,
Val_pretty_default);
printf_filtered ("\n");
+#endif
return PRINT_UNKNOWN;
break;
here. */
case bp_finish:
+#ifdef UI_OUT
+ if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+ ui_out_field_string (uiout, "reason", "function-finished");
+#endif
+ return PRINT_UNKNOWN;
+ break;
+
case bp_until:
+#ifdef UI_OUT
+ if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+ ui_out_field_string (uiout, "reason", "location-reached");
+#endif
+ return PRINT_UNKNOWN;
+ break;
+
case bp_none:
case bp_longjmp:
case bp_longjmp_resume:
further info to be printed.*/
enum print_stop_action
-bpstat_print (bs)
- bpstat bs;
+bpstat_print (bpstat bs)
{
int val;
make it pass through catch_errors. */
static int
-breakpoint_cond_eval (exp)
- PTR exp;
+breakpoint_cond_eval (PTR exp)
{
value_ptr mark = value_mark ();
int i = !value_true (evaluate_expression ((struct expression *) exp));
/* Allocate a new bpstat and chain it to the current one. */
static bpstat
-bpstat_alloc (b, cbs)
- register struct breakpoint *b;
- bpstat cbs; /* Current "bs" value */
+bpstat_alloc (struct breakpoint *b, bpstat cbs /* Current "bs" value */ )
{
bpstat bs;
/* Check watchpoint condition. */
static int
-watchpoint_check (p)
- PTR p;
+watchpoint_check (PTR p)
{
bpstat bs = (bpstat) p;
struct breakpoint *b;
in this case, by the time we call print_it_typical() this bp
will be deleted already. So we have no choice but print the
information here. */
+#ifdef UI_OUT
+ if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+ ui_out_field_string (uiout, "reason", "watchpoint-scope");
+ ui_out_text (uiout, "\nWatchpoint ");
+ ui_out_field_int (uiout, "wpnum", bs->breakpoint_at->number);
+ ui_out_text (uiout, " deleted because the program has left the block in\n\
+which its expression is valid.\n");
+#else
printf_filtered ("\
Watchpoint %d deleted because the program has left the block in\n\
which its expression is valid.\n", bs->breakpoint_at->number);
+#endif
if (b->related_breakpoint)
b->related_breakpoint->disposition = del_at_next_stop;
commands, FIXME??? fields. */
bpstat
-bpstat_stop_status (pc, not_a_breakpoint)
- CORE_ADDR *pc;
- int not_a_breakpoint;
+bpstat_stop_status (CORE_ADDR *pc, int not_a_breakpoint)
{
register struct breakpoint *b, *temp;
CORE_ADDR bp_addr;
if (VALUE_LVAL (v) == lval_memory
&& ! VALUE_LAZY (v))
{
- CORE_ADDR vaddr;
-
- vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
- /* Exact match not required. Within range is sufficient.
- */
- if (addr >= vaddr &&
- addr < vaddr + TYPE_LENGTH (VALUE_TYPE (v)))
- found = 1;
+ struct type *vtype = check_typedef (VALUE_TYPE (v));
+
+ if (v == b->val_chain
+ || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
+ && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
+ {
+ CORE_ADDR vaddr;
+
+ vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+ /* Exact match not required. Within range is
+ sufficient. */
+ if (addr >= vaddr &&
+ addr < vaddr + TYPE_LENGTH (VALUE_TYPE (v)))
+ found = 1;
+ }
}
}
if (found)
/* Stop. */
break;
case WP_VALUE_CHANGED:
+ if (b->type == bp_read_watchpoint)
+ {
+ /* Don't stop: read watchpoints shouldn't fire if
+ the value has changed. This is for targets which
+ cannot set read-only watchpoints. */
+ bs->print_it = print_it_noop;
+ bs->stop = 0;
+ continue;
+ }
+ ++(b->hit_count);
+ break;
case WP_VALUE_NOT_CHANGED:
/* Stop. */
++(b->hit_count);
real_breakpoint = 1;
}
- if (b->frame && b->frame != (get_current_frame ())->frame &&
- (b->type == bp_step_resume &&
- (INNER_THAN (get_current_frame ()->frame, b->frame))))
+ if (b->frame &&
+ b->frame != (get_current_frame ())->frame)
bs->stop = 0;
else
{
\f
/* Tell what to do about this bpstat. */
struct bpstat_what
-bpstat_what (bs)
- bpstat bs;
+bpstat_what (bpstat bs)
{
/* Classify each bpstat as one of the following. */
enum class
/*bp_noisy */
{sn, sn, sn, sn, sn, sn, sn, sr, ts, shl, shlr},
/*long_jump */
- {slr, ss, sn, slr, err, err, err, sr, ts, shl, shlr},
+ {slr, ss, sn, slr, slr, err, err, sr, ts, shl, shlr},
/*long_resume */
{clr, ss, sn, clrs, err, err, err, sr, ts, shl, shlr},
/*step_resume */
case bp_shlib_event:
bs_class = shlib_event;
break;
+ case bp_thread_event:
+ bs_class = bp_nostop;
+ break;
case bp_catch_load:
case bp_catch_unload:
/* Only if this catchpoint triggered should we cause the
just to things like whether watchpoints are set. */
int
-bpstat_should_step ()
+bpstat_should_step (void)
{
struct breakpoint *b;
ALL_BREAKPOINTS (b)
/* Nonzero if there are enabled hardware watchpoints. */
int
-bpstat_have_active_hw_watchpoints ()
+bpstat_have_active_hw_watchpoints (void)
{
struct breakpoint *b;
ALL_BREAKPOINTS (b)
function returns another bpstat which contains only the catchpoints
on that first list, if any. */
void
-bpstat_get_triggered_catchpoints (ep_list, cp_list)
- bpstat ep_list;
- bpstat *cp_list;
+bpstat_get_triggered_catchpoints (bpstat ep_list, bpstat *cp_list)
{
struct bpstats root_bs[1];
bpstat bs = root_bs;
*cp_list = bs;
}
-/* Print information on breakpoint number BNUM, or -1 if all.
- If WATCHPOINTS is zero, process only breakpoints; if WATCHPOINTS
- is nonzero, process only watchpoints. */
-
-typedef struct
-{
- enum bptype type;
- char *description;
-}
-ep_type_description_t;
-
+/* Print B to gdb_stdout. */
static void
-breakpoint_1 (bnum, allflag)
- int bnum;
- int allflag;
+print_one_breakpoint (struct breakpoint *b,
+ CORE_ADDR *last_addr)
{
- register struct breakpoint *b;
register struct command_line *l;
register struct symbol *sym;
- CORE_ADDR last_addr = (CORE_ADDR) -1;
- int found_a_breakpoint = 0;
- static ep_type_description_t bptypes[] =
+ struct ep_type_description
+ {
+ enum bptype type;
+ char *description;
+ };
+ static struct ep_type_description bptypes[] =
{
{bp_none, "?deleted?"},
{bp_breakpoint, "breakpoint"},
{bp_watchpoint_scope, "watchpoint scope"},
{bp_call_dummy, "call dummy"},
{bp_shlib_event, "shlib events"},
+ {bp_thread_event, "thread events"},
{bp_catch_load, "catch load"},
{bp_catch_unload, "catch unload"},
{bp_catch_fork, "catch fork"},
{bp_catch_catch, "catch catch"},
{bp_catch_throw, "catch throw"}
};
-
+
static char *bpdisps[] =
{"del", "dstp", "dis", "keep"};
static char bpenables[] = "nynny";
char wrap_indent[80];
+#ifdef UI_OUT
+ struct ui_stream *stb = ui_out_stream_new (uiout);
+ struct cleanup *old_chain = make_cleanup_ui_out_stream_delete (stb);
+#endif
+ annotate_record ();
+#ifdef UI_OUT
+ ui_out_list_begin (uiout, "bkpt");
+#endif
+ /* 1 */
+ annotate_field (0);
+#ifdef UI_OUT
+ ui_out_field_int (uiout, "number", b->number);
+#else
+ printf_filtered ("%-3d ", b->number);
+#endif
- ALL_BREAKPOINTS (b)
- if (bnum == -1
- || bnum == b->number)
+ /* 2 */
+ annotate_field (1);
+ if (((int) b->type > (sizeof (bptypes) / sizeof (bptypes[0])))
+ || ((int) b->type != bptypes[(int) b->type].type))
+ internal_error ("bptypes table does not describe type #%d.",
+ (int) b->type);
+#ifdef UI_OUT
+ ui_out_field_string (uiout, "type", bptypes[(int) b->type].description);
+#else
+ printf_filtered ("%-14s ", bptypes[(int) b->type].description);
+#endif
+
+ /* 3 */
+ annotate_field (2);
+#ifdef UI_OUT
+ ui_out_field_string (uiout, "disp", bpdisps[(int) b->disposition]);
+#else
+ printf_filtered ("%-4s ", bpdisps[(int) b->disposition]);
+#endif
+
+ /* 4 */
+ annotate_field (3);
+#ifdef UI_OUT
+ ui_out_field_fmt (uiout, "enabled", "%c", bpenables[(int) b->enable]);
+ ui_out_spaces (uiout, 2);
+#else
+ printf_filtered ("%-3c ", bpenables[(int) b->enable]);
+#endif
+
+ /* 5 and 6 */
+ strcpy (wrap_indent, " ");
+ if (addressprint)
+ strcat (wrap_indent, " ");
+ switch (b->type)
{
-/* We only print out user settable breakpoints unless the allflag is set. */
- if (!allflag
- && b->type != bp_breakpoint
- && b->type != bp_catch_load
- && b->type != bp_catch_unload
- && b->type != bp_catch_fork
- && b->type != bp_catch_vfork
- && b->type != bp_catch_exec
- && b->type != bp_catch_catch
- && b->type != bp_catch_throw
- && b->type != bp_hardware_breakpoint
- && b->type != bp_watchpoint
- && b->type != bp_read_watchpoint
- && b->type != bp_access_watchpoint
- && b->type != bp_hardware_watchpoint)
- continue;
+ case bp_none:
+ internal_error ("print_one_breakpoint: bp_none encountered\n");
+ break;
- if (!found_a_breakpoint++)
+ case bp_watchpoint:
+ case bp_hardware_watchpoint:
+ case bp_read_watchpoint:
+ case bp_access_watchpoint:
+ /* Field 4, the address, is omitted (which makes the columns
+ not line up too nicely with the headers, but the effect
+ is relatively readable). */
+#ifdef UI_OUT
+ if (addressprint)
+ ui_out_field_skip (uiout, "addr");
+ annotate_field (5);
+ print_expression (b->exp, stb->stream);
+ ui_out_field_stream (uiout, "what", stb);
+#else
+ annotate_field (5);
+ print_expression (b->exp, gdb_stdout);
+#endif
+ break;
+
+ case bp_catch_load:
+ case bp_catch_unload:
+ /* Field 4, the address, is omitted (which makes the columns
+ not line up too nicely with the headers, but the effect
+ is relatively readable). */
+#ifdef UI_OUT
+ if (addressprint)
+ ui_out_field_skip (uiout, "addr");
+ annotate_field (5);
+ if (b->dll_pathname == NULL)
{
- annotate_breakpoints_headers ();
-
- annotate_field (0);
- printf_filtered ("Num ");
- annotate_field (1);
- printf_filtered ("Type ");
- annotate_field (2);
- printf_filtered ("Disp ");
- annotate_field (3);
- printf_filtered ("Enb ");
- if (addressprint)
- {
- annotate_field (4);
- printf_filtered ("Address ");
- }
- annotate_field (5);
- printf_filtered ("What\n");
-
- annotate_breakpoints_table ();
+ ui_out_field_string (uiout, "what", "<any library>");
+ ui_out_spaces (uiout, 1);
}
-
- annotate_record ();
- annotate_field (0);
- printf_filtered ("%-3d ", b->number);
- annotate_field (1);
- if ((int) b->type > (sizeof (bptypes) / sizeof (bptypes[0])))
- error ("bptypes table does not describe type #%d.", (int) b->type);
- if ((int) b->type != bptypes[(int) b->type].type)
- error ("bptypes table does not describe type #%d?", (int) b->type);
- printf_filtered ("%-14s ", bptypes[(int) b->type].description);
- annotate_field (2);
- printf_filtered ("%-4s ", bpdisps[(int) b->disposition]);
- annotate_field (3);
- printf_filtered ("%-3c ", bpenables[(int) b->enable]);
-
- strcpy (wrap_indent, " ");
+ else
+ {
+ ui_out_text (uiout, "library \"");
+ ui_out_field_string (uiout, "what", b->dll_pathname);
+ ui_out_text (uiout, "\" ");
+ }
+#else
+ annotate_field (5);
+ if (b->dll_pathname == NULL)
+ printf_filtered ("<any library> ");
+ else
+ printf_filtered ("library \"%s\" ", b->dll_pathname);
+#endif
+ break;
+
+ case bp_catch_fork:
+ case bp_catch_vfork:
+ /* Field 4, the address, is omitted (which makes the columns
+ not line up too nicely with the headers, but the effect
+ is relatively readable). */
+#ifdef UI_OUT
if (addressprint)
- strcat (wrap_indent, " ");
- switch (b->type)
+ ui_out_field_skip (uiout, "addr");
+ annotate_field (5);
+ if (b->forked_inferior_pid != 0)
{
- case bp_watchpoint:
- case bp_hardware_watchpoint:
- case bp_read_watchpoint:
- case bp_access_watchpoint:
- /* Field 4, the address, is omitted (which makes the columns
- not line up too nicely with the headers, but the effect
- is relatively readable). */
- annotate_field (5);
- print_expression (b->exp, gdb_stdout);
- break;
-
- case bp_catch_load:
- case bp_catch_unload:
- /* Field 4, the address, is omitted (which makes the columns
- not line up too nicely with the headers, but the effect
- is relatively readable). */
- annotate_field (5);
- if (b->dll_pathname == NULL)
- printf_filtered ("<any library> ");
- else
- printf_filtered ("library \"%s\" ", b->dll_pathname);
- break;
-
- case bp_catch_fork:
- case bp_catch_vfork:
- /* Field 4, the address, is omitted (which makes the columns
- not line up too nicely with the headers, but the effect
- is relatively readable). */
- annotate_field (5);
- if (b->forked_inferior_pid != 0)
- printf_filtered ("process %d ", b->forked_inferior_pid);
- break;
-
- case bp_catch_exec:
- /* Field 4, the address, is omitted (which makes the columns
- not line up too nicely with the headers, but the effect
- is relatively readable). */
- annotate_field (5);
- if (b->exec_pathname != NULL)
- printf_filtered ("program \"%s\" ", b->exec_pathname);
- break;
- case bp_catch_catch:
- /* Field 4, the address, is omitted (which makes the columns
- not line up too nicely with the headers, but the effect
- is relatively readable). */
- annotate_field (5);
- printf_filtered ("exception catch ");
- break;
- case bp_catch_throw:
- /* Field 4, the address, is omitted (which makes the columns
- not line up too nicely with the headers, but the effect
- is relatively readable). */
- annotate_field (5);
- printf_filtered ("exception throw ");
- break;
-
- case bp_breakpoint:
- case bp_hardware_breakpoint:
- case bp_until:
- case bp_finish:
- case bp_longjmp:
- case bp_longjmp_resume:
- case bp_step_resume:
- case bp_through_sigtramp:
- case bp_watchpoint_scope:
- case bp_call_dummy:
- case bp_shlib_event:
- if (addressprint)
- {
- annotate_field (4);
- /* FIXME-32x64: need a print_address_numeric with
- field width */
- printf_filtered
- ("%s ",
- local_hex_string_custom
- ((unsigned long) b->address, "08l"));
- }
+ ui_out_text (uiout, "process ");
+ ui_out_field_int (uiout, "what", b->forked_inferior_pid);
+ ui_out_spaces (uiout, 1);
+ }
+#else
+ annotate_field (5);
+ if (b->forked_inferior_pid != 0)
+ printf_filtered ("process %d ", b->forked_inferior_pid);
+ break;
+#endif
+
+ case bp_catch_exec:
+ /* Field 4, the address, is omitted (which makes the columns
+ not line up too nicely with the headers, but the effect
+ is relatively readable). */
+#ifdef UI_OUT
+ if (addressprint)
+ ui_out_field_skip (uiout, "addr");
+ annotate_field (5);
+ if (b->exec_pathname != NULL)
+ {
+ ui_out_text (uiout, "program \"");
+ ui_out_field_string (uiout, "what", b->exec_pathname);
+ ui_out_text (uiout, "\" ");
+ }
+#else
+ annotate_field (5);
+ if (b->exec_pathname != NULL)
+ printf_filtered ("program \"%s\" ", b->exec_pathname);
+#endif
+ break;
- annotate_field (5);
+ case bp_catch_catch:
+ /* Field 4, the address, is omitted (which makes the columns
+ not line up too nicely with the headers, but the effect
+ is relatively readable). */
+#ifdef UI_OUT
+ if (addressprint)
+ ui_out_field_skip (uiout, "addr");
+ annotate_field (5);
+ ui_out_field_string (uiout, "what", "exception catch");
+ ui_out_spaces (uiout, 1);
+#else
+ annotate_field (5);
+ printf_filtered ("exception catch ");
+#endif
+ break;
- last_addr = b->address;
- if (b->source_file)
+ case bp_catch_throw:
+ /* Field 4, the address, is omitted (which makes the columns
+ not line up too nicely with the headers, but the effect
+ is relatively readable). */
+#ifdef UI_OUT
+ if (addressprint)
+ ui_out_field_skip (uiout, "addr");
+ annotate_field (5);
+ ui_out_field_string (uiout, "what", "exception throw");
+ ui_out_spaces (uiout, 1);
+#else
+ annotate_field (5);
+ printf_filtered ("exception throw ");
+#endif
+ break;
+
+ case bp_breakpoint:
+ case bp_hardware_breakpoint:
+ case bp_until:
+ case bp_finish:
+ case bp_longjmp:
+ case bp_longjmp_resume:
+ case bp_step_resume:
+ case bp_through_sigtramp:
+ case bp_watchpoint_scope:
+ case bp_call_dummy:
+ case bp_shlib_event:
+ case bp_thread_event:
+#ifdef UI_OUT
+ if (addressprint)
+ {
+ annotate_field (4);
+ ui_out_field_core_addr (uiout, "addr", b->address);
+ }
+ annotate_field (5);
+ *last_addr = b->address;
+ if (b->source_file)
+ {
+ sym = find_pc_sect_function (b->address, b->section);
+ if (sym)
{
- sym = find_pc_sect_function (b->address, b->section);
- if (sym)
- {
- fputs_filtered ("in ", gdb_stdout);
- fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout);
- wrap_here (wrap_indent);
- fputs_filtered (" at ", gdb_stdout);
- }
- fputs_filtered (b->source_file, gdb_stdout);
- printf_filtered (":%d", b->line_number);
+ ui_out_text (uiout, "in ");
+ ui_out_field_string (uiout, "func",
+ SYMBOL_SOURCE_NAME (sym));
+ ui_out_wrap_hint (uiout, wrap_indent);
+ ui_out_text (uiout, " at ");
}
- else
- print_address_symbolic (b->address, gdb_stdout, demangle, " ");
- break;
+ ui_out_field_string (uiout, "file", b->source_file);
+ ui_out_text (uiout, ":");
+ ui_out_field_int (uiout, "line", b->line_number);
}
-
- if (b->thread != -1)
- printf_filtered (" thread %d", b->thread);
-
- printf_filtered ("\n");
-
- if (b->frame)
+ else
{
- annotate_field (6);
-
- printf_filtered ("\tstop only in stack frame at ");
- print_address_numeric (b->frame, 1, gdb_stdout);
- printf_filtered ("\n");
+ print_address_symbolic (b->address, stb->stream, demangle, "");
+ ui_out_field_stream (uiout, "at", stb);
}
-
- if (b->cond)
+#else
+ if (addressprint)
{
- annotate_field (7);
-
- printf_filtered ("\tstop only if ");
- print_expression (b->cond, gdb_stdout);
- printf_filtered ("\n");
+ annotate_field (4);
+ /* FIXME-32x64: need a print_address_numeric with
+ field width */
+ printf_filtered
+ ("%s ",
+ local_hex_string_custom
+ ((unsigned long) b->address, "08l"));
}
-
- if (b->thread != -1)
+ annotate_field (5);
+ *last_addr = b->address;
+ if (b->source_file)
{
- /* FIXME should make an annotation for this */
- printf_filtered ("\tstop only in thread %d\n", b->thread);
+ sym = find_pc_sect_function (b->address, b->section);
+ if (sym)
+ {
+ fputs_filtered ("in ", gdb_stdout);
+ fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout);
+ wrap_here (wrap_indent);
+ fputs_filtered (" at ", gdb_stdout);
+ }
+ fputs_filtered (b->source_file, gdb_stdout);
+ printf_filtered (":%d", b->line_number);
}
+ else
+ print_address_symbolic (b->address, gdb_stdout, demangle, " ");
+#endif
+ break;
+ }
+
+ if (b->thread != -1)
+ {
+#ifdef UI_OUT
+ /* FIXME: This seems to be redundant and lost here; see the
+ "stop only in" line a little further down. */
+ ui_out_text (uiout, " thread ");
+ ui_out_field_int (uiout, "thread", b->thread);
+#else
+ printf_filtered (" thread %d", b->thread);
+#endif
+ }
+
+#ifdef UI_OUT
+ ui_out_text (uiout, "\n");
+#else
+ printf_filtered ("\n");
+#endif
+
+ if (b->frame)
+ {
+ annotate_field (6);
+#ifdef UI_OUT
+ ui_out_text (uiout, "\tstop only in stack frame at ");
+ ui_out_field_core_addr (uiout, "frame", b->frame);
+ ui_out_text (uiout, "\n");
+#else
+ printf_filtered ("\tstop only in stack frame at ");
+ print_address_numeric (b->frame, 1, gdb_stdout);
+ printf_filtered ("\n");
+#endif
+ }
+
+ if (b->cond)
+ {
+ annotate_field (7);
+#ifdef UI_OUT
+ ui_out_text (uiout, "\tstop only if ");
+ print_expression (b->cond, stb->stream);
+ ui_out_field_stream (uiout, "cond", stb);
+ ui_out_text (uiout, "\n");
+#else
+ printf_filtered ("\tstop only if ");
+ print_expression (b->cond, gdb_stdout);
+ printf_filtered ("\n");
+#endif
+ }
+
+ if (b->thread != -1)
+ {
+ /* FIXME should make an annotation for this */
+#ifdef UI_OUT
+ ui_out_text (uiout, "\tstop only in thread ");
+ ui_out_field_int (uiout, "thread", b->thread);
+ ui_out_text (uiout, "\n");
+#else
+ printf_filtered ("\tstop only in thread %d\n", b->thread);
+#endif
+ }
+
+ if (show_breakpoint_hit_counts && b->hit_count)
+ {
+ /* FIXME should make an annotation for this */
+#ifdef UI_OUT
+ if (ep_is_catchpoint (b))
+ ui_out_text (uiout, "\tcatchpoint");
+ else
+ ui_out_text (uiout, "\tbreakpoint");
+ ui_out_text (uiout, " already hit ");
+ ui_out_field_int (uiout, "times", b->hit_count);
+ if (b->hit_count == 1)
+ ui_out_text (uiout, " time\n");
+ else
+ ui_out_text (uiout, " times\n");
+#else
+ if (ep_is_catchpoint (b))
+ printf_filtered ("\tcatchpoint");
+ else
+ printf_filtered ("\tbreakpoint");
+ printf_filtered (" already hit %d time%s\n",
+ b->hit_count, (b->hit_count == 1 ? "" : "s"));
+#endif
+ }
+
+#ifdef UI_OUT
+ /* Output the count also if it is zero, but only if this is
+ mi. FIXME: Should have a better test for this. */
+ if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+ if (show_breakpoint_hit_counts && b->hit_count == 0)
+ ui_out_field_int (uiout, "times", b->hit_count);
+#endif
- if (show_breakpoint_hit_counts && b->hit_count)
+ if (b->ignore_count)
+ {
+ annotate_field (8);
+#ifdef UI_OUT
+ ui_out_text (uiout, "\tignore next ");
+ ui_out_field_int (uiout, "ignore", b->ignore_count);
+ ui_out_text (uiout, " hits\n");
+#else
+ printf_filtered ("\tignore next %d hits\n", b->ignore_count);
+#endif
+ }
+
+ if ((l = b->commands))
+ {
+ annotate_field (9);
+#ifdef UI_OUT
+ ui_out_list_begin (uiout, "script");
+ print_command_lines (uiout, l, 4);
+ ui_out_list_end (uiout);
+#else
+ while (l)
{
- /* FIXME should make an annotation for this */
- if (ep_is_catchpoint (b))
- printf_filtered ("\tcatchpoint");
- else
- printf_filtered ("\tbreakpoint");
- printf_filtered (" already hit %d time%s\n",
- b->hit_count, (b->hit_count == 1 ? "" : "s"));
+ print_command_line (l, 4, gdb_stdout);
+ l = l->next;
}
+#endif
+ }
+#ifdef UI_OUT
+ ui_out_list_end (uiout);
+ do_cleanups (old_chain);
+#endif
+}
- if (b->ignore_count)
- {
- annotate_field (8);
-
- printf_filtered ("\tignore next %d hits\n", b->ignore_count);
- }
+struct captured_breakpoint_query_args
+ {
+ int bnum;
+ };
- if ((l = b->commands))
+static int
+do_captured_breakpoint_query (void *data)
+{
+ struct captured_breakpoint_query_args *args = data;
+ register struct breakpoint *b;
+ CORE_ADDR dummy_addr = 0;
+ ALL_BREAKPOINTS (b)
+ {
+ if (args->bnum == b->number)
{
- annotate_field (9);
-
- while (l)
- {
- print_command_line (l, 4, gdb_stdout);
- l = l->next;
- }
+ print_one_breakpoint (b, &dummy_addr);
+ return GDB_RC_OK;
}
}
+ return GDB_RC_NONE;
+}
+
+enum gdb_rc
+gdb_breakpoint_query (/* output object, */ int bnum)
+{
+ struct captured_breakpoint_query_args args;
+ args.bnum = bnum;
+ /* For the moment we don't trust print_one_breakpoint() to not throw
+ an error. */
+ return catch_errors (do_captured_breakpoint_query, &args,
+ NULL, RETURN_MASK_ALL);
+}
+
+/* Print information on breakpoint number BNUM, or -1 if all.
+ If WATCHPOINTS is zero, process only breakpoints; if WATCHPOINTS
+ is nonzero, process only watchpoints. */
+static void
+breakpoint_1 (int bnum, int allflag)
+{
+ register struct breakpoint *b;
+ CORE_ADDR last_addr = (CORE_ADDR) -1;
+ int found_a_breakpoint = 0;
+
+#ifdef UI_OUT
+ if (addressprint)
+ ui_out_table_begin (uiout, 6, "BreakpointTable");
+ else
+ ui_out_table_begin (uiout, 5, "BreakpointTable");
+#endif /* UI_OUT */
+
+ ALL_BREAKPOINTS (b)
+ if (bnum == -1
+ || bnum == b->number)
+ {
+ /* We only print out user settable breakpoints unless the
+ allflag is set. */
+ if (!allflag
+ && b->type != bp_breakpoint
+ && b->type != bp_catch_load
+ && b->type != bp_catch_unload
+ && b->type != bp_catch_fork
+ && b->type != bp_catch_vfork
+ && b->type != bp_catch_exec
+ && b->type != bp_catch_catch
+ && b->type != bp_catch_throw
+ && b->type != bp_hardware_breakpoint
+ && b->type != bp_watchpoint
+ && b->type != bp_read_watchpoint
+ && b->type != bp_access_watchpoint
+ && b->type != bp_hardware_watchpoint)
+ continue;
+
+ if (!found_a_breakpoint++)
+ {
+ annotate_breakpoints_headers ();
+#ifdef UI_OUT
+ annotate_field (0);
+ ui_out_table_header (uiout, 3, ui_left, "Num"); /* 1 */
+ annotate_field (1);
+ ui_out_table_header (uiout, 14, ui_left, "Type"); /* 2 */
+ annotate_field (2);
+ ui_out_table_header (uiout, 4, ui_left, "Disp"); /* 3 */
+ annotate_field (3);
+ ui_out_table_header (uiout, 3, ui_left, "Enb"); /* 4 */
+ if (addressprint)
+ {
+ annotate_field (4);
+ ui_out_table_header (uiout, 10, ui_left, "Address"); /* 5 */
+ }
+ annotate_field (5);
+ ui_out_table_header (uiout, 40, ui_noalign, "What"); /* 6 */
+ ui_out_table_body (uiout);
+#else
+ annotate_field (0);
+ printf_filtered ("Num ");
+ annotate_field (1);
+ printf_filtered ("Type ");
+ annotate_field (2);
+ printf_filtered ("Disp ");
+ annotate_field (3);
+ printf_filtered ("Enb ");
+ if (addressprint)
+ {
+ annotate_field (4);
+ printf_filtered ("Address ");
+ }
+ annotate_field (5);
+ printf_filtered ("What\n");
+#endif /* UI_OUT */
+ annotate_breakpoints_table ();
+ }
+
+ print_one_breakpoint (b, &last_addr);
+ }
+
if (!found_a_breakpoint)
{
+#ifdef UI_OUT
+ if (bnum == -1)
+ ui_out_message (uiout, 0, "No breakpoints or watchpoints.\n");
+ else
+ ui_out_message (uiout, 0, "No breakpoint or watchpoint number %d.\n",
+ bnum);
+#else
if (bnum == -1)
printf_filtered ("No breakpoints or watchpoints.\n");
else
printf_filtered ("No breakpoint or watchpoint number %d.\n", bnum);
+#endif /* UI_OUT */
}
else
- /* Compare against (CORE_ADDR)-1 in case some compiler decides
- that a comparison of an unsigned with -1 is always false. */
- if (last_addr != (CORE_ADDR) -1)
- set_next_address (last_addr);
+ {
+ /* Compare against (CORE_ADDR)-1 in case some compiler decides
+ that a comparison of an unsigned with -1 is always false. */
+ if (last_addr != (CORE_ADDR) -1)
+ set_next_address (last_addr);
+ }
+#ifdef UI_OUT
+ ui_out_table_end (uiout);
+#endif /* UI_OUT */
+ /* FIXME? Should this be moved up so that it is only called when
+ there have been breakpoints? */
annotate_breakpoints_table_end ();
}
/* ARGSUSED */
static void
-breakpoints_info (bnum_exp, from_tty)
- char *bnum_exp;
- int from_tty;
+breakpoints_info (char *bnum_exp, int from_tty)
{
int bnum = -1;
/* ARGSUSED */
static void
-maintenance_info_breakpoints (bnum_exp, from_tty)
- char *bnum_exp;
- int from_tty;
+maintenance_info_breakpoints (char *bnum_exp, int from_tty)
{
int bnum = -1;
/* Print a message describing any breakpoints set at PC. */
static void
-describe_other_breakpoints (pc, section)
- CORE_ADDR pc;
- asection *section;
+describe_other_breakpoints (CORE_ADDR pc, asection *section)
{
register int others = 0;
register struct breakpoint *b;
for the `break' command with no arguments. */
void
-set_default_breakpoint (valid, addr, symtab, line)
- int valid;
- CORE_ADDR addr;
- struct symtab *symtab;
- int line;
+set_default_breakpoint (int valid, CORE_ADDR addr, struct symtab *symtab,
+ int line)
{
default_breakpoint_valid = valid;
default_breakpoint_address = addr;
the official one, and the rest as duplicates. */
static void
-check_duplicates (address, section)
- CORE_ADDR address;
- asection *section;
+check_duplicates (CORE_ADDR address, asection *section)
{
register struct breakpoint *b;
register int count = 0;
your arguments BEFORE calling this routine! */
struct breakpoint *
-set_raw_breakpoint (sal)
- struct symtab_and_line sal;
+set_raw_breakpoint (struct symtab_and_line sal)
{
register struct breakpoint *b, *b1;
#ifdef GET_LONGJMP_TARGET
static void
-create_longjmp_breakpoint (func_name)
- char *func_name;
+create_longjmp_breakpoint (char *func_name)
{
struct symtab_and_line sal;
struct breakpoint *b;
set_longjmp_resume_breakpoint() to figure out where we are going. */
void
-enable_longjmp_breakpoint ()
+enable_longjmp_breakpoint (void)
{
register struct breakpoint *b;
}
void
-disable_longjmp_breakpoint ()
+disable_longjmp_breakpoint (void)
{
register struct breakpoint *b;
}
}
+struct breakpoint *
+create_thread_event_breakpoint (CORE_ADDR address)
+{
+ struct breakpoint *b;
+ struct symtab_and_line sal;
+ char addr_string[80]; /* Surely an addr can't be longer than that. */
+
+ INIT_SAL (&sal); /* initialize to zeroes */
+ sal.pc = address;
+ sal.section = find_pc_overlay (sal.pc);
+ if ((b = set_raw_breakpoint (sal)) == NULL)
+ return NULL;
+
+ b->number = internal_breakpoint_number--;
+ b->disposition = donttouch;
+ b->type = bp_thread_event; /* XXX: do we need a new type?
+ bp_thread_event */
+ b->enable = enabled;
+ /* addr_string has to be used or breakpoint_re_set will delete me. */
+ sprintf (addr_string, "*0x%s", paddr (b->address));
+ b->addr_string = strsave (addr_string);
+
+ return b;
+}
+
+void
+remove_thread_event_breakpoints (void)
+{
+ struct breakpoint *b, *temp;
+
+ ALL_BREAKPOINTS_SAFE (b, temp)
+ if (b->type == bp_thread_event)
+ delete_breakpoint (b);
+}
+
#ifdef SOLIB_ADD
void
-remove_solib_event_breakpoints ()
+remove_solib_event_breakpoints (void)
{
register struct breakpoint *b, *temp;
}
struct breakpoint *
-create_solib_event_breakpoint (address)
- CORE_ADDR address;
+create_solib_event_breakpoint (CORE_ADDR address)
{
struct breakpoint *b;
struct symtab_and_line sal;
apply to enabled breakpoints, disabled ones can just stay disabled. */
void
-disable_breakpoints_in_shlibs (silent)
- int silent;
+disable_breakpoints_in_shlibs (int silent)
{
struct breakpoint *b;
int disabled_shlib_breaks = 0;
/* Try to reenable any breakpoints in shared libraries. */
void
-re_enable_breakpoints_in_shlibs ()
+re_enable_breakpoints_in_shlibs (void)
{
struct breakpoint *b;
#endif
static void
-solib_load_unload_1 (hookname, tempflag, dll_pathname, cond_string, bp_kind)
- char *hookname;
- int tempflag;
- char *dll_pathname;
- char *cond_string;
- enum bptype bp_kind;
+solib_load_unload_1 (char *hookname, int tempflag, char *dll_pathname,
+ char *cond_string, enum bptype bp_kind)
{
struct breakpoint *b;
struct symtabs_and_lines sals;
}
void
-create_solib_load_event_breakpoint (hookname, tempflag,
- dll_pathname, cond_string)
- char *hookname;
- int tempflag;
- char *dll_pathname;
- char *cond_string;
+create_solib_load_event_breakpoint (char *hookname, int tempflag,
+ char *dll_pathname, char *cond_string)
{
solib_load_unload_1 (hookname, tempflag, dll_pathname,
cond_string, bp_catch_load);
}
void
-create_solib_unload_event_breakpoint (hookname, tempflag,
- dll_pathname, cond_string)
- char *hookname;
- int tempflag;
- char *dll_pathname;
- char *cond_string;
+create_solib_unload_event_breakpoint (char *hookname, int tempflag,
+ char *dll_pathname, char *cond_string)
{
solib_load_unload_1 (hookname,tempflag, dll_pathname,
cond_string, bp_catch_unload);
}
static void
-create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_kind)
- int tempflag;
- char *cond_string;
- enum bptype bp_kind;
+create_fork_vfork_event_catchpoint (int tempflag, char *cond_string,
+ enum bptype bp_kind)
{
struct symtab_and_line sal;
struct breakpoint *b;
}
void
-create_fork_event_catchpoint (tempflag, cond_string)
- int tempflag;
- char *cond_string;
+create_fork_event_catchpoint (int tempflag, char *cond_string)
{
create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_catch_fork);
}
void
-create_vfork_event_catchpoint (tempflag, cond_string)
- int tempflag;
- char *cond_string;
+create_vfork_event_catchpoint (int tempflag, char *cond_string)
{
create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_catch_vfork);
}
void
-create_exec_event_catchpoint (tempflag, cond_string)
- int tempflag;
- char *cond_string;
+create_exec_event_catchpoint (int tempflag, char *cond_string)
{
struct symtab_and_line sal;
struct breakpoint *b;
}
static int
-hw_breakpoint_used_count ()
+hw_breakpoint_used_count (void)
{
register struct breakpoint *b;
int i = 0;
}
static int
-hw_watchpoint_used_count (type, other_type_used)
- enum bptype type;
- int *other_type_used;
+hw_watchpoint_used_count (enum bptype type, int *other_type_used)
{
register struct breakpoint *b;
int i = 0;
that gets deleted automatically... */
void
-set_longjmp_resume_breakpoint (pc, frame)
- CORE_ADDR pc;
- struct frame_info *frame;
+set_longjmp_resume_breakpoint (CORE_ADDR pc, struct frame_info *frame)
{
register struct breakpoint *b;
}
void
-disable_watchpoints_before_interactive_call_start ()
+disable_watchpoints_before_interactive_call_start (void)
{
struct breakpoint *b;
}
void
-enable_watchpoints_after_interactive_call_stop ()
+enable_watchpoints_after_interactive_call_stop (void)
{
struct breakpoint *b;
Restrict it to frame FRAME if FRAME is nonzero. */
struct breakpoint *
-set_momentary_breakpoint (sal, frame, type)
- struct symtab_and_line sal;
- struct frame_info *frame;
- enum bptype type;
+set_momentary_breakpoint (struct symtab_and_line sal, struct frame_info *frame,
+ enum bptype type)
{
register struct breakpoint *b;
b = set_raw_breakpoint (sal);
/* Tell the user we have just set a breakpoint B. */
static void
-mention (b)
- struct breakpoint *b;
+mention (struct breakpoint *b)
{
int say_where = 0;
+#ifdef UI_OUT
+ struct cleanup *old_chain;
+ struct ui_stream *stb;
+
+ stb = ui_out_stream_new (uiout);
+ old_chain = make_cleanup_ui_out_stream_delete (stb);
+#endif /* UI_OUT */
/* FIXME: This is misplaced; mention() is called by things (like hitting a
watchpoint) other than breakpoint creation. It should be possible to
case bp_none:
printf_filtered ("(apparently deleted?) Eventpoint %d: ", b->number);
break;
+#ifdef UI_OUT
+ case bp_watchpoint:
+ ui_out_text (uiout, "Watchpoint ");
+ ui_out_list_begin (uiout, "wpt");
+ ui_out_field_int (uiout, "number", b->number);
+ ui_out_text (uiout, ": ");
+ print_expression (b->exp, stb->stream);
+ ui_out_field_stream (uiout, "exp", stb);
+ ui_out_list_end (uiout);
+ break;
+ case bp_hardware_watchpoint:
+ ui_out_text (uiout, "Hardware watchpoint ");
+ ui_out_list_begin (uiout, "wpt");
+ ui_out_field_int (uiout, "number", b->number);
+ ui_out_text (uiout, ": ");
+ print_expression (b->exp, stb->stream);
+ ui_out_field_stream (uiout, "exp", stb);
+ ui_out_list_end (uiout);
+ break;
+#else
case bp_watchpoint:
printf_filtered ("Watchpoint %d: ", b->number);
print_expression (b->exp, gdb_stdout);
printf_filtered ("Hardware watchpoint %d: ", b->number);
print_expression (b->exp, gdb_stdout);
break;
+#endif
+#ifdef UI_OUT
+ case bp_read_watchpoint:
+ ui_out_text (uiout, "Hardware read watchpoint ");
+ ui_out_list_begin (uiout, "hw-rwpt");
+ ui_out_field_int (uiout, "number", b->number);
+ ui_out_text (uiout, ": ");
+ print_expression (b->exp, stb->stream);
+ ui_out_field_stream (uiout, "exp", stb);
+ ui_out_list_end (uiout);
+ break;
+ case bp_access_watchpoint:
+ ui_out_text (uiout, "Hardware access (read/write) watchpoint ");
+ ui_out_list_begin (uiout, "hw-awpt");
+ ui_out_field_int (uiout, "number", b->number);
+ ui_out_text (uiout, ": ");
+ print_expression (b->exp, stb->stream);
+ ui_out_field_stream (uiout, "exp", stb);
+ ui_out_list_end (uiout);
+ break;
+#else
case bp_read_watchpoint:
printf_filtered ("Hardware read watchpoint %d: ", b->number);
print_expression (b->exp, gdb_stdout);
b->number);
print_expression (b->exp, gdb_stdout);
break;
+#endif
case bp_breakpoint:
+#ifdef UI_OUT
+ if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+ {
+ say_where = 0;
+ break;
+ }
+#endif
printf_filtered ("Breakpoint %d", b->number);
say_where = 1;
break;
case bp_hardware_breakpoint:
+#ifdef UI_OUT
+ if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+ {
+ say_where = 0;
+ break;
+ }
+#endif
printf_filtered ("Hardware assisted breakpoint %d", b->number);
say_where = 1;
break;
case bp_call_dummy:
case bp_watchpoint_scope:
case bp_shlib_event:
+ case bp_thread_event:
break;
}
if (say_where)
TUIDO (((TuiOpaqueFuncPtr) tui_vAllSetHasBreakAt, b, 1));
TUIDO (((TuiOpaqueFuncPtr) tuiUpdateAllExecInfos));
}
+#ifdef UI_OUT
+ do_cleanups (old_chain);
+#endif
+#ifdef UI_OUT
+ if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+ return;
+#endif
printf_filtered ("\n");
}
\f
-/* Set a breakpoint according to ARG (function, linenum or *address)
- flag: first bit : 0 non-temporary, 1 temporary.
- second bit : 0 normal breakpoint, 1 hardware breakpoint. */
+/* Add SALS.nelts breakpoints to the breakpoint table. For each
+ SALS.sal[i] breakpoint, include the corresponding ADDR_STRING[i],
+ COND[i] and COND_STRING[i] values.
+
+ NOTE: If the function succeeds, the caller is expected to cleanup
+ the arrays ADDR_STRING, COND_STRING, COND and SALS (but not the
+ array contents). If the function fails (error() is called), the
+ caller is expected to cleanups both the ADDR_STRING, COND_STRING,
+ COND and SALS arrays and each of those arrays contents. */
static void
-break_command_1 (arg, flag, from_tty)
- char *arg;
- int flag, from_tty;
+create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
+ struct expression **cond, char **cond_string,
+ enum bptype type, enum bpdisp disposition,
+ int thread, int ignore_count, int from_tty)
{
- int tempflag, hardwareflag;
- struct symtabs_and_lines sals;
- struct symtab_and_line sal;
- register struct expression *cond = 0;
- register struct breakpoint *b;
-
- /* Pointers in arg to the start, and one past the end, of the condition. */
- char *cond_start = NULL;
- 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 = NULL;
- struct cleanup *old_chain;
- struct cleanup *canonical_strings_chain = NULL;
- char **canonical = (char **) NULL;
- int i;
- int thread;
-
- hardwareflag = flag & BP_HARDWAREFLAG;
- tempflag = flag & BP_TEMPFLAG;
+ if (type == bp_hardware_breakpoint)
+ {
+ int i = hw_breakpoint_used_count ();
+ int target_resources_ok =
+ TARGET_CAN_USE_HARDWARE_WATCHPOINT (bp_hardware_breakpoint,
+ i + sals.nelts, 0);
+ if (target_resources_ok == 0)
+ error ("No hardware breakpoint support in the target.");
+ else if (target_resources_ok < 0)
+ error ("Hardware breakpoints used exceeds limit.");
+ }
- sals.sals = NULL;
- sals.nelts = 0;
+ /* Now set all the breakpoints. */
+ {
+ int i;
+ for (i = 0; i < sals.nelts; i++)
+ {
+ struct breakpoint *b;
+ struct symtab_and_line sal = sals.sals[i];
- INIT_SAL (&sal); /* initialize to zeroes */
+ if (from_tty)
+ describe_other_breakpoints (sal.pc, sal.section);
+
+ b = set_raw_breakpoint (sal);
+ set_breakpoint_count (breakpoint_count + 1);
+ b->number = breakpoint_count;
+ b->type = type;
+ b->cond = cond[i];
+ b->thread = thread;
+ b->addr_string = addr_string[i];
+ b->cond_string = cond_string[i];
+ b->ignore_count = ignore_count;
+ b->enable = enabled;
+ b->disposition = disposition;
+ mention (b);
+ }
+ }
+}
- /* If no arg given, or if first arg is 'if ', use the default breakpoint. */
+/* Parse ARG which is assumed to be a SAL specification possibly
+ followed by conditionals. On return, SALS contains an array of SAL
+ addresses found. ADDR_STRING contains a vector of (canonical)
+ address strings. ARG points to the end of the SAL. */
- if (!arg || (arg[0] == 'i' && arg[1] == 'f'
- && (arg[2] == ' ' || arg[2] == '\t')))
+void
+parse_breakpoint_sals (char **address,
+ struct symtabs_and_lines *sals,
+ char ***addr_string)
+{
+ char *addr_start = *address;
+ *addr_string = NULL;
+ /* If no arg given, or if first arg is 'if ', use the default
+ breakpoint. */
+ if ((*address) == NULL
+ || (strncmp ((*address), "if", 2) == 0 && isspace ((*address)[2])))
{
if (default_breakpoint_valid)
{
- sals.sals = (struct symtab_and_line *)
+ struct symtab_and_line sal;
+ INIT_SAL (&sal); /* initialize to zeroes */
+ sals->sals = (struct symtab_and_line *)
xmalloc (sizeof (struct symtab_and_line));
sal.pc = default_breakpoint_address;
sal.line = default_breakpoint_line;
sal.symtab = default_breakpoint_symtab;
sal.section = find_pc_overlay (sal.pc);
- sals.sals[0] = sal;
- sals.nelts = 1;
+ sals->sals[0] = sal;
+ sals->nelts = 1;
}
else
error ("No default breakpoint address now.");
}
else
{
- addr_start = arg;
-
/* Force almost all breakpoints to be in terms of the
current_source_symtab (which is decode_line_1's default). This
should produce the results we want almost all of the time while
leaving default_breakpoint_* alone. */
if (default_breakpoint_valid
&& (!current_source_symtab
- || (arg && (*arg == '+' || *arg == '-'))))
- sals = decode_line_1 (&arg, 1, default_breakpoint_symtab,
- default_breakpoint_line, &canonical);
+ || (strchr ("+-", (*address)[0]) != NULL)))
+ *sals = decode_line_1 (address, 1, default_breakpoint_symtab,
+ default_breakpoint_line, addr_string);
else
- sals = decode_line_1 (&arg, 1, (struct symtab *) NULL, 0, &canonical);
-
- addr_end = arg;
+ *sals = decode_line_1 (address, 1, (struct symtab *) NULL, 0, addr_string);
}
-
- if (!sals.nelts)
- return;
-
- /* Make sure that all storage allocated in decode_line_1 gets freed
- in case the following `for' loop errors out. */
- old_chain = make_cleanup (free, sals.sals);
- if (canonical != (char **) NULL)
+ /* For any SAL that didn't have a canonical string, fill one in. */
+ if (sals->nelts > 0 && *addr_string == NULL)
+ *addr_string = xcalloc (sals->nelts, sizeof (char **));
+ if (addr_start != (*address))
{
- make_cleanup (free, canonical);
- canonical_strings_chain = make_cleanup (null_cleanup, 0);
- for (i = 0; i < sals.nelts; i++)
+ int i;
+ for (i = 0; i < sals->nelts; i++)
{
- if (canonical[i] != NULL)
- make_cleanup (free, canonical[i]);
+ /* Add the string if not present. */
+ if ((*addr_string)[i] == NULL)
+ (*addr_string)[i] = savestring (addr_start, (*address) - addr_start);
}
}
+}
- thread = -1; /* No specific thread yet */
- /* Resolve all line numbers to PC's, and verify that conditions
- can be parsed, before setting any breakpoints. */
- for (i = 0; i < sals.nelts; i++)
- {
- char *tok, *end_tok;
- int toklen;
+/* Convert each SAL into a real PC. Verify that the PC can be
+ inserted as a breakpoint. If it can't throw an error. */
- resolve_sal_pc (&sals.sals[i]);
+void
+breakpoint_sals_to_pc (struct symtabs_and_lines *sals,
+ char *address)
+{
+ int i;
+ for (i = 0; i < sals->nelts; i++)
+ {
+ resolve_sal_pc (&sals->sals[i]);
/* It's possible for the PC to be nonzero, but still an illegal
value on some targets.
Give the target a chance to bless sals.sals[i].pc before we
try to make a breakpoint for it. */
- if (PC_REQUIRES_RUN_BEFORE_USE (sals.sals[i].pc))
+ if (PC_REQUIRES_RUN_BEFORE_USE (sals->sals[i].pc))
{
- error ("Cannot break on %s without a running program.",
- addr_start);
+ if (address == NULL)
+ error ("Cannot break without a running program.");
+ else
+ error ("Cannot break on %s without a running program.",
+ address);
}
+ }
+}
+
+/* Set a breakpoint according to ARG (function, linenum or *address)
+ flag: first bit : 0 non-temporary, 1 temporary.
+ second bit : 0 normal breakpoint, 1 hardware breakpoint. */
+
+static void
+break_command_1 (char *arg, int flag, int from_tty)
+{
+ int tempflag, hardwareflag;
+ struct symtabs_and_lines sals;
+ register struct expression **cond = 0;
+ /* Pointers in arg to the start, and one past the end, of the
+ condition. */
+ char **cond_string = (char **) NULL;
+ char *addr_start = arg;
+ char **addr_string;
+ struct cleanup *old_chain;
+ struct cleanup *breakpoint_chain = NULL;
+ int i;
+ int thread = -1;
+ int ignore_count = 0;
+
+ hardwareflag = flag & BP_HARDWAREFLAG;
+ tempflag = flag & BP_TEMPFLAG;
+
+ sals.sals = NULL;
+ sals.nelts = 0;
+ addr_string = NULL;
+ parse_breakpoint_sals (&arg, &sals, &addr_string);
+
+ if (!sals.nelts)
+ return;
+
+ /* Create a chain of things that always need to be cleaned up. */
+ old_chain = make_cleanup (null_cleanup, 0);
+
+ /* Make sure that all storage allocated to SALS gets freed. */
+ make_cleanup (free, sals.sals);
+
+ /* Cleanup the addr_string array but not its contents. */
+ make_cleanup (free, addr_string);
- tok = arg;
+ /* Allocate space for all the cond expressions. */
+ cond = xcalloc (sals.nelts, sizeof (struct expression *));
+ make_cleanup (free, cond);
+ /* Allocate space for all the cond strings. */
+ cond_string = xcalloc (sals.nelts, sizeof (char **));
+ make_cleanup (free, cond_string);
+
+ /* ----------------------------- SNIP -----------------------------
+ Anything added to the cleanup chain beyond this point is assumed
+ to be part of a breakpoint. If the breakpoint create succeeds
+ then the memory is not reclaimed. */
+ breakpoint_chain = make_cleanup (null_cleanup, 0);
+
+ /* Mark the contents of the addr_string for cleanup. These go on
+ the breakpoint_chain and only occure if the breakpoint create
+ fails. */
+ for (i = 0; i < sals.nelts; i++)
+ {
+ if (addr_string[i] != NULL)
+ make_cleanup (free, addr_string[i]);
+ }
+
+ /* Resolve all line numbers to PC's and verify that the addresses
+ are ok for the target. */
+ breakpoint_sals_to_pc (&sals, addr_start);
+
+ /* Verify that condition can be parsed, before setting any
+ breakpoints. Allocate a separate condition expression for each
+ breakpoint. */
+ thread = -1; /* No specific thread yet */
+ for (i = 0; i < sals.nelts; i++)
+ {
+ char *tok = arg;
while (tok && *tok)
{
+ char *end_tok;
+ int toklen;
+ char *cond_start = NULL;
+ char *cond_end = NULL;
while (*tok == ' ' || *tok == '\t')
tok++;
if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
{
tok = cond_start = end_tok + 1;
- cond = parse_exp_1 (&tok, block_for_pc (sals.sals[i].pc), 0);
+ cond[i] = parse_exp_1 (&tok, block_for_pc (sals.sals[i].pc), 0);
+ make_cleanup (free, cond[i]);
cond_end = tok;
+ cond_string[i] = savestring (cond_start, cond_end - cond_start);
+ make_cleanup (free, cond_string[i]);
}
else if (toklen >= 1 && strncmp (tok, "thread", toklen) == 0)
{
error ("Junk at end of arguments.");
}
}
- if (hardwareflag)
- {
- int i, target_resources_ok;
- i = hw_breakpoint_used_count ();
- target_resources_ok =
- TARGET_CAN_USE_HARDWARE_WATCHPOINT (bp_hardware_breakpoint,
- i + sals.nelts, 0);
- if (target_resources_ok == 0)
- error ("No hardware breakpoint support in the target.");
- else if (target_resources_ok < 0)
- error ("Hardware breakpoints used exceeds limit.");
+ create_breakpoints (sals, addr_string, cond, cond_string,
+ hardwareflag ? bp_hardware_breakpoint : bp_breakpoint,
+ tempflag ? del : donttouch,
+ thread, ignore_count, from_tty);
+
+ if (sals.nelts > 1)
+ {
+ warning ("Multiple breakpoints were set.");
+ warning ("Use the \"delete\" command to delete unwanted breakpoints.");
}
+ /* That's it. Discard the cleanups for data inserted into the
+ breakpoint. */
+ discard_cleanups (breakpoint_chain);
+ /* But cleanup everything else. */
+ do_cleanups (old_chain);
+}
- /* Remove the canonical strings from the cleanup, they are needed below. */
- if (canonical != (char **) NULL)
- discard_cleanups (canonical_strings_chain);
+/* Set a breakpoint of TYPE/DISPOSITION according to ARG (function,
+ linenum or *address) with COND and IGNORE_COUNT. */
- /* Now set all the breakpoints. */
- for (i = 0; i < sals.nelts; i++)
- {
- sal = sals.sals[i];
+struct captured_breakpoint_args
+ {
+ char *address;
+ char *condition;
+ int hardwareflag;
+ int tempflag;
+ int thread;
+ int ignore_count;
+ };
- if (from_tty)
- describe_other_breakpoints (sal.pc, sal.section);
+static int
+do_captured_breakpoint (void *data)
+{
+ struct captured_breakpoint_args *args = data;
+ struct symtabs_and_lines sals;
+ register struct expression **cond;
+ struct cleanup *old_chain;
+ struct cleanup *breakpoint_chain = NULL;
+ int i;
+ char **addr_string;
+ char **cond_string;
- b = set_raw_breakpoint (sal);
- set_breakpoint_count (breakpoint_count + 1);
- b->number = breakpoint_count;
- b->type = hardwareflag ? bp_hardware_breakpoint : bp_breakpoint;
- b->cond = cond;
- b->thread = thread;
+ char *address_end;
+
+ /* Parse the source and lines spec. Delay check that the expression
+ didn't contain trailing garbage until after cleanups are in
+ place. */
+ sals.sals = NULL;
+ sals.nelts = 0;
+ address_end = args->address;
+ addr_string = NULL;
+ parse_breakpoint_sals (&address_end, &sals, &addr_string);
- /* If a canonical line spec is needed use that instead of the
- command string. */
- if (canonical != (char **) NULL && canonical[i] != NULL)
- b->addr_string = canonical[i];
- else if (addr_start)
- b->addr_string = savestring (addr_start, addr_end - addr_start);
- if (cond_start)
- b->cond_string = savestring (cond_start, cond_end - cond_start);
+ if (!sals.nelts)
+ return GDB_RC_NONE;
- b->enable = enabled;
- b->disposition = tempflag ? del : donttouch;
- mention (b);
+ /* Create a chain of things at always need to be cleaned up. */
+ old_chain = make_cleanup (null_cleanup, 0);
+
+ /* Always have a addr_string array, even if it is empty. */
+ make_cleanup (free, addr_string);
+
+ /* Make sure that all storage allocated to SALS gets freed. */
+ make_cleanup (free, sals.sals);
+
+ /* Allocate space for all the cond expressions. */
+ cond = xcalloc (sals.nelts, sizeof (struct expression *));
+ make_cleanup (free, cond);
+
+ /* Allocate space for all the cond strings. */
+ cond_string = xcalloc (sals.nelts, sizeof (char **));
+ make_cleanup (free, cond_string);
+
+ /* ----------------------------- SNIP -----------------------------
+ Anything added to the cleanup chain beyond this point is assumed
+ to be part of a breakpoint. If the breakpoint create goes
+ through then that memory is not cleaned up. */
+ breakpoint_chain = make_cleanup (null_cleanup, 0);
+
+ /* Mark the contents of the addr_string for cleanup. These go on
+ the breakpoint_chain and only occure if the breakpoint create
+ fails. */
+ for (i = 0; i < sals.nelts; i++)
+ {
+ if (addr_string[i] != NULL)
+ make_cleanup (free, addr_string[i]);
}
- if (sals.nelts > 1)
+ /* Wait until now before checking for garbage at the end of the
+ address. That way cleanups can take care of freeing any
+ memory. */
+ if (*address_end != '\0')
+ error ("Garbage %s following breakpoint address", address_end);
+
+ /* Resolve all line numbers to PC's. */
+ breakpoint_sals_to_pc (&sals, args->address);
+
+ /* Verify that conditions can be parsed, before setting any
+ breakpoints. */
+ for (i = 0; i < sals.nelts; i++)
{
- warning ("Multiple breakpoints were set.");
- warning ("Use the \"delete\" command to delete unwanted breakpoints.");
+ if (args->condition != NULL)
+ {
+ char *tok = args->condition;
+ cond[i] = parse_exp_1 (&tok, block_for_pc (sals.sals[i].pc), 0);
+ if (*tok != '\0')
+ error ("Garbage %s follows condition", tok);
+ make_cleanup (free, cond[i]);
+ cond_string[i] = xstrdup (args->condition);
+ }
}
+
+ create_breakpoints (sals, addr_string, cond, cond_string,
+ args->hardwareflag ? bp_hardware_breakpoint : bp_breakpoint,
+ args->tempflag ? del : donttouch,
+ args->thread, args->ignore_count, 0/*from-tty*/);
+
+ /* That's it. Discard the cleanups for data inserted into the
+ breakpoint. */
+ discard_cleanups (breakpoint_chain);
+ /* But cleanup everything else. */
do_cleanups (old_chain);
+ return GDB_RC_OK;
+}
+
+enum gdb_rc
+gdb_breakpoint (char *address, char *condition,
+ int hardwareflag, int tempflag,
+ int thread, int ignore_count)
+{
+ struct captured_breakpoint_args args;
+ args.address = address;
+ args.condition = condition;
+ args.hardwareflag = hardwareflag;
+ args.tempflag = tempflag;
+ args.thread = thread;
+ args.ignore_count = ignore_count;
+ return catch_errors (do_captured_breakpoint, &args,
+ NULL, RETURN_MASK_ALL);
}
+
static void
-break_at_finish_at_depth_command_1 (arg, flag, from_tty)
- char *arg;
- int flag;
- int from_tty;
+break_at_finish_at_depth_command_1 (char *arg, int flag, int from_tty)
{
struct frame_info *frame;
CORE_ADDR low, high, selected_pc = 0;
static void
-break_at_finish_command_1 (arg, flag, from_tty)
- char *arg;
- int flag;
- int from_tty;
+break_at_finish_command_1 (char *arg, int flag, int from_tty)
{
char *addr_string, *break_string, *beg_addr_string;
CORE_ADDR low, high;
/* Helper function for break_command_1 and disassemble_command. */
void
-resolve_sal_pc (sal)
- struct symtab_and_line *sal;
+resolve_sal_pc (struct symtab_and_line *sal)
{
CORE_ADDR pc;
}
void
-break_command (arg, from_tty)
- char *arg;
- int from_tty;
+break_command (char *arg, int from_tty)
{
break_command_1 (arg, 0, from_tty);
}
static void
-break_at_finish_command (arg, from_tty)
- char *arg;
- int from_tty;
+break_at_finish_command (char *arg, int from_tty)
{
break_at_finish_command_1 (arg, 0, from_tty);
}
static void
-break_at_finish_at_depth_command (arg, from_tty)
- char *arg;
- int from_tty;
+break_at_finish_at_depth_command (char *arg, int from_tty)
{
break_at_finish_at_depth_command_1 (arg, 0, from_tty);
}
void
-tbreak_command (arg, from_tty)
- char *arg;
- int from_tty;
+tbreak_command (char *arg, int from_tty)
{
break_command_1 (arg, BP_TEMPFLAG, from_tty);
}
static void
-tbreak_at_finish_command (arg, from_tty)
- char *arg;
- int from_tty;
+tbreak_at_finish_command (char *arg, int from_tty)
{
break_at_finish_command_1 (arg, BP_TEMPFLAG, from_tty);
}
static void
-hbreak_command (arg, from_tty)
- char *arg;
- int from_tty;
+hbreak_command (char *arg, int from_tty)
{
break_command_1 (arg, BP_HARDWAREFLAG, from_tty);
}
static void
-thbreak_command (arg, from_tty)
- char *arg;
- int from_tty;
+thbreak_command (char *arg, int from_tty)
{
break_command_1 (arg, (BP_TEMPFLAG | BP_HARDWAREFLAG), from_tty);
}
static void
-stop_command (arg, from_tty)
- char *arg;
- int from_tty;
+stop_command (char *arg, int from_tty)
{
printf_filtered ("Specify the type of breakpoint to set.\n\
Usage: stop in <function | address>\n\
}
static void
-stopin_command (arg, from_tty)
- char *arg;
- int from_tty;
+stopin_command (char *arg, int from_tty)
{
int badInput = 0;
}
static void
-stopat_command (arg, from_tty)
- char *arg;
- int from_tty;
+stopat_command (char *arg, int from_tty)
{
int badInput = 0;
hw_read: watch read,
hw_access: watch access (read or write) */
static void
-watch_command_1 (arg, accessflag, from_tty)
- char *arg;
- int accessflag;
- int from_tty;
+watch_command_1 (char *arg, int accessflag, int from_tty)
{
struct breakpoint *b;
struct symtab_and_line sal;
#endif
static int
-can_use_hardware_watchpoint (v)
- struct value *v;
+can_use_hardware_watchpoint (struct value *v)
{
int found_memory_cnt = 0;
+ struct value *head = v;
/* Did the user specifically forbid us to use hardware watchpoints? */
if (!can_use_hw_watchpoints)
{
/* Ahh, memory we actually used! Check if we can cover
it with hardware watchpoints. */
- CORE_ADDR vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
- int len = TYPE_LENGTH (VALUE_TYPE (v));
+ struct type *vtype = check_typedef (VALUE_TYPE (v));
+
+ /* We only watch structs and arrays if user asked for it
+ explicitly, never if they just happen to appear in a
+ middle of some value chain. */
+ if (v == head
+ || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
+ && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
+ {
+ CORE_ADDR vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+ int len = TYPE_LENGTH (VALUE_TYPE (v));
- if (!TARGET_REGION_OK_FOR_HW_WATCHPOINT (vaddr, len))
- return 0;
- else
- found_memory_cnt++;
+ if (!TARGET_REGION_OK_FOR_HW_WATCHPOINT (vaddr, len))
+ return 0;
+ else
+ found_memory_cnt++;
+ }
}
}
else if (v->lval != not_lval && v->modifiable == 0)
return found_memory_cnt;
}
+#ifdef UI_OUT
+void
+watch_command_wrapper (char *arg, int from_tty)
+{
+ watch_command (arg, from_tty);
+}
+#endif
static void
-watch_command (arg, from_tty)
- char *arg;
- int from_tty;
+watch_command (char *arg, int from_tty)
{
watch_command_1 (arg, hw_write, from_tty);
}
+#ifdef UI_OUT
+void
+rwatch_command_wrapper (char *arg, int from_tty)
+{
+ rwatch_command (arg, from_tty);
+}
+#endif
static void
-rwatch_command (arg, from_tty)
- char *arg;
- int from_tty;
+rwatch_command (char *arg, int from_tty)
{
watch_command_1 (arg, hw_read, from_tty);
}
+#ifdef UI_OUT
+void
+awatch_command_wrapper (char *arg, int from_tty)
+{
+ awatch_command (arg, from_tty);
+}
+#endif
static void
-awatch_command (arg, from_tty)
- char *arg;
- int from_tty;
+awatch_command (char *arg, int from_tty)
{
watch_command_1 (arg, hw_access, from_tty);
}
static void
until_break_command_continuation (struct continuation_arg *arg)
{
- /* Do all the exec cleanups, which at this point should only be the
- one set up in the first part of the until_break_command
- function. */
- do_exec_cleanups (ALL_CLEANUPS);
+ struct cleanup *cleanups;
+
+ cleanups = (struct cleanup *) arg->data.pointer;
+ do_exec_cleanups (cleanups);
}
/* ARGSUSED */
void
-until_break_command (arg, from_tty)
- char *arg;
- int from_tty;
+until_break_command (char *arg, int from_tty)
{
struct symtabs_and_lines sals;
struct symtab_and_line sal;
struct frame_info *prev_frame = get_prev_frame (selected_frame);
struct breakpoint *breakpoint;
struct cleanup *old_chain;
+ struct continuation_arg *arg1;
+
clear_proceed_status ();
breakpoint = set_momentary_breakpoint (sal, selected_frame, bp_until);
if (!event_loop_p || !target_can_async_p ())
- old_chain = make_cleanup ((make_cleanup_func) delete_breakpoint,
- breakpoint);
+ old_chain = make_cleanup_delete_breakpoint (breakpoint);
else
- make_exec_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
+ old_chain = make_exec_cleanup_delete_breakpoint (breakpoint);
/* If we are running asynchronously, and the target supports async
execution, we are not waiting for the target to stop, in the call
if (event_loop_p && target_can_async_p ())
{
- /* In this case we don't need args for the continuation, because
- all it needs to do is do the cleanups in the
- exec_cleanup_chain, which will be only those inserted by this
- function. We can get away by using ALL_CLEANUPS. */
- add_continuation (until_break_command_continuation, NULL);
+ /* In this case the arg for the continuation is just the point
+ in the exec_cleanups chain from where to start doing
+ cleanups, because all the continuation does is the cleanups in
+ the exec_cleanup_chain. */
+ arg1 =
+ (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
+ arg1->next = NULL;
+ arg1->data.pointer = old_chain;
+
+ add_continuation (until_break_command_continuation, arg1);
}
/* Keep within the current frame */
sal.pc = prev_frame->pc;
breakpoint = set_momentary_breakpoint (sal, prev_frame, bp_until);
if (!event_loop_p || !target_can_async_p ())
- make_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
+ make_cleanup_delete_breakpoint (breakpoint);
else
- make_exec_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
+ make_exec_cleanup_delete_breakpoint (breakpoint);
}
proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
/* These aren't used; I don't konw what they were for. */
/* Set a breakpoint at the catch clause for NAME. */
static int
-catch_breakpoint (name)
- char *name;
+catch_breakpoint (char *name)
{
}
static int
-disable_catch_breakpoint ()
+disable_catch_breakpoint (void)
{
}
static int
-delete_catch_breakpoint ()
+delete_catch_breakpoint (void)
{
}
static int
-enable_catch_breakpoint ()
+enable_catch_breakpoint (void)
{
}
#endif /* 0 */
/* For each catch clause identified in ARGS, run FUNCTION
with that clause as an argument. */
static struct symtabs_and_lines
-map_catch_names (args, function)
- char *args;
- int (*function) ();
+map_catch_names (char *args, int (*function) ())
{
register char *p = args;
register char *p1;
/* This shares a lot of code with `print_frame_label_vars' from stack.c. */
static struct symtabs_and_lines
-get_catch_sals (this_level_only)
- int this_level_only;
+get_catch_sals (int this_level_only)
{
register struct blockvector *bl;
register struct block *block;
}
static void
-ep_skip_leading_whitespace (s)
- char **s;
+ep_skip_leading_whitespace (char **s)
{
if ((s == NULL) || (*s == NULL))
return;
the token is returned. Else, NULL is returned. */
static char *
-ep_find_event_name_end (arg)
- char *arg;
+ep_find_event_name_end (char *arg)
{
char *s = arg;
char *event_name_end = NULL;
if clause in the arg string. */
static char *
-ep_parse_optional_if_clause (arg)
- char **arg;
+ep_parse_optional_if_clause (char **arg)
{
char *cond_string;
Note that clients needing to preserve the returned filename for
future access should copy it to their own buffers. */
static char *
-ep_parse_optional_filename (arg)
- char **arg;
+ep_parse_optional_filename (char **arg)
{
static char filename[1024];
char *arg_p = *arg;
catch_fork_kind;
#if defined(CHILD_INSERT_FORK_CATCHPOINT) || defined(CHILD_INSERT_VFORK_CATCHPOINT)
-static void catch_fork_command_1 PARAMS ((catch_fork_kind fork_kind,
- char *arg,
- int tempflag,
- int from_tty));
+static void catch_fork_command_1 (catch_fork_kind fork_kind,
+ char *arg, int tempflag, int from_tty);
static void
-catch_fork_command_1 (fork_kind, arg, tempflag, from_tty)
- catch_fork_kind fork_kind;
- char *arg;
- int tempflag;
- int from_tty;
+catch_fork_command_1 (catch_fork_kind fork_kind, char *arg, int tempflag,
+ int from_tty)
{
char *cond_string = NULL;
#if defined(CHILD_INSERT_EXEC_CATCHPOINT)
static void
-catch_exec_command_1 (arg, tempflag, from_tty)
- char *arg;
- int tempflag;
- int from_tty;
+catch_exec_command_1 (char *arg, int tempflag, int from_tty)
{
char *cond_string = NULL;
#if defined(SOLIB_ADD)
static void
-catch_load_command_1 (arg, tempflag, from_tty)
- char *arg;
- int tempflag;
- int from_tty;
+catch_load_command_1 (char *arg, int tempflag, int from_tty)
{
char *dll_pathname = NULL;
char *cond_string = NULL;
}
static void
-catch_unload_command_1 (arg, tempflag, from_tty)
- char *arg;
- int tempflag;
- int from_tty;
+catch_unload_command_1 (char *arg, int tempflag, int from_tty)
{
char *dll_pathname = NULL;
char *cond_string = NULL;
exception event callback */
static void
-create_exception_catchpoint (tempflag, cond_string, ex_event, sal)
- int tempflag;
- char *cond_string;
- enum exception_event_kind ex_event;
- struct symtab_and_line *sal;
+create_exception_catchpoint (int tempflag, char *cond_string,
+ enum exception_event_kind ex_event,
+ struct symtab_and_line *sal)
{
struct breakpoint *b;
int thread = -1; /* All threads. */
/* Deal with "catch catch" and "catch throw" commands */
static void
-catch_exception_command_1 (ex_event, arg, tempflag, from_tty)
- enum exception_event_kind ex_event;
- char *arg;
- int tempflag;
- int from_tty;
+catch_exception_command_1 (enum exception_event_kind ex_event, char *arg,
+ int tempflag, int from_tty)
{
char *cond_string = NULL;
struct symtab_and_line *sal = NULL;
inside a catch_errors */
static int
-cover_target_enable_exception_callback (arg)
- PTR arg;
+cover_target_enable_exception_callback (PTR arg)
{
args_for_catchpoint_enable *args = arg;
struct symtab_and_line *sal;
static void
-handle_gnu_4_16_catch_command (arg, tempflag, from_tty)
- char *arg;
- int tempflag;
- int from_tty;
+handle_gnu_4_16_catch_command (char *arg, int tempflag, int from_tty)
{
/* First, translate ARG into something we can deal with in terms
of breakpoints. */
/* This creates a temporary internal breakpoint
just to placate infrun */
static struct breakpoint *
-create_temp_exception_breakpoint (pc)
- CORE_ADDR pc;
+create_temp_exception_breakpoint (CORE_ADDR pc)
{
struct symtab_and_line sal;
struct breakpoint *b;
#endif
static void
-catch_command_1 (arg, tempflag, from_tty)
- char *arg;
- int tempflag;
- int from_tty;
+catch_command_1 (char *arg, int tempflag, int from_tty)
{
/* The first argument may be an event name, such as "start" or "load".
/* Used by the gui, could be made a worker for other things. */
struct breakpoint *
-set_breakpoint_sal (sal)
- struct symtab_and_line sal;
+set_breakpoint_sal (struct symtab_and_line sal)
{
struct breakpoint *b;
b = set_raw_breakpoint (sal);
/* These aren't used; I don't know what they were for. */
/* Disable breakpoints on all catch clauses described in ARGS. */
static void
-disable_catch (args)
- char *args;
+disable_catch (char *args)
{
/* Map the disable command to catch clauses described in ARGS. */
}
/* Enable breakpoints on all catch clauses described in ARGS. */
static void
-enable_catch (args)
- char *args;
+enable_catch (char *args)
{
/* Map the disable command to catch clauses described in ARGS. */
}
/* Delete breakpoints on all catch clauses in the active scope. */
static void
-delete_catch (args)
- char *args;
+delete_catch (char *args)
{
/* Map the delete command to catch clauses described in ARGS. */
}
#endif /* 0 */
static void
-catch_command (arg, from_tty)
- char *arg;
- int from_tty;
+catch_command (char *arg, int from_tty)
{
catch_command_1 (arg, 0, from_tty);
}
\f
static void
-tcatch_command (arg, from_tty)
- char *arg;
- int from_tty;
+tcatch_command (char *arg, int from_tty)
{
catch_command_1 (arg, 1, from_tty);
}
static void
-clear_command (arg, from_tty)
- char *arg;
- int from_tty;
+clear_command (char *arg, int from_tty)
{
register struct breakpoint *b, *b1;
int default_match;
This is called after any breakpoint is hit, or after errors. */
void
-breakpoint_auto_delete (bs)
- bpstat bs;
+breakpoint_auto_delete (bpstat bs)
{
struct breakpoint *b, *temp;
structures. */
void
-delete_breakpoint (bpt)
- struct breakpoint *bpt;
+delete_breakpoint (struct breakpoint *bpt)
{
register struct breakpoint *b;
register bpstat bs;
free ((PTR) bpt);
}
+static void
+do_delete_breakpoint_cleanup (void *b)
+{
+ delete_breakpoint (b);
+}
+
+struct cleanup *
+make_cleanup_delete_breakpoint (struct breakpoint *b)
+{
+ return make_cleanup (do_delete_breakpoint_cleanup, b);
+}
+
+struct cleanup *
+make_exec_cleanup_delete_breakpoint (struct breakpoint *b)
+{
+ return make_exec_cleanup (do_delete_breakpoint_cleanup, b);
+}
+
void
-delete_command (arg, from_tty)
- char *arg;
- int from_tty;
+delete_command (char *arg, int from_tty)
{
struct breakpoint *b, *temp;
{
if (b->type != bp_call_dummy &&
b->type != bp_shlib_event &&
+ b->type != bp_thread_event &&
b->number >= 0)
breaks_to_delete = 1;
}
{
if (b->type != bp_call_dummy &&
b->type != bp_shlib_event &&
+ b->type != bp_thread_event &&
b->number >= 0)
delete_breakpoint (b);
}
Unused in this case. */
static int
-breakpoint_re_set_one (bint)
- PTR bint;
+breakpoint_re_set_one (PTR bint)
{
/* get past catch_errs */
struct breakpoint *b = (struct breakpoint *) bint;
starts and we really don't want to touch it. */
case bp_shlib_event:
+ /* Like bp_shlib_event, this breakpoint type is special.
+ Once it is set up, we do not want to touch it. */
+ case bp_thread_event:
+
/* Keep temporary breakpoints, which can be encountered when we step
over a dlopen call and SOLIB_ADD is resetting the breakpoints.
Otherwise these should have been blown away via the cleanup chain
/* Re-set all breakpoints after symbols have been re-loaded. */
void
-breakpoint_re_set ()
+breakpoint_re_set (void)
{
struct breakpoint *b, *temp;
enum language save_language;
- If the breakpoint is for all threads, leave it as-is.
- Else, reset it to the current thread for inferior_pid. */
void
-breakpoint_re_set_thread (b)
- struct breakpoint *b;
+breakpoint_re_set_thread (struct breakpoint *b)
{
if (b->thread != -1)
{
}
void
-set_ignore_count (bptnum, count, from_tty)
- int bptnum, count, from_tty;
+set_ignore_count (int bptnum, int count, int from_tty)
{
register struct breakpoint *b;
/* Clear the ignore counts of all breakpoints. */
void
-breakpoint_clear_ignore_counts ()
+breakpoint_clear_ignore_counts (void)
{
struct breakpoint *b;
/* Command to set ignore-count of breakpoint N to COUNT. */
static void
-ignore_command (args, from_tty)
- char *args;
- int from_tty;
+ignore_command (char *args, int from_tty)
{
char *p = args;
register int num;
whose numbers are given in ARGS. */
static void
-map_breakpoint_numbers (args, function)
- char *args;
- void (*function) PARAMS ((struct breakpoint *));
+map_breakpoint_numbers (char *args, void (*function) (struct breakpoint *))
{
register char *p = args;
char *p1;
}
void
-disable_breakpoint (bpt)
- struct breakpoint *bpt;
+disable_breakpoint (struct breakpoint *bpt)
{
/* Never disable a watchpoint scope breakpoint; we want to
hit them when we leave scope so we can delete both the
/* ARGSUSED */
static void
-disable_command (args, from_tty)
- char *args;
- int from_tty;
+disable_command (char *args, int from_tty)
{
register struct breakpoint *bpt;
if (args == 0)
}
static void
-do_enable_breakpoint (bpt, disposition)
- struct breakpoint *bpt;
- enum bpdisp disposition;
+do_enable_breakpoint (struct breakpoint *bpt, enum bpdisp disposition)
{
struct frame_info *save_selected_frame = NULL;
int save_selected_frame_level = -1;
}
if (save_selected_frame_level >= 0)
- select_and_print_frame (save_selected_frame,
- save_selected_frame_level);
+ select_frame (save_selected_frame, save_selected_frame_level);
value_free_to_mark (mark);
}
if (modify_breakpoint_hook)
}
void
-enable_breakpoint (bpt)
- struct breakpoint *bpt;
+enable_breakpoint (struct breakpoint *bpt)
{
do_enable_breakpoint (bpt, bpt->disposition);
}
/* ARGSUSED */
static void
-enable_command (args, from_tty)
- char *args;
- int from_tty;
+enable_command (char *args, int from_tty)
{
register struct breakpoint *bpt;
if (args == 0)
}
static void
-enable_once_breakpoint (bpt)
- struct breakpoint *bpt;
+enable_once_breakpoint (struct breakpoint *bpt)
{
do_enable_breakpoint (bpt, disable);
}
/* ARGSUSED */
static void
-enable_once_command (args, from_tty)
- char *args;
- int from_tty;
+enable_once_command (char *args, int from_tty)
{
map_breakpoint_numbers (args, enable_once_breakpoint);
}
static void
-enable_delete_breakpoint (bpt)
- struct breakpoint *bpt;
+enable_delete_breakpoint (struct breakpoint *bpt)
{
do_enable_breakpoint (bpt, del);
}
/* ARGSUSED */
static void
-enable_delete_command (args, from_tty)
- char *args;
- int from_tty;
+enable_delete_command (char *args, int from_tty)
{
map_breakpoint_numbers (args, enable_delete_breakpoint);
}
/* Use default_breakpoint_'s, or nothing if they aren't valid. */
struct symtabs_and_lines
-decode_line_spec_1 (string, funfirstline)
- char *string;
- int funfirstline;
+decode_line_spec_1 (char *string, int funfirstline)
{
struct symtabs_and_lines sals;
if (string == 0)
}
\f
void
-_initialize_breakpoint ()
+_initialize_breakpoint (void)
{
struct cmd_list_element *c;