/* Everything about breakpoints, for GDB.
- Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995
+ Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
Free Software Foundation, Inc.
This file is part of GDB.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include <ctype.h>
#include "gdbcore.h"
#include "gdbcmd.h"
#include "value.h"
-#include "ctype.h"
#include "command.h"
#include "inferior.h"
#include "thread.h"
#include "target.h"
#include "language.h"
-#include <string.h>
+#include "gdb_string.h"
#include "demangle.h"
#include "annotate.h"
b? (tmp=b->next, 1): 0; \
b = tmp)
-/* Provide defaults for systems that don't support hardware watchpoints. */
-
-#ifndef TARGET_CAN_USE_HARDWARE_WATCHPOINT
-
-/* Returns non-zero if we can set a hardware watchpoint of type TYPE. TYPE is
- one of bp_hardware_watchpoint, bp_read_watchpoint, bp_write_watchpoint, or
- bp_hardware_breakpoint. CNT is the number of such watchpoints used so far
- (including this one?). OTHERTYPE is who knows what... */
-
-#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(TYPE,CNT,OTHERTYPE) 0
-
-/* Set/clear a hardware watchpoint starting at ADDR, for LEN bytes. TYPE is 1
- for read and 2 for read/write accesses. Returns 0 for success, non-zero for
- failure. */
-
-#define target_remove_watchpoint(ADDR,LEN,TYPE) -1
-#define target_insert_watchpoint(ADDR,LEN,TYPE) -1
-#endif
-
-#ifndef target_insert_hw_breakpoint
-#define target_remove_hw_breakpoint(ADDR,SHADOW) -1
-#define target_insert_hw_breakpoint(ADDR,SHADOW) -1
-#endif
-
-#ifndef target_stopped_data_address
-#define target_stopped_data_address() 0
-#endif
-
/* True if breakpoint hit counts should be displayed in breakpoint info. */
int show_breakpoint_hit_counts = 1;
}
/* Failure to remove any of the hardware watchpoints comes here. */
if (b->inserted)
- error ("Hardware watchpoint %d: Could not remove watchpoint\n",
- b->number);
+ warning ("Hardware watchpoint %d: Could not remove watchpoint\n",
+ b->number);
/* Free the saved value chain. We will construct a new one
the next time the watchpoint is inserted. */
{
bpstat bs = (bpstat) p;
struct breakpoint *b;
- struct frame_info *saved_frame, *fr;
- int within_current_scope, saved_level;
+ struct frame_info *fr;
+ int within_current_scope;
b = bs->breakpoint_at;
&& b->address != bp_addr)
continue;
-/* If defined, then we need to decr pc by this much after a hardware break-
- point. Presumably should override DECR_PC_AFTER_BREAK, though it doesn't
- now... */
-
-#ifndef DECR_PC_AFTER_HW_BREAK
-#define DECR_PC_AFTER_HW_BREAK 0
-#endif
-
if (b->type == bp_hardware_breakpoint
&& b->address != (bp_addr - DECR_PC_AFTER_HW_BREAK))
continue;
/* We hit the through_sigtramp breakpoint. */
through_sig,
+ /* We hit the shared library event breakpoint. */
+ shlib_event,
+
/* This is just used to count how many enums there are. */
class_last
};
/* Here is the table which drives this routine. So that we can
format it pretty, we define some abbreviations for the
enum bpstat_what codes. */
-#define keep_c BPSTAT_WHAT_KEEP_CHECKING
-#define stop_s BPSTAT_WHAT_STOP_SILENT
-#define stop_n BPSTAT_WHAT_STOP_NOISY
-#define single BPSTAT_WHAT_SINGLE
-#define setlr BPSTAT_WHAT_SET_LONGJMP_RESUME
-#define clrlr BPSTAT_WHAT_CLEAR_LONGJMP_RESUME
-#define clrlrs BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE
+#define kc BPSTAT_WHAT_KEEP_CHECKING
+#define ss BPSTAT_WHAT_STOP_SILENT
+#define sn BPSTAT_WHAT_STOP_NOISY
+#define sgl BPSTAT_WHAT_SINGLE
+#define slr BPSTAT_WHAT_SET_LONGJMP_RESUME
+#define clr BPSTAT_WHAT_CLEAR_LONGJMP_RESUME
+#define clrs BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE
#define sr BPSTAT_WHAT_STEP_RESUME
#define ts BPSTAT_WHAT_THROUGH_SIGTRAMP
+#define shl BPSTAT_WHAT_CHECK_SHLIBS
/* "Can't happen." Might want to print an error message.
abort() is not out of the question, but chances are GDB is just
table[(int)class_last][(int)BPSTAT_WHAT_LAST] =
{
/* old action */
- /* keep_c stop_s stop_n single setlr clrlr clrlrs sr ts
+ /* kc ss sn sgl slr clr clrs sr ts shl
*/
-/*no_effect*/ {keep_c,stop_s,stop_n,single, setlr , clrlr , clrlrs, sr, ts},
-/*wp_silent*/ {stop_s,stop_s,stop_n,stop_s, stop_s, stop_s, stop_s, sr, ts},
-/*wp_noisy*/ {stop_n,stop_n,stop_n,stop_n, stop_n, stop_n, stop_n, sr, ts},
-/*bp_nostop*/ {single,stop_s,stop_n,single, setlr , clrlrs, clrlrs, sr, ts},
-/*bp_silent*/ {stop_s,stop_s,stop_n,stop_s, stop_s, stop_s, stop_s, sr, ts},
-/*bp_noisy*/ {stop_n,stop_n,stop_n,stop_n, stop_n, stop_n, stop_n, sr, ts},
-/*long_jump*/ {setlr ,stop_s,stop_n,setlr , err , err , err , sr, ts},
-/*long_resume*/ {clrlr ,stop_s,stop_n,clrlrs, err , err , err , sr, ts},
-/*step_resume*/ {sr ,sr ,sr ,sr , sr , sr , sr , sr, ts},
-/*through_sig*/ {ts ,ts ,ts ,ts , ts , ts , ts , ts, ts}
+/*no_effect*/ {kc, ss, sn, sgl, slr, clr, clrs, sr, ts, shl},
+/*wp_silent*/ {ss, ss, sn, ss, ss, ss, ss, sr, ts, shl},
+/*wp_noisy*/ {sn, sn, sn, sn, sn, sn, sn, sr, ts, shl},
+/*bp_nostop*/ {sgl, ss, sn, sgl, slr, clrs, clrs, sr, ts, shl},
+/*bp_silent*/ {ss, ss, sn, ss, ss, ss, ss, sr, ts, shl},
+/*bp_noisy*/ {sn, sn, sn, sn, sn, sn, sn, sr, ts, shl},
+/*long_jump*/ {slr, ss, sn, slr, err, err, err, sr, ts, shl},
+/*long_resume*/ {clr, ss, sn, clrs, err, err, err, sr, ts, shl},
+/*step_resume*/ {sr, sr, sr, sr, sr, sr, sr, sr, ts, shl},
+/*through_sig*/ {ts, ts, ts, ts, ts, ts, ts, ts, ts, shl},
+/*shlib*/ {shl, shl, shl, shl, shl, shl, shl, shl, ts, shl}
};
-#undef keep_c
-#undef stop_s
-#undef stop_n
-#undef single
-#undef setlr
-#undef clrlr
-#undef clrlrs
+#undef kc
+#undef ss
+#undef sn
+#undef sgl
+#undef slr
+#undef clr
+#undef clrs
#undef err
#undef sr
#undef ts
+#undef shl
enum bpstat_what_main_action current_action = BPSTAT_WHAT_KEEP_CHECKING;
struct bpstat_what retval;
case bp_watchpoint_scope:
bs_class = bp_nostop;
break;
-
+ case bp_shlib_event:
+ bs_class = shlib_event;
+ break;
case bp_call_dummy:
/* Make sure the action is stop (silent or noisy), so infrun.c
pops the dummy frame. */
"hw watchpoint", "read watchpoint",
"acc watchpoint", "longjmp",
"longjmp resume", "step resume",
- "watchpoint scope", "call dummy" };
+ "sigtramp",
+ "watchpoint scope", "call dummy",
+ "shlib events" };
static char *bpdisps[] = {"del", "dis", "keep"};
static char bpenables[] = "ny";
char wrap_indent[80];
case bp_through_sigtramp:
case bp_watchpoint_scope:
case bp_call_dummy:
+ case bp_shlib_event:
if (addressprint)
{
annotate_field (4);
return b;
}
+static int internal_breakpoint_number = -1;
+
static void
-create_longjmp_breakpoint(func_name)
+create_longjmp_breakpoint (func_name)
char *func_name;
{
struct symtab_and_line sal;
struct breakpoint *b;
- static int internal_breakpoint_number = -1;
if (func_name != NULL)
{
sal.symtab = NULL;
sal.line = 0;
- b = set_raw_breakpoint(sal);
+ b = set_raw_breakpoint (sal);
if (!b) return;
b->type = func_name != NULL ? bp_longjmp : bp_longjmp_resume;
}
}
+#ifdef SOLIB_ADD
+void
+remove_solib_event_breakpoints ()
+{
+ register struct breakpoint *b;
+
+ ALL_BREAKPOINTS (b)
+ if (b->type == bp_shlib_event)
+ delete_breakpoint (b);
+}
+
+void
+create_solib_event_breakpoint (address)
+ CORE_ADDR address;
+{
+ struct breakpoint *b;
+ struct symtab_and_line sal;
+
+ sal.pc = address;
+ sal.symtab = NULL;
+ sal.line = 0;
+ b = set_raw_breakpoint (sal);
+ b->number = internal_breakpoint_number--;
+ b->disposition = donttouch;
+ b->type = bp_shlib_event;
+}
+#endif
+
int
hw_breakpoint_used_count()
{
b->enable = enabled;
b->disposition = donttouch;
b->frame = (frame ? frame->frame : 0);
+
+ /* If we're debugging a multi-threaded program, then we
+ want momentary breakpoints to be active in only a
+ single thread of control. */
+ if (in_thread_list (inferior_pid))
+ b->thread = pid_to_thread_id (inferior_pid);
+
return b;
}
case bp_call_dummy:
delete_breakpoint (b);
break;
+
+ /* This breakpoint is special, it's set up when the inferior
+ starts and we really don't want to touch it. */
+ case bp_shlib_event:
+ break;
}
return 0;
set_language (save_language);
input_radix = save_input_radix;
- create_longjmp_breakpoint("longjmp");
- create_longjmp_breakpoint("_longjmp");
- create_longjmp_breakpoint("siglongjmp");
- create_longjmp_breakpoint(NULL);
+#ifdef GET_LONGJMP_TARGET
+ create_longjmp_breakpoint ("longjmp");
+ create_longjmp_breakpoint ("_longjmp");
+ create_longjmp_breakpoint ("siglongjmp");
+ create_longjmp_breakpoint (NULL);
+#endif
#if 0
- /* Took this out (temporaliy at least), since it produces an extra
+ /* Took this out (temporarily at least), since it produces an extra
blank line at startup. This messes up the gdbtests. -PB */
/* Blank line to finish off all those mention() messages we just printed. */
printf_filtered ("\n");