* [patch] Single stepping over atomic instruction sets for GDB 6.6
@ 2007-04-23 21:06 Luis Machado
2007-04-28 18:16 ` Jan Kratochvil
0 siblings, 1 reply; 5+ messages in thread
From: Luis Machado @ 2007-04-23 21:06 UTC (permalink / raw)
To: gdb-patches ml
[-- Attachment #1: Type: text/plain, Size: 236 bytes --]
Hi folks,
This is the patch for handling the sigle stepping of atomic instruction
sets previously posted on this list refreshed for the stable version 6.6
of GDB, in case users of this version would like to use it.
Best regards,
Luis
[-- Attachment #2: single_stepping.diff --]
[-- Type: text/x-patch, Size: 20215 bytes --]
2007-04-12 Luis Machado <luisgpm@br.ibm.com>
* gdbarch.sh (software_single_step): Change the return type
from void to int and reformatted some comments to <= 80
columns.
* gdbarch.c, gdbarch.h: Regenerated.
* alpha-tdep.c (alpha_software_single_step): Likewise.
* alpha-tdep.h (alpha_software_single_step): Likewise.
* arm-tdep.c (arm_software_single_step): Likewise.
* cris-tdep.c (cris_software_single_step): Likewise.
* mips-tdep.c (mips_software_single_step): Likewise.
* mips-tdep.h (mips_software_single_step): Likewise.
* rs6000-tdep.c (rs6000_software_single_step): Likewise.
* rs6000-tdep.h (rs6000_software_single_step): Likewise.
* sparc-tdep.c (sparc_software_single_step): Likewise.
* sparc-tdep.h (sparc_software_single_step): Likewise.
* wince.c (wince_software_single_step): Likewise.
* infrun.c (resume): Check the return value from SOFTWARE_SINGLE_STEP
and act accordingly.
* rs6000-tdep.c: Defines masks for POWER instructions that set
and use the reservation flag (LWARX,LDARX,STWCX,STDCX).
* rs6000-tdep.c (deal_with_atomic_sequence): Handles single
stepping through an atomic sequence of instructions.
* rs6000-tdep.c (rs6000_software_single_step): Added a function
call to check if we are stepping through an atomic sequence of
instructions.
* rs6000-tdep.c (rs6000_gdbarch_init): Initializes a function to
check for atomic instruction sequences while single stepping.
Index: gdb/alpha-tdep.c
===================================================================
--- gdb/alpha-tdep.c.orig 2006-08-22 14:31:36.000000000 -0700
+++ gdb/alpha-tdep.c 2007-04-23 10:24:06.000000000 -0700
@@ -1510,7 +1510,7 @@
return (pc + 4);
}
-void
+int
alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p)
{
static CORE_ADDR next_pc;
@@ -1528,6 +1528,7 @@
remove_single_step_breakpoints ();
write_pc (next_pc);
}
+ return 1;
}
\f
Index: gdb/alpha-tdep.h
===================================================================
--- gdb/alpha-tdep.h.orig 2006-07-31 13:15:50.000000000 -0700
+++ gdb/alpha-tdep.h 2007-04-23 10:24:06.000000000 -0700
@@ -107,7 +107,7 @@
};
extern unsigned int alpha_read_insn (CORE_ADDR pc);
-extern void alpha_software_single_step (enum target_signal, int);
+extern int alpha_software_single_step (enum target_signal, int);
extern CORE_ADDR alpha_after_prologue (CORE_ADDR pc);
extern void alpha_mdebug_init_abi (struct gdbarch_info, struct gdbarch *);
Index: gdb/arm-tdep.c
===================================================================
--- gdb/arm-tdep.c.orig 2006-11-12 03:06:31.000000000 -0800
+++ gdb/arm-tdep.c 2007-04-23 10:24:06.000000000 -0700
@@ -1840,7 +1840,7 @@
single_step() is also called just after the inferior stops. If we
had set up a simulated single-step, we undo our damage. */
-static void
+static int
arm_software_single_step (enum target_signal sig, int insert_bpt)
{
/* NOTE: This may insert the wrong breakpoint instruction when
@@ -1855,6 +1855,8 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
#include "bfd-in2.h"
Index: gdb/cris-tdep.c
===================================================================
--- gdb/cris-tdep.c.orig 2006-04-18 12:20:06.000000000 -0700
+++ gdb/cris-tdep.c 2007-04-23 10:24:06.000000000 -0700
@@ -2117,7 +2117,7 @@
digs through the opcodes in order to find all possible targets.
Either one ordinary target or two targets for branches may be found. */
-static void
+static int
cris_software_single_step (enum target_signal ignore, int insert_breakpoints)
{
inst_env_type inst_env;
@@ -2150,6 +2150,8 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
/* Calculates the prefix value for quick offset addressing mode. */
Index: gdb/gdbarch.c
===================================================================
--- gdb/gdbarch.c.orig 2006-11-10 11:20:35.000000000 -0800
+++ gdb/gdbarch.c 2007-04-23 10:24:06.000000000 -0700
@@ -3273,14 +3273,14 @@
return gdbarch->software_single_step != NULL;
}
-void
+int
gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p)
{
gdb_assert (gdbarch != NULL);
gdb_assert (gdbarch->software_single_step != NULL);
if (gdbarch_debug >= 2)
fprintf_unfiltered (gdb_stdlog, "gdbarch_software_single_step called\n");
- gdbarch->software_single_step (sig, insert_breakpoints_p);
+ return gdbarch->software_single_step (sig, insert_breakpoints_p);
}
void
Index: gdb/gdbarch.h
===================================================================
--- gdb/gdbarch.h.orig 2006-11-10 11:20:36.000000000 -0800
+++ gdb/gdbarch.h 2007-04-23 10:24:06.000000000 -0700
@@ -1140,14 +1140,19 @@
#define SMASH_TEXT_ADDRESS(addr) (gdbarch_smash_text_address (current_gdbarch, addr))
#endif
-/* FIXME/cagney/2001-01-18: This should be split in two. A target method that indicates if
- the target needs software single step. An ISA method to implement it.
+/* FIXME/cagney/2001-01-18: This should be split in two. A target method that
+ indicates if the target needs software single step. An ISA method to
+ implement it.
- FIXME/cagney/2001-01-18: This should be replaced with something that inserts breakpoints
- using the breakpoint system instead of blatting memory directly (as with rs6000).
+ FIXME/cagney/2001-01-18: This should be replaced with something that inserts
+ breakpoints using the breakpoint system instead of blatting memory directly
+ (as with rs6000).
- FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the target can
- single step. If not, then implement single step using breakpoints. */
+ FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the
+ target can single step. If not, then implement single step using breakpoints.
+
+ A return value of 1 means that the software_single_step breakpoints
+ were inserted; 0 means they were not. */
#if defined (SOFTWARE_SINGLE_STEP)
/* Legacy for systems yet to multi-arch SOFTWARE_SINGLE_STEP */
@@ -1164,8 +1169,8 @@
#define SOFTWARE_SINGLE_STEP_P() (gdbarch_software_single_step_p (current_gdbarch))
#endif
-typedef void (gdbarch_software_single_step_ftype) (enum target_signal sig, int insert_breakpoints_p);
-extern void gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p);
+typedef int (gdbarch_software_single_step_ftype) (enum target_signal sig, int insert_breakpoints_p);
+extern int gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p);
extern void set_gdbarch_software_single_step (struct gdbarch *gdbarch, gdbarch_software_single_step_ftype *software_single_step);
#if !defined (GDB_TM_FILE) && defined (SOFTWARE_SINGLE_STEP)
#error "Non multi-arch definition of SOFTWARE_SINGLE_STEP"
Index: gdb/gdbarch.sh
===================================================================
--- gdb/gdbarch.sh.orig 2006-11-10 11:20:36.000000000 -0800
+++ gdb/gdbarch.sh 2007-04-23 10:24:06.000000000 -0700
@@ -601,15 +601,22 @@
# It is not at all clear why SMASH_TEXT_ADDRESS is not folded into
# ADDR_BITS_REMOVE.
f:=:CORE_ADDR:smash_text_address:CORE_ADDR addr:addr::core_addr_identity::0
-# FIXME/cagney/2001-01-18: This should be split in two. A target method that indicates if
-# the target needs software single step. An ISA method to implement it.
+
+# FIXME/cagney/2001-01-18: This should be split in two. A target method that
+# indicates if the target needs software single step. An ISA method to
+# implement it.
+#
+# FIXME/cagney/2001-01-18: This should be replaced with something that inserts
+# breakpoints using the breakpoint system instead of blatting memory directly
+# (as with rs6000).
#
-# FIXME/cagney/2001-01-18: This should be replaced with something that inserts breakpoints
-# using the breakpoint system instead of blatting memory directly (as with rs6000).
+# FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the
+# target can single step. If not, then implement single step using breakpoints.
#
-# FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the target can
-# single step. If not, then implement single step using breakpoints.
-F:=:void:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p
+# A return value of 1 means that the software_single_step breakpoints
+# were inserted; 0 means they were not.
+F:=:int:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p
+
# Return non-zero if the processor is executing a delay slot and a
# further single-step is needed before the instruction finishes.
M::int:single_step_through_delay:struct frame_info *frame:frame
Index: gdb/infrun.c
===================================================================
--- gdb/infrun.c.orig 2006-10-18 09:56:13.000000000 -0700
+++ gdb/infrun.c 2007-04-23 10:24:06.000000000 -0700
@@ -557,13 +557,15 @@
if (SOFTWARE_SINGLE_STEP_P () && step)
{
/* Do it the hard way, w/temp breakpoints */
- SOFTWARE_SINGLE_STEP (sig, 1 /*insert-breakpoints */ );
- /* ...and don't ask hardware to do it. */
- step = 0;
- /* and do not pull these breakpoints until after a `wait' in
- `wait_for_inferior' */
- singlestep_breakpoints_inserted_p = 1;
- singlestep_ptid = inferior_ptid;
+ if (SOFTWARE_SINGLE_STEP (sig, 1 /*insert-breakpoints */ ))
+ {
+ /* ...and don't ask hardware to do it. */
+ step = 0;
+ /* and do not pull these breakpoints until after a `wait' in
+ `wait_for_inferior' */
+ singlestep_breakpoints_inserted_p = 1;
+ singlestep_ptid = inferior_ptid;
+ }
}
/* If there were any forks/vforks/execs that were caught and are
@@ -1382,7 +1384,7 @@
(LONGEST) ecs->ws.value.integer));
gdb_flush (gdb_stdout);
target_mourn_inferior ();
- singlestep_breakpoints_inserted_p = 0; /*SOFTWARE_SINGLE_STEP_P() */
+ singlestep_breakpoints_inserted_p = 0; /* SOFTWARE_SINGLE_STEP_P() */
stop_print_frame = 0;
stop_stepping (ecs);
return;
@@ -1402,7 +1404,7 @@
target_mourn_inferior ();
print_stop_reason (SIGNAL_EXITED, stop_signal);
- singlestep_breakpoints_inserted_p = 0; /*SOFTWARE_SINGLE_STEP_P() */
+ singlestep_breakpoints_inserted_p = 0; /* SOFTWARE_SINGLE_STEP_P() */
stop_stepping (ecs);
return;
@@ -1576,7 +1578,7 @@
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog, "infrun: stepping_past_singlestep_breakpoint\n");
/* Pull the single step breakpoints out of the target. */
- SOFTWARE_SINGLE_STEP (0, 0);
+ (void) SOFTWARE_SINGLE_STEP (0, 0);
singlestep_breakpoints_inserted_p = 0;
ecs->random_signal = 0;
@@ -1640,7 +1642,7 @@
if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
{
/* Pull the single step breakpoints out of the target. */
- SOFTWARE_SINGLE_STEP (0, 0);
+ (void) SOFTWARE_SINGLE_STEP (0, 0);
singlestep_breakpoints_inserted_p = 0;
}
@@ -1713,7 +1715,7 @@
if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
{
/* Pull the single step breakpoints out of the target. */
- SOFTWARE_SINGLE_STEP (0, 0);
+ (void) SOFTWARE_SINGLE_STEP (0, 0);
singlestep_breakpoints_inserted_p = 0;
}
Index: gdb/mips-tdep.c
===================================================================
--- gdb/mips-tdep.c.orig 2006-08-08 14:32:37.000000000 -0700
+++ gdb/mips-tdep.c 2007-04-23 10:24:06.000000000 -0700
@@ -2185,7 +2185,7 @@
single_step is also called just after the inferior stops. If we had
set up a simulated single-step, we undo our damage. */
-void
+int
mips_software_single_step (enum target_signal sig, int insert_breakpoints_p)
{
CORE_ADDR pc, next_pc;
@@ -2199,6 +2199,8 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
/* Test whether the PC points to the return instruction at the
Index: gdb/mips-tdep.h
===================================================================
--- gdb/mips-tdep.h.orig 2005-12-17 14:34:01.000000000 -0800
+++ gdb/mips-tdep.h 2007-04-23 10:24:06.000000000 -0700
@@ -103,7 +103,7 @@
};
/* Single step based on where the current instruction will take us. */
-extern void mips_software_single_step (enum target_signal, int);
+extern int mips_software_single_step (enum target_signal, int);
/* Tell if the program counter value in MEMADDR is in a MIPS16
function. */
Index: gdb/rs6000-tdep.c
===================================================================
--- gdb/rs6000-tdep.c.orig 2007-04-23 10:24:05.000000000 -0700
+++ gdb/rs6000-tdep.c 2007-04-23 10:24:06.000000000 -0700
@@ -701,10 +701,98 @@
return little_breakpoint;
}
+#define LWARX_MASK 0xfc0007fe
+#define LWARX_INSTRUCTION 0x7c000028
+#define LDARX_INSTRUCTION 0x7c0000A8
+#define STWCX_MASK 0xfc0007ff
+#define STWCX_INSTRUCTION 0x7c00012d
+#define STDCX_INSTRUCTION 0x7c0001ad
+#define BC_MASK 0xfc000000
+#define BC_INSTRUCTION 0x40000000
+#define IMMEDIATE_PART(insn) (((insn & ~3) << 16) >> 16)
+#define ABSOLUTE_P(insn) ((int) ((insn >> 1) & 1))
+
+static int
+deal_with_atomic_sequence (enum target_signal sig, int insert_breakpoints_p)
+{
+ CORE_ADDR pc = read_pc ();
+ CORE_ADDR breaks[2] = {-1, -1};
+ CORE_ADDR loc = pc;
+ int insn = read_memory_integer (loc, PPC_INSN_SIZE);
+ int last_break = 0;
+ int i;
-/* AIX does not support PT_STEP. Simulate it. */
+ if (insert_breakpoints_p)
+ {
+
+ /* Assume all atomic sequences start with an lwarx or ldarx instruction. */
+ if ((insn & LWARX_MASK) != LWARX_INSTRUCTION
+ && (insn & LWARX_MASK) != LDARX_INSTRUCTION)
+ return 0;
+
+ /* Assume that no atomic sequence is longer than 6 instructions. */
+ for (i = 1; i < 5; ++i)
+ {
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
+
+ /* Assume at most one conditional branch instruction between
+ the lwarx and stwcx instructions.*/
+ if ((insn & BC_MASK) == BC_INSTRUCTION)
+ {
+ last_break = 1;
+ breaks[1] = IMMEDIATE_PART (insn);
+ if ( ! ABSOLUTE_P(insn))
+ breaks[1] += loc;
+ continue;
+ }
-void
+ if ((insn & STWCX_MASK) == STWCX_INSTRUCTION
+ || (insn & STWCX_MASK) == STDCX_INSTRUCTION)
+ break;
+ }
+
+ /* Assume that the atomic sequence ends with a stwcx instruction
+ followed by a conditional branch instruction. */
+ if ((insn & STWCX_MASK) != STWCX_INSTRUCTION
+ && (insn & STWCX_MASK) != STDCX_INSTRUCTION)
+ warning (_("Tried to step over an atomic sequence of instructions at %s\n \
+ but could not find the end of the sequence."),
+ core_addr_to_string(pc));
+
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
+
+ if ((insn & BC_MASK) != BC_INSTRUCTION)
+ warning (_("Tried to step over an atomic sequence of instructions at %s\n \
+ but the instruction sequence ended in an unexpected way."),
+ core_addr_to_string(pc));
+
+ breaks[0] = loc;
+
+ /* This should never happen, but make sure we don't put
+ two breakpoints on the same address. */
+ if (last_break && breaks[1] == breaks[0])
+ last_break = 0;
+
+ for (i = 0; i <= last_break; ++i)
+ insert_single_step_breakpoint (breaks[i]);
+
+ printf_unfiltered (_("Stepping over an atomic sequence of instructions beginning at %s\n"),
+ core_addr_to_string (pc));
+
+ gdb_flush (gdb_stdout);
+ }
+ else
+ remove_single_step_breakpoints();
+
+ return 1;
+}
+
+/* AIX does not support PT_STEP. Simulate it, dealing with any sequence of
+ instructions that must be atomic. */
+
+int
rs6000_software_single_step (enum target_signal signal,
int insert_breakpoints_p)
{
@@ -722,6 +810,9 @@
insn = read_memory_integer (loc, 4);
+ if (deal_with_atomic_sequence (signal, insert_breakpoints_p))
+ return 1;
+
breaks[0] = loc + breakp_sz;
opcode = insn >> 26;
breaks[1] = branch_dest (opcode, insn, loc, breaks[0]);
@@ -743,6 +834,8 @@
errno = 0; /* FIXME, don't ignore errors! */
/* What errors? {read,write}_memory call error(). */
+
+ return 1;
}
@@ -3447,6 +3540,9 @@
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc);
+ /* Watch for locking instruction sequences during single stepping */
+ set_gdbarch_software_single_step(gdbarch, deal_with_atomic_sequence);
+
/* Handle the 64-bit SVR4 minimal-symbol convention of using "FN"
for the descriptor and ".FN" for the entry-point -- a user
specifying "break FN" will unexpectedly end up with a breakpoint
Index: gdb/rs6000-tdep.h
===================================================================
--- gdb/rs6000-tdep.h.orig 2006-02-10 12:56:14.000000000 -0800
+++ gdb/rs6000-tdep.h 2007-04-23 10:24:06.000000000 -0700
@@ -21,6 +21,6 @@
#include "defs.h"
-extern void rs6000_software_single_step (enum target_signal signal,
- int insert_breakpoints_p);
+extern int rs6000_software_single_step (enum target_signal signal,
+ int insert_breakpoints_p);
Index: gdb/sparc-tdep.c
===================================================================
--- gdb/sparc-tdep.c.orig 2006-11-09 08:36:58.000000000 -0800
+++ gdb/sparc-tdep.c 2007-04-23 10:24:06.000000000 -0700
@@ -1131,7 +1131,7 @@
return 0;
}
-void
+int
sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p)
{
struct gdbarch *arch = current_gdbarch;
@@ -1161,6 +1161,8 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
static void
Index: gdb/sparc-tdep.h
===================================================================
--- gdb/sparc-tdep.h.orig 2006-01-22 12:07:38.000000000 -0800
+++ gdb/sparc-tdep.h 2007-04-23 10:24:06.000000000 -0700
@@ -167,8 +167,8 @@
\f
-extern void sparc_software_single_step (enum target_signal sig,
- int insert_breakpoints_p);
+extern int sparc_software_single_step (enum target_signal sig,
+ int insert_breakpoints_p);
extern void sparc_supply_rwindow (struct regcache *regcache,
CORE_ADDR sp, int regnum);
Index: gdb/wince.c
===================================================================
--- gdb/wince.c.orig 2006-04-18 12:20:06.000000000 -0700
+++ gdb/wince.c 2007-04-23 10:24:06.000000000 -0700
@@ -838,7 +838,7 @@
}
}
-void
+int
wince_software_single_step (enum target_signal ignore,
int insert_breakpoints_p)
{
@@ -850,14 +850,15 @@
if (!insert_breakpoints_p)
{
undoSStep (th);
- return;
+ return 1;
}
th->stepped = 1;
pc = read_register (PC_REGNUM);
th->step_pc = mips_next_pc (pc);
insert_single_step_breakpoint (th->step_pc);
- return;
+
+ return 1;
}
#elif SHx
/* Renesas SH architecture instruction encoding masks */
@@ -979,7 +980,7 @@
instruction and setting a breakpoint on the "next" instruction
which would be executed. This code hails from sh-stub.c.
*/
-void
+int
wince_software_single_step (enum target_signal ignore,
int insert_breakpoints_p)
{
@@ -989,13 +990,14 @@
if (!insert_breakpoints_p)
{
undoSStep (th);
- return;
+ return 1;
}
th->stepped = 1;
th->step_pc = sh_get_next_pc (&th->context);
insert_single_step_breakpoint (th->step_pc);
- return;
+
+ return 1;
}
#elif defined (ARM)
#undef check_for_step
@@ -1026,7 +1028,7 @@
}
}
-void
+int
wince_software_single_step (enum target_signal ignore,
int insert_breakpoints_p)
{
@@ -1038,14 +1040,15 @@
if (!insert_breakpoints_p)
{
undoSStep (th);
- return;
+ return 1;
}
th->stepped = 1;
pc = read_register (PC_REGNUM);
th->step_pc = arm_get_next_pc (pc);
insert_single_step_breakpoint (th->step_pc);
- return;
+
+ return 1;
}
#endif
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [patch] Single stepping over atomic instruction sets for GDB 6.6
2007-04-23 21:06 [patch] Single stepping over atomic instruction sets for GDB 6.6 Luis Machado
@ 2007-04-28 18:16 ` Jan Kratochvil
2007-04-28 23:37 ` Luis Machado
0 siblings, 1 reply; 5+ messages in thread
From: Jan Kratochvil @ 2007-04-28 18:16 UTC (permalink / raw)
To: Luis Machado; +Cc: gdb-patches ml
[-- Attachment #1: Type: text/plain, Size: 1240 bytes --]
On Mon, 23 Apr 2007 20:19:31 +0200, Luis Machado wrote:
...
> This is the patch for handling the sigle stepping of atomic instruction
> sets previously posted on this list refreshed for the stable version 6.6
> of GDB, in case users of this version would like to use it.
It fails for me on the attached testcase on gdb-6.6.ppc64 in 99% cases with
infrun.c:1567: internal-error: handle_inferior_event: Assertion `SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p' failed.
(tested on 4x CPU POWER5+, kernel-2.6.18-8.1.1.el5.ppc64)
The attached patch ON TOP OF YOURS fixes this problem (mostly, see below).
This patch has not been ported to HEAD as the last CVS version of your patch
I found is
http://sourceware.org/ml/gdb-patches/2007-03/msg00145.html
which is no longer applicable to HEAD, please update it.
--
This fix is not 100%, though, it now passes only in 93% cases, in the remaining
7% of cases it will prematurely FAIL due to (missed breakpoint)
Program exited normally.
I believe it is not a failure of this fix but some unrelated PPC port problem.
Unfortunately this "Program exited normally." FAIL becomes unreproducible while
trying to debug it (`set debug infrun 1'), there is some race.
Regards,
Jan
[-- Attachment #2: gdb-6.6-stepping_past_singlestep.patch --]
[-- Type: text/plain, Size: 7508 bytes --]
2007-04-28 Jan Kratochvil <jan.kratochvil@redhat.com>
* infrun.c (handle_inferior_event): Handle
(STEPPING_PAST_SINGLESTEP_BREAKPOINT
&& !SINGLESTEP_BREAKPOINTS_INSERTED_P).
2007-04-28 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.threads/atomic-step-mass-join.c,
gdb.threads/atomic-step-mass-join.exp: New files.
diff -u -rup gdb-6.6-orig/gdb/infrun.c gdb-6.6/gdb/infrun.c
--- gdb-6.6-orig/gdb/infrun.c 2006-10-18 18:56:13.000000000 +0200
+++ gdb-6.6/gdb/infrun.c 2007-04-28 19:23:08.000000000 +0200
@@ -1561,10 +1561,17 @@ handle_inferior_event (struct execution_
if (stepping_past_singlestep_breakpoint)
{
- gdb_assert (SOFTWARE_SINGLE_STEP_P ()
- && singlestep_breakpoints_inserted_p);
- gdb_assert (ptid_equal (singlestep_ptid, ecs->ptid));
- gdb_assert (!ptid_equal (singlestep_ptid, saved_singlestep_ptid));
+ gdb_assert (SOFTWARE_SINGLE_STEP_P ());
+ /* SINGLESTEP_BREAKPOINTS_INSERTED_P is 0 if the another thread which hit
+ the singlestep breakpoint intended for SAVED_SINGLESTEP_PTID is not
+ right now at the atomic sequence. SINGLESTEP_PTID is not defined in
+ such case. SINGLESTEP_BREAKPOINTS_INSERTED_P is 1 when both the
+ SAVED_SINGLESTEP_PTID thread and the SINGLESTEP_PTID thread skip over
+ an atomic sequence, possibly a different one. */
+ gdb_assert (!singlestep_breakpoints_inserted_p
+ || ptid_equal (singlestep_ptid, ecs->ptid));
+ gdb_assert (!singlestep_breakpoints_inserted_p
+ || !ptid_equal (singlestep_ptid, saved_singlestep_ptid));
stepping_past_singlestep_breakpoint = 0;
@@ -1575,9 +1582,13 @@ handle_inferior_event (struct execution_
{
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog, "infrun: stepping_past_singlestep_breakpoint\n");
- /* Pull the single step breakpoints out of the target. */
- (void) SOFTWARE_SINGLE_STEP (0, 0);
- singlestep_breakpoints_inserted_p = 0;
+
+ if (singlestep_breakpoints_inserted_p)
+ {
+ /* Pull the single step breakpoints out of the target. */
+ (void) SOFTWARE_SINGLE_STEP (0, 0);
+ singlestep_breakpoints_inserted_p = 0;
+ }
ecs->random_signal = 0;
diff -u -rup gdb-6.6-orig/gdb/testsuite/gdb.threads/atomic-step-mass-join.c gdb-6.6/gdb/testsuite/gdb.threads/atomic-step-mass-join.c
--- gdb-6.6-orig/gdb/testsuite/gdb.threads/atomic-step-mass-join.c 2007-04-28 19:43:46.000000000 +0200
+++ gdb-6.6/gdb/testsuite/gdb.threads/atomic-step-mass-join.c 2007-04-28 19:24:15.000000000 +0200
@@ -0,0 +1,57 @@
+/* Test case for stepping over RISC atomic code constructs.
+
+ Copyright 2007
+ free software foundation, inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <pthread.h>
+#include <assert.h>
+#include <unistd.h>
+
+static volatile int var;
+
+static void *start (void *arg)
+{
+ /* Do not start quitting before all the threads were spawn. */
+ sleep (5);
+
+ return arg;
+}
+
+#define LENGTH(x) (sizeof (x) / sizeof (x)[0])
+
+int main (void)
+{
+ pthread_t thread[20];
+ int i, j;
+
+ var = 0;
+ for (j = 0; j < LENGTH (thread); j++)
+ {
+ i = pthread_create (&thread[j], NULL, start, NULL); /* _create_ */
+ assert (i == 0);
+ }
+ for (j = 0; j < LENGTH (thread); j++)
+ {
+ i = pthread_join (thread[j], NULL); /* _delete_ */
+ assert (i == 0);
+ }
+
+ return 0; /* _quit_ */
+}
diff -u -rup gdb-6.6-orig/gdb/testsuite/gdb.threads/atomic-step-mass-join.exp gdb-6.6/gdb/testsuite/gdb.threads/atomic-step-mass-join.exp
--- gdb-6.6-orig/gdb/testsuite/gdb.threads/atomic-step-mass-join.exp 2007-04-28 19:43:46.000000000 +0200
+++ gdb-6.6/gdb/testsuite/gdb.threads/atomic-step-mass-join.exp 2007-04-28 19:42:25.000000000 +0200
@@ -0,0 +1,93 @@
+# atomic-step-mass-join.exp -- Test case for stepping over RISC atomic code constructs.
+# Copyright (C) 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+set testfile atomic-step-mass-join
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [istarget "*-*-linux"] then {
+ set target_cflags "-D_MIT_POSIX_THREADS"
+} else {
+ set target_cflags ""
+}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_load ${binfile}
+if ![runto_main] then {
+ fail "Can't run to main"
+ return 0
+}
+
+# With a watchpoint we would crash on pthread_create(3):
+# Program received signal SIGSTOP, Stopped (signal).
+# [Switching to Thread 4160681152 (LWP 979)]
+# 0x0f55c368 in clone () from /lib/libc.so.6
+# Still it is not applicable so far due to:
+# [New Thread 4139709632 (LWP 9022)]^M
+# 0x0f354a28 in __nptl_create_event () from /lib/libpthread.so.0^M
+# ptrace: No such process.^M
+#gdb_test "handle SIGSTOP nostop noprint pass" \
+# ".*SIGSTOP +No\tNo\tYes\t+Stopped \\(signal\\)" \
+# "Disown SIGSTOP"
+
+set line [gdb_get_line_number "_delete_"]
+gdb_test "tbreak $line" \
+ "Breakpoint (\[0-9\]+) at .*$srcfile, line $line\..*" \
+ "set breakpoint at delete"
+gdb_test "c" \
+ ".*/\\* _delete_ \\*/.*" \
+ "run till _delete_"
+
+# Without a software watchpoint no single-stepping would be used.
+set test "Start (software) watchpoint"
+gdb_test_multiple "watch var" $test {
+ -re "Watchpoint \[0-9\]+: var.*$gdb_prompt $" {
+ pass $test
+ }
+ -re "Hardware watchpoint \[0-9\]+: var.*$gdb_prompt $" {
+ # We do not test the goal but still the whole testcase should pass.
+ unsupported $test
+ }
+}
+
+###gdb_test "set debug infrun 1" ""
+
+set line [gdb_get_line_number "_quit_"]
+gdb_test "tbreak $line" \
+ "Breakpoint \[0-9\]+ at .*$srcfile, line $line\..*" \
+ "set breakpoint at _quit_"
+set timeout_old $timeout
+# 20 threads may take about 45 seconds. */
+set timeout 180
+gdb_test "c" \
+ ".*/\\* _quit_ \\*/.*" \
+ "run till _quit_"
+set timeout $timeout_old
+
+gdb_test "c" \
+ ".*Program exited normally\\." \
+ "run till program exit"
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [patch] Single stepping over atomic instruction sets for GDB 6.6
2007-04-28 18:16 ` Jan Kratochvil
@ 2007-04-28 23:37 ` Luis Machado
2007-04-29 15:50 ` Jan Kratochvil
0 siblings, 1 reply; 5+ messages in thread
From: Luis Machado @ 2007-04-28 23:37 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: gdb-patches ml
Jan,
I've sent a version for CVS HEAD, but it seems it didn't make its way to
the list. I re-submitted it now. You should have access to it through
this url:
http://sourceware.org/ml/gdb-patches/2007-04/msg00386.html
I'd like to better understand your patch. So please, if you could go
through the modifications, that would be nice.
Thanks for the update!
Best Regards,
Luis
On Sat, 2007-04-28 at 19:56 +0200, Jan Kratochvil wrote:
> On Mon, 23 Apr 2007 20:19:31 +0200, Luis Machado wrote:
> ...
> > This is the patch for handling the sigle stepping of atomic instruction
> > sets previously posted on this list refreshed for the stable version 6.6
> > of GDB, in case users of this version would like to use it.
>
> It fails for me on the attached testcase on gdb-6.6.ppc64 in 99% cases with
> infrun.c:1567: internal-error: handle_inferior_event: Assertion `SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p' failed.
> (tested on 4x CPU POWER5+, kernel-2.6.18-8.1.1.el5.ppc64)
>
> The attached patch ON TOP OF YOURS fixes this problem (mostly, see below).
>
> This patch has not been ported to HEAD as the last CVS version of your patch
> I found is
> http://sourceware.org/ml/gdb-patches/2007-03/msg00145.html
> which is no longer applicable to HEAD, please update it.
>
> --
>
> This fix is not 100%, though, it now passes only in 93% cases, in the remaining
> 7% of cases it will prematurely FAIL due to (missed breakpoint)
> Program exited normally.
>
> I believe it is not a failure of this fix but some unrelated PPC port problem.
> Unfortunately this "Program exited normally." FAIL becomes unreproducible while
> trying to debug it (`set debug infrun 1'), there is some race.
>
>
> Regards,
> Jan
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [patch] Single stepping over atomic instruction sets for GDB 6.6
2007-04-28 23:37 ` Luis Machado
@ 2007-04-29 15:50 ` Jan Kratochvil
2007-04-30 20:26 ` Luis Machado
0 siblings, 1 reply; 5+ messages in thread
From: Jan Kratochvil @ 2007-04-29 15:50 UTC (permalink / raw)
To: Luis Machado; +Cc: gdb-patches ml
On Sun, 29 Apr 2007 01:35:41 +0200, Luis Machado wrote:
...
> I'd like to better understand your patch. So please, if you could go
> through the modifications, that would be nice.
Your patch sets SINGLESTEP_BREAKPOINTS_INSERTED_P conditionally, according to
whether SOFTWARE_SINGLE_STEP () was successful.
SINGLESTEP_BREAKPOINTS_INSERTED_P was always set before so the original GDB
code does not expect it can be unset.
I have updated the code to handle the case when SOFTWARE_SINGLE_STEP () failed
(and so SINGLESTEP_BREAKPOINTS_INSERTED_P is unset; it could safely fail to
software singlestep because hardware singlestepping feature is available).
Regards,
Jan
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [patch] Single stepping over atomic instruction sets for GDB 6.6
2007-04-29 15:50 ` Jan Kratochvil
@ 2007-04-30 20:26 ` Luis Machado
0 siblings, 0 replies; 5+ messages in thread
From: Luis Machado @ 2007-04-30 20:26 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: gdb-patches ml
Thanks Jan,
I think your patch could be applied on top of the first piece of the
single stepping patch, the one that actually changed code on infrun.c.
It's already in HEAD.
http://sourceware.org/ml/gdb-cvs/2007-04/msg00043.html
Regards,
Luis
On Sun, 2007-04-29 at 09:07 +0200, Jan Kratochvil wrote:
> On Sun, 29 Apr 2007 01:35:41 +0200, Luis Machado wrote:
> ...
> > I'd like to better understand your patch. So please, if you could go
> > through the modifications, that would be nice.
>
> Your patch sets SINGLESTEP_BREAKPOINTS_INSERTED_P conditionally, according to
> whether SOFTWARE_SINGLE_STEP () was successful.
> SINGLESTEP_BREAKPOINTS_INSERTED_P was always set before so the original GDB
> code does not expect it can be unset.
>
> I have updated the code to handle the case when SOFTWARE_SINGLE_STEP () failed
> (and so SINGLESTEP_BREAKPOINTS_INSERTED_P is unset; it could safely fail to
> software singlestep because hardware singlestepping feature is available).
>
>
> Regards,
> Jan
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2007-04-30 20:19 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-04-23 21:06 [patch] Single stepping over atomic instruction sets for GDB 6.6 Luis Machado
2007-04-28 18:16 ` Jan Kratochvil
2007-04-28 23:37 ` Luis Machado
2007-04-29 15:50 ` Jan Kratochvil
2007-04-30 20:26 ` Luis Machado
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox