From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17692 invoked by alias); 13 Sep 2004 13:03:05 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 17576 invoked from network); 13 Sep 2004 13:02:55 -0000 Received: from unknown (HELO smtp.hispeed.ch) (62.2.95.247) by sourceware.org with SMTP; 13 Sep 2004 13:02:55 -0000 Received: from indel.ch (217-162-27-127.dclient.hispeed.ch [217.162.27.127]) by smtp.hispeed.ch (8.12.6/8.12.6/tornado-1.0) with SMTP id i8DD2pQq014640 for ; Mon, 13 Sep 2004 15:02:51 +0200 Received: from fabi.indel.ch [192.168.1.19] by indel.ch [127.0.0.1] with SMTP (MDaemon.v2.7.SP5.R) for ; Mon, 13 Sep 2004 15:02:47 +0200 Message-Id: <5.2.0.9.1.20040913145416.01d2c858@NT_SERVER> X-Sender: cenedese@NT_SERVER (Unverified) Date: Mon, 13 Sep 2004 13:03:00 -0000 To: gdb@sources.redhat.com From: Fabian Cenedese Subject: Re: Remote set thread breakpoint In-Reply-To: <413F155B.6070003@gnu.org> References: <5.2.0.9.1.20040908160444.01d4c920@NT_SERVER> <5.2.0.9.1.20040908160444.01d4c920@NT_SERVER> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" X-MDaemon-Deliver-To: gdb@sources.redhat.com X-Return-Path: cenedese@indel.ch X-SW-Source: 2004-09/txt/msg00093.txt.bz2 >>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;