From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21055 invoked by alias); 2 Aug 2005 15:11:59 -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 21026 invoked by uid 22791); 2 Aug 2005 15:11:47 -0000 Received: from zproxy.gmail.com (HELO zproxy.gmail.com) (64.233.162.205) by sourceware.org (qpsmtpd/0.30-dev) with ESMTP; Tue, 02 Aug 2005 15:11:47 +0000 Received: by zproxy.gmail.com with SMTP id x3so851907nze for ; Tue, 02 Aug 2005 08:11:45 -0700 (PDT) Received: by 10.36.81.7 with SMTP id e7mr559858nzb; Tue, 02 Aug 2005 08:11:45 -0700 (PDT) Received: by 10.36.118.14 with HTTP; Tue, 2 Aug 2005 08:11:45 -0700 (PDT) Message-ID: <6f48278f05080208114fb35462@mail.gmail.com> Date: Tue, 02 Aug 2005 15:11:00 -0000 From: Jie Zhang Reply-To: Jie Zhang To: gdb@sources.redhat.com Subject: [RFC] Reinsert the single stepping breakpoint after being hopped over Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline X-SW-Source: 2005-08/txt/msg00010.txt.bz2 Hi, I'm working on a new port of GDB for Blackfin. It's usually used for remote debugging using gdbserver and software single stepping. It has many FAILs for schedlock.exp. I traced these FAILs and, I think, found a bug in GDB. Assume there are two threads in the program and we are stepping on one. (I use GDB for the whole of GDB and gdbserver.) 1. GDB inserts a breakpoint for stepping and resumes both threads. 2. Both threads hit this breakpoint. 3. The first stopped thread GDB looks for (for some reason) is not the thread we are stepping. GDB make it hop over the stepping breakpoint. 4. GDB resume both threads by resume (1, TARGET_SIGNAL_0); So the thread we are stepping will do a new step and the previous stop of step will never be noticed by GDB. (It's caught by gdbserver and saved as a pending status. However, when it stops again for the new step, the previous stepping breakpoint has been removed, so check_removed_breakpoint () will clear status_pending_p and the previous stop is lost.) GDB will never get a chance to check if the stepping is out of the range. The step command will not return. To fix it, GDB should put the previous stepping breakpoint back, not do a new stepping when resuming both threads. The following patch is trying to fix this. It adds a new field "singlestep_breakpoint_addr" in "struct thread_info" to remember the last single stepping breakpoint address. Passing 2 as the second argument to SOFTWARE_SINGLE_STEP () to tell the target software single stepping function that we just reinsert the previous single stepping breakpoint. This is a preliminary patch. It only changes the arm port as an example. I tested this patch, it fixes all FAILs of schedlock.exp for our new port. However, I have no boards of other ports using software single stepping. So I cannot test it. And I'm not sure if this bug is only for remote debugging using gdbserver? Or if this patch will affect native ports using software single stepping? Any thoughts? Jie 2005-08-02 Jie Zhang * arm-tdep.c (arm_software_single_step): Use singlestep_breakpoint_addr. * gdbthread.h (struct thread_info): New field singlestep_breakpoint_addr. (save_infrun_state): New argument singlestep_breakpoint_addr. (load_infrun_state): Likewise. * infcmd.c (singlestep_breakpoint_addr): Define. * inferior.h (singlestep_breakpoint_addr): Declare. * infrun.c (context_switch): Save and load singlestep_breakpoint_addr. (handle_inferior_event): Reinsert the single stepping breakpoint after another thread has hopped over it. * thread.c (save_infrun_state): Save singlestep_breakpoint_addr. (load_infrun_state): Load singlestep_breakpoint_addr. Index: gdb/arm-tdep.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/gdb/arm-tdep.c,v retrieving revision 1.200 diff -u -p -r1.200 arm-tdep.c --- gdb/arm-tdep.c 12 Jun 2005 12:57:21 -0000 1.200 +++ gdb/arm-tdep.c 2 Aug 2005 14:39:02 -0000 @@ -1872,16 +1872,17 @@ arm_get_next_pc (CORE_ADDR pc) static void arm_software_single_step (enum target_signal sig, int insert_bpt) { - static int next_pc; /* State between setting and unsetting. */ static char break_mem[BREAKPOINT_MAX]; /* Temporary storage for mem@bpt = */ =20 if (insert_bpt) { - next_pc =3D arm_get_next_pc (read_register (ARM_PC_REGNUM)); - target_insert_breakpoint (next_pc, break_mem); + if (insert_bpt =3D=3D 1) + singlestep_breakpoint_addr + =3D arm_get_next_pc (read_register (ARM_PC_REGNUM)); + target_insert_breakpoint (singlestep_breakpoint_addr, break_mem); } else - target_remove_breakpoint (next_pc, break_mem); + target_remove_breakpoint (singlestep_breakpoint_addr, break_mem); } =20 #include "bfd-in2.h" Index: gdb/gdbthread.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/gdb/gdbthread.h,v retrieving revision 1.12 diff -u -p -r1.12 gdbthread.h --- gdb/gdbthread.h 25 Aug 2004 15:18:05 -0000 1.12 +++ gdb/gdbthread.h 2 Aug 2005 14:39:02 -0000 @@ -47,6 +47,7 @@ struct thread_info struct breakpoint *step_resume_breakpoint; CORE_ADDR step_range_start; CORE_ADDR step_range_end; + CORE_ADDR singlestep_breakpoint_addr; struct frame_id step_frame_id; int current_line; struct symtab *current_symtab; @@ -114,6 +115,7 @@ extern void save_infrun_state (ptid_t pt struct breakpoint *step_resume_breakpoint, CORE_ADDR step_range_start, CORE_ADDR step_range_end, + CORE_ADDR singlestep_breakpoint_addr, const struct frame_id *step_frame_id, int handling_longjmp, int another_trap, @@ -130,6 +132,7 @@ extern void load_infrun_state (ptid_t pt struct breakpoint **step_resume_breakpoint, CORE_ADDR *step_range_start, CORE_ADDR *step_range_end, + CORE_ADDR *singlestep_breakpoint_addr, struct frame_id *step_frame_id, int *handling_longjmp, int *another_trap, Index: gdb/infcmd.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/gdb/infcmd.c,v retrieving revision 1.139 diff -u -p -r1.139 infcmd.c --- gdb/infcmd.c 6 Jul 2005 14:54:33 -0000 1.139 +++ gdb/infcmd.c 2 Aug 2005 14:39:03 -0000 @@ -181,6 +181,7 @@ int stopped_by_random_signal; =20 CORE_ADDR step_range_start; /* Inclusive */ CORE_ADDR step_range_end; /* Exclusive */ +CORE_ADDR singlestep_breakpoint_addr; =20 /* Stack frame address as of when stepping command was issued. This is how we know when we step into a subroutine call, Index: gdb/inferior.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/gdb/inferior.h,v retrieving revision 1.72 diff -u -p -r1.72 inferior.h --- gdb/inferior.h 6 Jul 2005 14:54:33 -0000 1.72 +++ gdb/inferior.h 2 Aug 2005 14:39:03 -0000 @@ -355,6 +355,7 @@ extern int stopped_by_random_signal; =20 extern CORE_ADDR step_range_start; /* Inclusive */ extern CORE_ADDR step_range_end; /* Exclusive */ +extern CORE_ADDR singlestep_breakpoint_addr; =20 /* Stack frame address as of when stepping command was issued. This is how we know when we step into a subroutine call, Index: gdb/infrun.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/gdb/infrun.c,v retrieving revision 1.203 diff -u -p -r1.203 infrun.c --- gdb/infrun.c 1 Aug 2005 03:32:32 -0000 1.203 +++ gdb/infrun.c 2 Aug 2005 14:39:06 -0000 @@ -1117,8 +1117,8 @@ context_switch (struct execution_control /* Save infrun state for the old thread. */ save_infrun_state (inferior_ptid, prev_pc, trap_expected, step_resume_breakpoint, - step_range_start, - step_range_end, &step_frame_id, + step_range_start, step_range_end, + singlestep_breakpoint_addr, &step_frame_id, ecs->handling_longjmp, ecs->another_trap, ecs->stepping_through_solib_after_catch, ecs->stepping_through_solib_catchpoints, @@ -1127,8 +1127,8 @@ context_switch (struct execution_control /* Load infrun state for the new thread. */ load_infrun_state (ecs->ptid, &prev_pc, &trap_expected, &step_resume_breakpoint, - &step_range_start, - &step_range_end, &step_frame_id, + &step_range_start, &step_range_end, + &singlestep_breakpoint_addr, &step_frame_id, &ecs->handling_longjmp, &ecs->another_trap, &ecs->stepping_through_solib_after_catch, &ecs->stepping_through_solib_catchpoints, @@ -1555,7 +1555,10 @@ handle_inferior_event (struct execution_ if (deprecated_context_hook) deprecated_context_hook (pid_to_thread_id (ecs->ptid)); =20 - resume (1, TARGET_SIGNAL_0); + SOFTWARE_SINGLE_STEP (TARGET_SIGNAL_0, 2); + singlestep_breakpoints_inserted_p =3D 1; + singlestep_ptid =3D inferior_ptid; + resume (0, TARGET_SIGNAL_0); prepare_to_wait (ecs); return; } Index: gdb/thread.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/gdb/thread.c,v retrieving revision 1.46 diff -u -p -r1.46 thread.c --- gdb/thread.c 15 Feb 2005 15:49:22 -0000 1.46 +++ gdb/thread.c 2 Aug 2005 14:39:06 -0000 @@ -297,6 +297,7 @@ load_infrun_state (ptid_t ptid, struct breakpoint **step_resume_breakpoint, CORE_ADDR *step_range_start, CORE_ADDR *step_range_end, + CORE_ADDR *singlestep_breakpoint_addr, struct frame_id *step_frame_id, int *handling_longjmp, int *another_trap, @@ -318,6 +319,7 @@ load_infrun_state (ptid_t ptid, *step_resume_breakpoint =3D tp->step_resume_breakpoint; *step_range_start =3D tp->step_range_start; *step_range_end =3D tp->step_range_end; + *singlestep_breakpoint_addr =3D tp->singlestep_breakpoint_addr; *step_frame_id =3D tp->step_frame_id; *handling_longjmp =3D tp->handling_longjmp; *another_trap =3D tp->another_trap; @@ -338,6 +340,7 @@ save_infrun_state (ptid_t ptid, struct breakpoint *step_resume_breakpoint, CORE_ADDR step_range_start, CORE_ADDR step_range_end, + CORE_ADDR singlestep_breakpoint_addr, const struct frame_id *step_frame_id, int handling_longjmp, int another_trap, @@ -359,6 +362,7 @@ save_infrun_state (ptid_t ptid, tp->step_resume_breakpoint =3D step_resume_breakpoint; tp->step_range_start =3D step_range_start; tp->step_range_end =3D step_range_end; + tp->singlestep_breakpoint_addr =3D singlestep_breakpoint_addr; tp->step_frame_id =3D (*step_frame_id); tp->handling_longjmp =3D handling_longjmp; tp->another_trap =3D another_trap;