This is the mail archive of the
gdb@sources.redhat.com
mailing list for the GDB project.
Re: Remote set thread breakpoint
>>I'm thinking about extending the remote protocol for thread breakpoints.
>>The easiest solution would be to just add another data field to the Z
>>commands, like:
>>Ztype,addr,length,threadid
>>If threadid is given, gdbserver can use it. If it's -1 or not present (as in
>>the present implementation) it's a global breakpoint.
>>But if this would cause incompatibilities with existing parsers it may
>>be better to create a new command, even if it's just Z5 and the rest
>>is the same.
>>What would be better? Or is something like that already in the pipe?
>
>Yes [zZ]5 would be safer. Would also be a good oportunity to formalize how to probe support for this packet - Z5? Given things like vCont and its vCont? query, a [better?] alternative might be be vBP...
>
>Just note that there is a small challenge here. GDB internally assumes that breakpoints are global (it's a limitation / bug) - you'll need to also investigate what needs to be changed closer to GDB's core.
I have a first shot and wanted to get some opinions. I'm not asking that
this patch gets included into gdb. It's more about knowing if I'm on the
right track, if I have missed some stuff, what difficulties these changes
may provide etc.
The core handling is quite untouched (so still global BPs), only the remote
target is implemented as I don't know other targets at all. The fallback
is anyway to use the normal BP routines if thread BP is not available.
I also didn't add a new command probe for Z5, I just used the same
as is already there for the other Z commands.
This is against gdb-6.1.1, I couldn't get 6.2 to compile (didn't try cvs).
I can still change it for cvs-gdb when it has a future :)
Thanks
bye Fabi
diff -ru gdb-6.1.1o/gdb/breakpoint.c gdb-6.1.1/gdb/breakpoint.c
--- gdb-6.1.1o/gdb/breakpoint.c 2004-06-12 19:58:23.000000000 +0200
+++ gdb-6.1.1/gdb/breakpoint.c 2004-09-10 16:04:58.687500000 +0200
@@ -781,8 +781,14 @@
val = target_insert_hw_breakpoint (bpt->address,
bpt->shadow_contents);
else
- val = target_insert_breakpoint (bpt->address,
- bpt->shadow_contents);
+ if (-1!=bpt->owner->thread) {
+ val = target_insert_thread_breakpoint (bpt->address,
+ bpt->shadow_contents,
+ ptid_get_pid (thread_id_to_pid (bpt->owner->thread)));
+ } else {
+ val = target_insert_breakpoint (bpt->address,
+ bpt->shadow_contents);
+ }
}
else
{
@@ -801,7 +807,15 @@
CORE_ADDR addr = overlay_unmapped_address (bpt->address,
bpt->section);
/* Set a software (trap) breakpoint at the LMA. */
- val = target_insert_breakpoint (addr, bpt->shadow_contents);
+ if (-1!=bpt->owner->thread) {
+ val = target_insert_thread_breakpoint (addr,
+ bpt->shadow_contents,
+ ptid_get_pid (thread_id_to_pid (bpt->owner->thread)));
+ } else {
+ val = target_insert_breakpoint (addr,
+ bpt->shadow_contents);
+ }
+
if (val != 0)
fprintf_unfiltered (tmp_error_stream,
"Overlay breakpoint %d failed: in ROM?",
@@ -816,8 +830,14 @@
val = target_insert_hw_breakpoint (bpt->address,
bpt->shadow_contents);
else
- val = target_insert_breakpoint (bpt->address,
- bpt->shadow_contents);
+ if (-1!=bpt->owner->thread) {
+ val = target_insert_thread_breakpoint (bpt->address,
+ bpt->shadow_contents,
+ ptid_get_pid (thread_id_to_pid (bpt->owner->thread)));
+ } else {
+ val = target_insert_breakpoint (bpt->address,
+ bpt->shadow_contents);
+ }
}
else
{
@@ -1015,7 +1035,15 @@
/* If we get here, we must have a callback mechanism for exception
events -- with g++ style embedded label support, we insert
ordinary breakpoints and not catchpoints. */
- val = target_insert_breakpoint (bpt->address, bpt->shadow_contents);
+ if (-1!=bpt->owner->thread) {
+ val = target_insert_thread_breakpoint (bpt->address,
+ bpt->shadow_contents,
+ ptid_get_pid (thread_id_to_pid (bpt->owner->thread)));
+ } else {
+ val = target_insert_breakpoint (bpt->address,
+ bpt->shadow_contents);
+ }
+
if (val)
{
/* Couldn't set breakpoint for some reason */
@@ -1208,7 +1236,14 @@
if (b->loc_type == bp_loc_hardware_breakpoint)
val = target_insert_hw_breakpoint (b->address, b->shadow_contents);
else
- val = target_insert_breakpoint (b->address, b->shadow_contents);
+ if (-1!=b->owner->thread) {
+ val = target_insert_thread_breakpoint (b->address,
+ b->shadow_contents,
+ ptid_get_pid (thread_id_to_pid (b->owner->thread)));
+ } else {
+ val = target_insert_breakpoint (b->address,
+ b->shadow_contents);
+ }
/* FIXME drow/2003-10-07: This doesn't handle any other kinds of
breakpoints. It's wrong for watchpoints, for example. */
if (val != 0)
@@ -1415,7 +1450,14 @@
val = target_remove_hw_breakpoint (b->address,
b->shadow_contents);
else
- val = target_remove_breakpoint (b->address, b->shadow_contents);
+ if (-1!=b->owner->thread) {
+ val = target_remove_thread_breakpoint (b->address,
+ b->shadow_contents,
+ ptid_get_pid(thread_id_to_pid(b->owner->thread)));
+ } else {
+ val = target_remove_breakpoint (b->address,
+ b->shadow_contents);
+ }
}
else
{
@@ -1433,7 +1475,14 @@
if (b->loc_type == bp_loc_hardware_breakpoint)
target_remove_hw_breakpoint (addr, b->shadow_contents);
else
- target_remove_breakpoint (addr, b->shadow_contents);
+ if (-1!=b->owner->thread) {
+ target_remove_thread_breakpoint (addr,
+ b->shadow_contents,
+ ptid_get_pid(thread_id_to_pid(b->owner->thread)));
+ } else {
+ target_remove_breakpoint (addr,
+ b->shadow_contents);
+ }
}
/* Did we set a breakpoint at the VMA?
If so, we will have marked the breakpoint 'inserted'. */
@@ -1447,8 +1496,14 @@
val = target_remove_hw_breakpoint (b->address,
b->shadow_contents);
else
- val = target_remove_breakpoint (b->address,
- b->shadow_contents);
+ if (-1!=b->owner->thread) {
+ val = target_remove_thread_breakpoint (b->address,
+ b->shadow_contents,
+ ptid_get_pid(thread_id_to_pid(b->owner->thread)));
+ } else {
+ val = target_remove_breakpoint (b->address,
+ b->shadow_contents);
+ }
}
else
{
@@ -1557,7 +1612,14 @@
&& !b->duplicate)
{
- val = target_remove_breakpoint (b->address, b->shadow_contents);
+ if (-1!=b->owner->thread) {
+ val = target_remove_thread_breakpoint (b->address,
+ b->shadow_contents,
+ ptid_get_pid(thread_id_to_pid(b->owner->thread)));
+ } else {
+ val = target_remove_breakpoint (b->address,
+ b->shadow_contents);
+ }
if (val)
return val;
@@ -6949,7 +7011,14 @@
if (b->type == bp_hardware_breakpoint)
val = target_insert_hw_breakpoint (b->loc->address, b->loc->shadow_contents);
else
- val = target_insert_breakpoint (b->loc->address, b->loc->shadow_contents);
+ if (-1!=b->thread) {
+ val = target_insert_thread_breakpoint (b->loc->address,
+ b->loc->shadow_contents,
+ ptid_get_pid (thread_id_to_pid (b->thread)));
+ } else {
+ val = target_insert_breakpoint (b->loc->address,
+ b->loc->shadow_contents);
+ }
/* If there was an error in the insert, print a message, then stop execution. */
if (val != 0)
diff -ru gdb-6.1.1o/gdb/corelow.c gdb-6.1.1/gdb/corelow.c
--- gdb-6.1.1o/gdb/corelow.c 2004-02-28 19:04:36.000000000 +0100
+++ gdb-6.1.1/gdb/corelow.c 2004-09-10 10:16:12.296875000 +0200
@@ -614,6 +614,8 @@
core_ops.to_files_info = core_files_info;
core_ops.to_insert_breakpoint = ignore;
core_ops.to_remove_breakpoint = ignore;
+ core_ops.to_insert_thread_breakpoint = NULL;
+ core_ops.to_remove_thread_breakpoint = NULL;
core_ops.to_create_inferior = find_default_create_inferior;
core_ops.to_thread_alive = core_file_thread_alive;
core_ops.to_stratum = core_stratum;
diff -ru gdb-6.1.1o/gdb/exec.c gdb-6.1.1/gdb/exec.c
--- gdb-6.1.1o/gdb/exec.c 2004-02-28 19:04:37.000000000 +0100
+++ gdb-6.1.1/gdb/exec.c 2004-09-10 10:26:37.125000000 +0200
@@ -705,6 +705,8 @@
exec_ops.to_files_info = exec_files_info;
exec_ops.to_insert_breakpoint = ignore;
exec_ops.to_remove_breakpoint = ignore;
+ exec_ops.to_insert_thread_breakpoint = NULL;
+ exec_ops.to_remove_thread_breakpoint = NULL;
exec_ops.to_create_inferior = find_default_create_inferior;
exec_ops.to_stratum = file_stratum;
exec_ops.to_has_memory = 1;
diff -ru gdb-6.1.1o/gdb/gnu-nat.c gdb-6.1.1/gdb/gnu-nat.c
--- gdb-6.1.1o/gdb/gnu-nat.c 2003-09-30 15:23:49.000000000 +0200
+++ gdb-6.1.1/gdb/gnu-nat.c 2004-09-10 10:26:10.359375000 +0200
@@ -2604,6 +2604,8 @@
gnu_ops.to_find_memory_regions = gnu_find_memory_regions;
gnu_ops.to_insert_breakpoint = memory_insert_breakpoint;
gnu_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ gnu_ops.to_insert_thread_breakpoint = NULL;
+ gnu_ops.to_remove_thread_breakpoint = NULL;
gnu_ops.to_terminal_init = gnu_terminal_init_inferior;
gnu_ops.to_terminal_inferior = terminal_inferior;
gnu_ops.to_terminal_ours_for_output = terminal_ours_for_output;
diff -ru gdb-6.1.1o/gdb/go32-nat.c gdb-6.1.1/gdb/go32-nat.c
--- gdb-6.1.1o/gdb/go32-nat.c 2003-12-29 08:42:43.000000000 +0100
+++ gdb-6.1.1/gdb/go32-nat.c 2004-09-10 10:24:54.140625000 +0200
@@ -863,6 +863,8 @@
go32_ops.to_files_info = go32_files_info;
go32_ops.to_insert_breakpoint = memory_insert_breakpoint;
go32_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ go32_ops.to_insert_thread_breakpoint = NULL;
+ go32_ops.to_remove_thread_breakpoint = NULL;
go32_ops.to_terminal_init = go32_terminal_init;
go32_ops.to_terminal_inferior = go32_terminal_inferior;
go32_ops.to_terminal_ours_for_output = go32_terminal_ours;
diff -ru gdb-6.1.1o/gdb/hpux-thread.c gdb-6.1.1/gdb/hpux-thread.c
--- gdb-6.1.1o/gdb/hpux-thread.c 2003-10-02 22:28:29.000000000 +0200
+++ gdb-6.1.1/gdb/hpux-thread.c 2004-09-10 10:24:24.406250000 +0200
@@ -551,6 +551,8 @@
hpux_thread_ops.to_files_info = hpux_thread_files_info;
hpux_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
hpux_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ hpux_thread_ops.to_insert_thread_breakpoint = NULL;
+ hpux_thread_ops.to_remove_thread_breakpoint = NULL;
hpux_thread_ops.to_terminal_init = terminal_init_inferior;
hpux_thread_ops.to_terminal_inferior = terminal_inferior;
hpux_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
diff -ru gdb-6.1.1o/gdb/inftarg.c gdb-6.1.1/gdb/inftarg.c
--- gdb-6.1.1o/gdb/inftarg.c 2004-02-04 22:49:55.000000000 +0100
+++ gdb-6.1.1/gdb/inftarg.c 2004-09-10 10:24:02.484375000 +0200
@@ -626,6 +626,8 @@
child_ops.to_files_info = child_files_info;
child_ops.to_insert_breakpoint = memory_insert_breakpoint;
child_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ child_ops.to_insert_thread_breakpoint = NULL;
+ child_ops.to_remove_thread_breakpoint = NULL;
child_ops.to_terminal_init = terminal_init_inferior;
child_ops.to_terminal_inferior = terminal_inferior;
child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
diff -ru gdb-6.1.1o/gdb/monitor.c gdb-6.1.1/gdb/monitor.c
--- gdb-6.1.1o/gdb/monitor.c 2004-01-21 16:37:11.000000000 +0100
+++ gdb-6.1.1/gdb/monitor.c 2004-09-10 10:23:38.140625000 +0200
@@ -2259,6 +2259,8 @@
monitor_ops.to_files_info = monitor_files_info;
monitor_ops.to_insert_breakpoint = monitor_insert_breakpoint;
monitor_ops.to_remove_breakpoint = monitor_remove_breakpoint;
+ monitor_ops.to_insert_thread_breakpoint = NULL;
+ monitor_ops.to_remove_thread_breakpoint = NULL;
monitor_ops.to_kill = monitor_kill;
monitor_ops.to_load = monitor_load;
monitor_ops.to_create_inferior = monitor_create_inferior;
diff -ru gdb-6.1.1o/gdb/nto-procfs.c gdb-6.1.1/gdb/nto-procfs.c
--- gdb-6.1.1o/gdb/nto-procfs.c 2003-07-18 19:15:33.000000000 +0200
+++ gdb-6.1.1/gdb/nto-procfs.c 2004-09-10 10:22:47.171875000 +0200
@@ -1275,6 +1275,8 @@
procfs_ops.to_files_info = procfs_files_info;
procfs_ops.to_insert_breakpoint = procfs_insert_breakpoint;
procfs_ops.to_remove_breakpoint = procfs_remove_breakpoint;
+ procfs_ops.to_insert_thread_breakpoint = NULL;
+ procfs_ops.to_remove_thread_breakpoint = NULL;
procfs_ops.to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint;
procfs_ops.to_insert_hw_breakpoint = procfs_insert_hw_breakpoint;
procfs_ops.to_remove_hw_breakpoint = procfs_remove_breakpoint;
diff -ru gdb-6.1.1o/gdb/ppc-bdm.c gdb-6.1.1/gdb/ppc-bdm.c
--- gdb-6.1.1o/gdb/ppc-bdm.c 2003-09-17 16:24:30.000000000 +0200
+++ gdb-6.1.1/gdb/ppc-bdm.c 2004-09-10 10:26:59.671875000 +0200
@@ -331,6 +331,8 @@
bdm_ppc_ops.to_files_info = ocd_files_info;
bdm_ppc_ops.to_insert_breakpoint = ocd_insert_breakpoint;
bdm_ppc_ops.to_remove_breakpoint = ocd_remove_breakpoint;
+ bdm_ppc_ops.to_insert_thread_breakpoint = NULL;
+ bdm_ppc_ops.to_remove_thread_breakpoint = NULL;
bdm_ppc_ops.to_kill = ocd_kill;
bdm_ppc_ops.to_load = ocd_load;
bdm_ppc_ops.to_create_inferior = ocd_create_inferior;
diff -ru gdb-6.1.1o/gdb/procfs.c gdb-6.1.1/gdb/procfs.c
--- gdb-6.1.1o/gdb/procfs.c 2004-02-15 23:38:40.000000000 +0100
+++ gdb-6.1.1/gdb/procfs.c 2004-09-10 10:15:43.656250000 +0200
@@ -175,6 +175,8 @@
procfs_ops.to_xfer_memory = procfs_xfer_memory;
procfs_ops.to_insert_breakpoint = memory_insert_breakpoint;
procfs_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ procfs_ops.to_insert_thread_breakpoint = NULL;
+ procfs_ops.to_remove_thread_breakpoint = NULL;
procfs_ops.to_notice_signals = procfs_notice_signals;
procfs_ops.to_files_info = procfs_files_info;
procfs_ops.to_stop = procfs_stop;
diff -ru gdb-6.1.1o/gdb/remote-e7000.c gdb-6.1.1/gdb/remote-e7000.c
--- gdb-6.1.1o/gdb/remote-e7000.c 2003-12-11 07:21:12.000000000 +0100
+++ gdb-6.1.1/gdb/remote-e7000.c 2004-09-10 10:15:13.000000000 +0200
@@ -2153,6 +2153,8 @@
e7000_ops.to_files_info = e7000_files_info;
e7000_ops.to_insert_breakpoint = e7000_insert_breakpoint;
e7000_ops.to_remove_breakpoint = e7000_remove_breakpoint;
+ e7000_ops.to_insert_thread_breakpoint = NULL;
+ e7000_ops.to_remove_thread_breakpoint = NULL;
e7000_ops.to_kill = e7000_kill;
e7000_ops.to_load = e7000_load;
e7000_ops.to_create_inferior = e7000_create_inferior;
diff -ru gdb-6.1.1o/gdb/remote-m32r-sdi.c gdb-6.1.1/gdb/remote-m32r-sdi.c
--- gdb-6.1.1o/gdb/remote-m32r-sdi.c 2004-03-10 01:22:45.000000000 +0100
+++ gdb-6.1.1/gdb/remote-m32r-sdi.c 2004-09-10 09:31:47.937500000 +0200
@@ -1619,6 +1619,8 @@
m32r_ops.to_files_info = m32r_files_info;
m32r_ops.to_insert_breakpoint = m32r_insert_breakpoint;
m32r_ops.to_remove_breakpoint = m32r_remove_breakpoint;
+ m32r_ops.to_insert_thread_breakpoint = NULL;
+ m32r_ops.to_remove_thread_breakpoint = NULL;
m32r_ops.to_can_use_hw_breakpoint = m32r_can_use_hw_watchpoint;
m32r_ops.to_insert_watchpoint = m32r_insert_watchpoint;
m32r_ops.to_remove_watchpoint = m32r_remove_watchpoint;
diff -ru gdb-6.1.1o/gdb/remote-mips.c gdb-6.1.1/gdb/remote-mips.c
--- gdb-6.1.1o/gdb/remote-mips.c 2004-01-21 16:37:11.000000000 +0100
+++ gdb-6.1.1/gdb/remote-mips.c 2004-09-10 09:32:15.812500000 +0200
@@ -3310,6 +3310,8 @@
mips_ops.to_files_info = mips_files_info;
mips_ops.to_insert_breakpoint = mips_insert_breakpoint;
mips_ops.to_remove_breakpoint = mips_remove_breakpoint;
+ mips_ops.to_insert_thread_breakpoint = NULL;
+ mips_ops.to_remove_thread_breakpoint = NULL;
mips_ops.to_insert_watchpoint = mips_insert_watchpoint;
mips_ops.to_remove_watchpoint = mips_remove_watchpoint;
mips_ops.to_stopped_by_watchpoint = mips_stopped_by_watchpoint;
diff -ru gdb-6.1.1o/gdb/remote-rdi.c gdb-6.1.1/gdb/remote-rdi.c
--- gdb-6.1.1o/gdb/remote-rdi.c 2004-02-12 19:43:09.000000000 +0100
+++ gdb-6.1.1/gdb/remote-rdi.c 2004-09-10 09:32:34.421875000 +0200
@@ -905,6 +905,8 @@
arm_rdi_ops.to_files_info = arm_rdi_files_info;
arm_rdi_ops.to_insert_breakpoint = arm_rdi_insert_breakpoint;
arm_rdi_ops.to_remove_breakpoint = arm_rdi_remove_breakpoint;
+ arm_rdi_ops.to_insert_breakpoint = NULL;
+ arm_rdi_ops.to_remove_breakpoint = NULL;
arm_rdi_ops.to_kill = arm_rdi_kill;
arm_rdi_ops.to_load = generic_load;
arm_rdi_ops.to_create_inferior = arm_rdi_create_inferior;
diff -ru gdb-6.1.1o/gdb/remote-rdp.c gdb-6.1.1/gdb/remote-rdp.c
--- gdb-6.1.1o/gdb/remote-rdp.c 2004-03-25 18:03:59.000000000 +0100
+++ gdb-6.1.1/gdb/remote-rdp.c 2004-09-10 09:35:50.562500000 +0200
@@ -1408,6 +1408,8 @@
remote_rdp_ops.to_files_info = remote_rdp_files_info;
remote_rdp_ops.to_insert_breakpoint = remote_rdp_insert_breakpoint;
remote_rdp_ops.to_remove_breakpoint = remote_rdp_remove_breakpoint;
+ remote_rdp_ops.to_insert_thread_breakpoint = NULL;
+ remote_rdp_ops.to_remove_thread_breakpoint = NULL;
remote_rdp_ops.to_kill = remote_rdp_kill;
remote_rdp_ops.to_load = generic_load;
remote_rdp_ops.to_create_inferior = remote_rdp_create_inferior;
diff -ru gdb-6.1.1o/gdb/remote-sds.c gdb-6.1.1/gdb/remote-sds.c
--- gdb-6.1.1o/gdb/remote-sds.c 2004-01-19 02:20:11.000000000 +0100
+++ gdb-6.1.1/gdb/remote-sds.c 2004-09-10 09:36:12.234375000 +0200
@@ -1070,6 +1070,8 @@
sds_ops.to_files_info = sds_files_info;
sds_ops.to_insert_breakpoint = sds_insert_breakpoint;
sds_ops.to_remove_breakpoint = sds_remove_breakpoint;
+ sds_ops.to_insert_thread_breakpoint = NULL;
+ sds_ops.to_remove_thread_breakpoint = NULL;
sds_ops.to_kill = sds_kill;
sds_ops.to_load = sds_load;
sds_ops.to_create_inferior = sds_create_inferior;
diff -ru gdb-6.1.1o/gdb/remote-sim.c gdb-6.1.1/gdb/remote-sim.c
--- gdb-6.1.1o/gdb/remote-sim.c 2004-02-02 17:14:36.000000000 +0100
+++ gdb-6.1.1/gdb/remote-sim.c 2004-09-10 09:38:51.375000000 +0200
@@ -871,6 +871,8 @@
gdbsim_ops.to_files_info = gdbsim_files_info;
gdbsim_ops.to_insert_breakpoint = gdbsim_insert_breakpoint;
gdbsim_ops.to_remove_breakpoint = gdbsim_remove_breakpoint;
+ gdbsim_ops.to_insert_thread_breakpoint = NULL;
+ gdbsim_ops.to_remove_thread_breakpoint = NULL;
gdbsim_ops.to_kill = gdbsim_kill;
gdbsim_ops.to_load = gdbsim_load;
gdbsim_ops.to_create_inferior = gdbsim_create_inferior;
diff -ru gdb-6.1.1o/gdb/remote-st.c gdb-6.1.1/gdb/remote-st.c
--- gdb-6.1.1o/gdb/remote-st.c 2003-09-19 00:39:21.000000000 +0200
+++ gdb-6.1.1/gdb/remote-st.c 2004-09-10 09:46:18.875000000 +0200
@@ -778,6 +778,8 @@
st2000_ops.to_files_info = st2000_files_info;
st2000_ops.to_insert_breakpoint = st2000_insert_breakpoint;
st2000_ops.to_remove_breakpoint = st2000_remove_breakpoint; /* Breakpoints */
+ st2000_ops.to_insert_thread_breakpoint = NULL;
+ st2000_ops.to_remove_thread_breakpoint = NULL; /* Breakpoints */
st2000_ops.to_kill = st2000_kill;
st2000_ops.to_create_inferior = st2000_create_inferior;
st2000_ops.to_mourn_inferior = st2000_mourn_inferior;
diff -ru gdb-6.1.1o/gdb/remote-vx.c gdb-6.1.1/gdb/remote-vx.c
--- gdb-6.1.1o/gdb/remote-vx.c 2003-09-21 03:26:45.000000000 +0200
+++ gdb-6.1.1/gdb/remote-vx.c 2004-09-10 09:39:52.859375000 +0200
@@ -1380,6 +1380,8 @@
vx_run_ops.to_files_info = vx_run_files_info;
vx_run_ops.to_insert_breakpoint = vx_insert_breakpoint;
vx_run_ops.to_remove_breakpoint = vx_remove_breakpoint;
+ vx_run_ops.to_insert_thread_breakpoint = NULL;
+ vx_run_ops.to_remove_thread_breakpoint = NULL;
vx_run_ops.to_kill = vx_kill;
vx_run_ops.to_load = vx_load_command;
vx_run_ops.to_lookup_symbol = vx_lookup_symbol;
diff -ru gdb-6.1.1o/gdb/remote.c gdb-6.1.1/gdb/remote.c
--- gdb-6.1.1o/gdb/remote.c 2004-02-25 21:41:00.000000000 +0100
+++ gdb-6.1.1/gdb/remote.c 2004-09-13 14:51:34.515625000 +0200
@@ -146,6 +146,10 @@
static int remote_remove_breakpoint (CORE_ADDR, char *);
+static int remote_insert_thread_breakpoint (CORE_ADDR, char *, int);
+
+static int remote_remove_thread_breakpoint (CORE_ADDR, char *, int);
+
static int hexnumlen (ULONGEST num);
static void init_remote_ops (void);
@@ -837,6 +841,7 @@
Z_PACKET_WRITE_WP,
Z_PACKET_READ_WP,
Z_PACKET_ACCESS_WP,
+ Z_PACKET_SOFTWARE_THREAD_BP,
NR_Z_PACKET_TYPES
};
@@ -915,6 +920,21 @@
show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_ACCESS_WP]);
}
+static void
+set_remote_protocol_Z_software_thread_bp_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ update_packet_config (&remote_protocol_Z[Z_PACKET_SOFTWARE_THREAD_BP]);
+}
+
+static void
+show_remote_protocol_Z_software_thread_bp_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_SOFTWARE_THREAD_BP]);
+}
+
+
/* For compatibility with older distributions. Provide a ``set remote
Z-packet ...'' command that updates all the Z packet types. */
@@ -4729,6 +4749,86 @@
"remote_remove_hw_breakpoint: reached end of function");
}
+static int
+remote_insert_thread_breakpoint (CORE_ADDR addr, char *contents_cache, int threadid)
+{
+ struct remote_state *rs = get_remote_state ();
+ int bp_size;
+
+ /* Try the "Z" s/w breakpoint packet if it is not already disabled.
+ If it succeeds, then set the support to PACKET_ENABLE. If it
+ fails, and the user has explicitly requested the Z support then
+ report an error, otherwise, mark it disabled and go on. */
+
+ if ((remote_protocol_Z[Z_PACKET_SOFTWARE_THREAD_BP].support != PACKET_DISABLE)
+ &&(-1!=threadid))
+ {
+ char *buf = alloca (rs->remote_packet_size);
+ char *p = buf;
+
+ addr = remote_address_masked (addr);
+ *(p++) = 'Z';
+ *(p++) = '5';
+ *(p++) = ',';
+ p += hexnumstr (p, (ULONGEST) addr);
+ BREAKPOINT_FROM_PC (&addr, &bp_size);
+ sprintf (p, ",%d", bp_size);
+ p+=strlen(p);
+ sprintf (p, ",%x", threadid);
+
+ putpkt (buf);
+ getpkt (buf, (rs->remote_packet_size), 0);
+
+ switch (packet_ok (buf, &remote_protocol_Z[Z_PACKET_SOFTWARE_THREAD_BP]))
+ {
+ case PACKET_ERROR:
+ return -1;
+ case PACKET_OK:
+ return 0;
+ case PACKET_UNKNOWN:
+ break;
+ }
+ }
+
+ /* thread breakpoint not available, use normal breakpoint. */
+ return remote_insert_breakpoint (addr, contents_cache);
+}
+
+static int
+remote_remove_thread_breakpoint (CORE_ADDR addr, char *contents_cache, int threadid)
+{
+ struct remote_state *rs = get_remote_state ();
+ int bp_size;
+
+ if ((remote_protocol_Z[Z_PACKET_SOFTWARE_THREAD_BP].support != PACKET_DISABLE)
+ &&(-1!=threadid))
+ {
+ char *buf = alloca (rs->remote_packet_size);
+ char *p = buf;
+
+ *(p++) = 'z';
+ *(p++) = '5';
+ *(p++) = ',';
+
+ addr = remote_address_masked (addr);
+ p += hexnumstr (p, (ULONGEST) addr);
+ BREAKPOINT_FROM_PC (&addr, &bp_size);
+ sprintf (p, ",%d", bp_size);
+ p+=strlen(p);
+ sprintf (p, ",%x", threadid);
+
+ putpkt (buf);
+ getpkt (buf, (rs->remote_packet_size), 0);
+
+ return (buf[0] == 'E');
+ }
+
+ /* thread breakpoint not available, use normal breakpoint. */
+ return remote_remove_breakpoint (addr, contents_cache);
+
+}
+
+
/* Some targets are only capable of doing downloads, and afterwards
they switch to the remote serial protocol. This function provides
a clean way to get from the download target to the remote target.
@@ -5240,6 +5340,8 @@
remote_ops.to_remove_hw_breakpoint = remote_remove_hw_breakpoint;
remote_ops.to_insert_watchpoint = remote_insert_watchpoint;
remote_ops.to_remove_watchpoint = remote_remove_watchpoint;
+ remote_ops.to_insert_thread_breakpoint = remote_insert_thread_breakpoint;
+ remote_ops.to_remove_thread_breakpoint = remote_remove_thread_breakpoint;
remote_ops.to_kill = remote_kill;
remote_ops.to_load = generic_load;
remote_ops.to_mourn_inferior = remote_mourn;
@@ -5666,6 +5768,13 @@
&remote_set_cmdlist, &remote_show_cmdlist,
0);
+ add_packet_config_cmd (&remote_protocol_Z[Z_PACKET_SOFTWARE_THREAD_BP],
+ "Z5", "software-thread-breakpoint",
+ set_remote_protocol_Z_software_thread_bp_packet_cmd,
+ show_remote_protocol_Z_software_thread_bp_packet_cmd,
+ &remote_set_cmdlist, &remote_show_cmdlist,
+ 0);
+
add_packet_config_cmd (&remote_protocol_qPart_auxv,
"qPart_auxv", "read-aux-vector",
set_remote_protocol_qPart_auxv_packet_cmd,
diff -ru gdb-6.1.1o/gdb/sol-thread.c gdb-6.1.1/gdb/sol-thread.c
--- gdb-6.1.1o/gdb/sol-thread.c 2004-02-01 23:35:28.000000000 +0100
+++ gdb-6.1.1/gdb/sol-thread.c 2004-09-10 09:45:52.156250000 +0200
@@ -1584,6 +1584,8 @@
sol_thread_ops.to_files_info = sol_thread_files_info;
sol_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
sol_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ sol_thread_ops.to_insert_thread_breakpoint = NULL;
+ sol_thread_ops.to_remove_thread_breakpoint = NULL;
sol_thread_ops.to_terminal_init = terminal_init_inferior;
sol_thread_ops.to_terminal_inferior = terminal_inferior;
sol_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
@@ -1628,6 +1630,8 @@
sol_core_ops.to_files_info = sol_core_files_info;
sol_core_ops.to_insert_breakpoint = ignore;
sol_core_ops.to_remove_breakpoint = ignore;
+ sol_core_ops.to_insert_thread_breakpoint = NULL;
+ sol_core_ops.to_remove_thread_breakpoint = NULL;
sol_core_ops.to_create_inferior = sol_thread_create_inferior;
sol_core_ops.to_stratum = core_stratum;
sol_core_ops.to_has_memory = 1;
diff -ru gdb-6.1.1o/gdb/target.c gdb-6.1.1/gdb/target.c
--- gdb-6.1.1o/gdb/target.c 2004-01-19 17:49:35.000000000 +0100
+++ gdb-6.1.1/gdb/target.c 2004-09-10 10:31:29.156250000 +0200
@@ -117,6 +117,10 @@
static int debug_to_remove_breakpoint (CORE_ADDR, char *);
+static int debug_to_insert_thread_breakpoint (CORE_ADDR, char *, int);
+
+static int debug_to_remove_thread_breakpoint (CORE_ADDR, char *, int);
+
static int debug_to_can_use_hw_breakpoint (int, int, int);
static int debug_to_insert_hw_breakpoint (CORE_ADDR, char *);
@@ -390,6 +394,8 @@
INHERIT (to_files_info, t);
INHERIT (to_insert_breakpoint, t);
INHERIT (to_remove_breakpoint, t);
+ INHERIT (to_insert_thread_breakpoint, t);
+ INHERIT (to_remove_thread_breakpoint, t);
INHERIT (to_can_use_hw_breakpoint, t);
INHERIT (to_insert_hw_breakpoint, t);
INHERIT (to_remove_hw_breakpoint, t);
@@ -506,6 +512,10 @@
memory_insert_breakpoint);
de_fault (to_remove_breakpoint,
memory_remove_breakpoint);
+ de_fault (to_insert_thread_breakpoint,
+ NULL);
+ de_fault (to_remove_thread_breakpoint,
+ NULL);
de_fault (to_can_use_hw_breakpoint,
(int (*) (int, int, int))
return_zero);
@@ -1886,6 +1896,36 @@
}
static int
+debug_to_insert_thread_breakpoint (CORE_ADDR addr, char *save, int threadid)
+{
+ int retval;
+
+ retval = debug_target.to_insert_thread_breakpoint (addr, save, threadid);
+
+ fprintf_unfiltered (gdb_stdlog,
+ "target_insert_breakpoint (0x%lx, %lx) = %ld\n",
+ (unsigned long) addr,
+ (unsigned long) threadid,
+ (unsigned long) retval);
+ return retval;
+}
+
+static int
+debug_to_remove_thread_breakpoint (CORE_ADDR addr, char *save, int threadid)
+{
+ int retval;
+
+ retval = debug_target.to_remove_thread_breakpoint (addr, save, threadid);
+
+ fprintf_unfiltered (gdb_stdlog,
+ "target_remove_thread_breakpoint (0x%lx, %lx) = %ld\n",
+ (unsigned long) addr,
+ (unsigned long) threadid,
+ (unsigned long) retval);
+ return retval;
+}
+
+static int
debug_to_can_use_hw_breakpoint (int type, int cnt, int from_tty)
{
int retval;
@@ -2354,6 +2394,8 @@
current_target.to_files_info = debug_to_files_info;
current_target.to_insert_breakpoint = debug_to_insert_breakpoint;
current_target.to_remove_breakpoint = debug_to_remove_breakpoint;
+ current_target.to_insert_thread_breakpoint = debug_to_insert_thread_breakpoint;
+ current_target.to_remove_thread_breakpoint = debug_to_remove_thread_breakpoint;
current_target.to_can_use_hw_breakpoint = debug_to_can_use_hw_breakpoint;
current_target.to_insert_hw_breakpoint = debug_to_insert_hw_breakpoint;
current_target.to_remove_hw_breakpoint = debug_to_remove_hw_breakpoint;
diff -ru gdb-6.1.1o/gdb/target.h gdb-6.1.1/gdb/target.h
--- gdb-6.1.1o/gdb/target.h 2004-02-04 22:49:55.000000000 +0100
+++ gdb-6.1.1/gdb/target.h 2004-09-10 15:50:36.640625000 +0200
@@ -335,6 +335,8 @@
void (*to_files_info) (struct target_ops *);
int (*to_insert_breakpoint) (CORE_ADDR, char *);
int (*to_remove_breakpoint) (CORE_ADDR, char *);
+ int (*to_insert_thread_breakpoint) (CORE_ADDR, char *, int);
+ int (*to_remove_thread_breakpoint) (CORE_ADDR, char *, int);
int (*to_can_use_hw_breakpoint) (int, int, int);
int (*to_insert_hw_breakpoint) (CORE_ADDR, char *);
int (*to_remove_hw_breakpoint) (CORE_ADDR, char *);
@@ -632,6 +634,11 @@
#define target_insert_breakpoint(addr, save) \
(*current_target.to_insert_breakpoint) (addr, save)
+#define target_insert_thread_breakpoint(addr, save, threadid) \
+ (current_target.to_insert_thread_breakpoint? \
+ (*current_target.to_insert_thread_breakpoint) (addr, save, threadid): \
+ (*current_target.to_insert_breakpoint) (addr, save))
+
/* Remove a breakpoint at address ADDR in the target machine.
SAVE is a pointer to the same save area
that was previously passed to target_insert_breakpoint.
@@ -640,6 +647,11 @@
#define target_remove_breakpoint(addr, save) \
(*current_target.to_remove_breakpoint) (addr, save)
+#define target_remove_thread_breakpoint(addr, save, threadid) \
+ (current_target.to_remove_thread_breakpoint? \
+ (*current_target.to_remove_thread_breakpoint) (addr, save, threadid): \
+ (*current_target.to_remove_breakpoint) (addr, save))
+
/* Initialize the terminal settings we record for the inferior,
before we actually run the inferior. */
diff -ru gdb-6.1.1o/gdb/v850ice.c gdb-6.1.1/gdb/v850ice.c
--- gdb-6.1.1o/gdb/v850ice.c 2003-10-02 22:28:30.000000000 +0200
+++ gdb-6.1.1/gdb/v850ice.c 2004-09-10 09:25:18.703125000 +0200
@@ -905,6 +905,8 @@
v850ice_ops.to_files_info = v850ice_files_info;
v850ice_ops.to_insert_breakpoint = v850ice_insert_breakpoint;
v850ice_ops.to_remove_breakpoint = v850ice_remove_breakpoint;
+ v850ice_ops.to_insert_thread_breakpoint = NULL;
+ v850ice_ops.to_remove_thread_breakpoint = NULL;
v850ice_ops.to_kill = v850ice_kill;
v850ice_ops.to_load = v850ice_load;
v850ice_ops.to_mourn_inferior = v850ice_mourn;
diff -ru gdb-6.1.1o/gdb/win32-nat.c gdb-6.1.1/gdb/win32-nat.c
--- gdb-6.1.1o/gdb/win32-nat.c 2004-01-05 20:53:08.000000000 +0100
+++ gdb-6.1.1/gdb/win32-nat.c 2004-09-10 09:24:59.984375000 +0200
@@ -2060,6 +2060,8 @@
child_ops.to_files_info = child_files_info;
child_ops.to_insert_breakpoint = memory_insert_breakpoint;
child_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ child_ops.to_insert_thread_breakpoint = NULL;
+ child_ops.to_remove_thread_breakpoint = NULL;
child_ops.to_terminal_init = terminal_init_inferior;
child_ops.to_terminal_inferior = terminal_inferior;
child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
diff -ru gdb-6.1.1o/gdb/wince.c gdb-6.1.1/gdb/wince.c
--- gdb-6.1.1o/gdb/wince.c 2003-11-06 03:52:28.000000000 +0100
+++ gdb-6.1.1/gdb/wince.c 2004-09-10 09:24:50.343750000 +0200
@@ -1908,6 +1908,8 @@
child_ops.to_files_info = child_files_info;
child_ops.to_insert_breakpoint = memory_insert_breakpoint;
child_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ child_ops.to_insert_thread_breakpoint = NULL;
+ child_ops.to_remove_thread_breakpoint = NULL;
child_ops.to_terminal_init = terminal_init_inferior;
child_ops.to_terminal_inferior = terminal_inferior;
child_ops.to_terminal_ours_for_output = terminal_ours_for_output;