2010-07-19 Hui Zhu <teawater@gmail.com>

* breakpoint.c (single_step_breakpoints_inserted): New
	function.
	* breakpoint.h (single_step_breakpoints_inserted): Extern.
	* infrun.c (maybe_software_singlestep): Add check code.
	* record.c (record_resume): Add code for software single step.
	(record_wait): Ditto.
This commit is contained in:
Hui Zhu 2010-07-19 07:55:43 +00:00
parent 06e700d6a2
commit f02253f190
5 changed files with 81 additions and 6 deletions

View File

@ -1,3 +1,12 @@
2010-07-19 Hui Zhu <teawater@gmail.com>
* breakpoint.c (single_step_breakpoints_inserted): New
function.
* breakpoint.h (single_step_breakpoints_inserted): Extern.
* infrun.c (maybe_software_singlestep): Add check code.
* record.c (record_resume): Add code for software single step.
(record_wait): Ditto.
2010-07-18 Jan Kratochvil <jan.kratochvil@redhat.com> 2010-07-18 Jan Kratochvil <jan.kratochvil@redhat.com>
* linux-nat.c (linux_handle_extended_wait): Move variable new_lp into * linux-nat.c (linux_handle_extended_wait): Move variable new_lp into

View File

@ -10726,6 +10726,16 @@ insert_single_step_breakpoint (struct gdbarch *gdbarch,
paddress (gdbarch, next_pc)); paddress (gdbarch, next_pc));
} }
/* Check if the breakpoints used for software single stepping
were inserted or not. */
int
single_step_breakpoints_inserted (void)
{
return (single_step_breakpoints[0] != NULL
|| single_step_breakpoints[1] != NULL);
}
/* Remove and delete any breakpoints used for software single step. */ /* Remove and delete any breakpoints used for software single step. */
void void

View File

@ -1000,6 +1000,7 @@ extern int remove_hw_watchpoints (void);
twice before remove is called. */ twice before remove is called. */
extern void insert_single_step_breakpoint (struct gdbarch *, extern void insert_single_step_breakpoint (struct gdbarch *,
struct address_space *, CORE_ADDR); struct address_space *, CORE_ADDR);
extern int single_step_breakpoints_inserted (void);
extern void remove_single_step_breakpoints (void); extern void remove_single_step_breakpoints (void);
extern void cancel_single_step_breakpoints (void); extern void cancel_single_step_breakpoints (void);

View File

@ -1515,7 +1515,8 @@ maybe_software_singlestep (struct gdbarch *gdbarch, CORE_ADDR pc)
{ {
int hw_step = 1; int hw_step = 1;
if (gdbarch_software_single_step_p (gdbarch) if (execution_direction == EXEC_FORWARD
&& gdbarch_software_single_step_p (gdbarch)
&& gdbarch_software_single_step (gdbarch, get_current_frame ())) && gdbarch_software_single_step (gdbarch, get_current_frame ()))
{ {
hw_step = 0; hw_step = 0;

View File

@ -1011,9 +1011,43 @@ record_resume (struct target_ops *ops, ptid_t ptid, int step,
if (!RECORD_IS_REPLAY) if (!RECORD_IS_REPLAY)
{ {
struct gdbarch *gdbarch = target_thread_architecture (ptid);
record_message (get_current_regcache (), signal); record_message (get_current_regcache (), signal);
record_beneath_to_resume (record_beneath_to_resume_ops, ptid, 1,
signal); if (!step)
{
/* This is not hard single step. */
if (!gdbarch_software_single_step_p (gdbarch))
{
/* This is a normal continue. */
step = 1;
}
else
{
/* This arch support soft sigle step. */
if (single_step_breakpoints_inserted ())
{
/* This is a soft single step. */
record_resume_step = 1;
}
else
{
/* This is a continue.
Try to insert a soft single step breakpoint. */
if (!gdbarch_software_single_step (gdbarch,
get_current_frame ()))
{
/* This system don't want use soft single step.
Use hard sigle step. */
step = 1;
}
}
}
}
record_beneath_to_resume (record_beneath_to_resume_ops,
ptid, step, signal);
} }
} }
@ -1089,12 +1123,16 @@ record_wait (struct target_ops *ops,
/* This is not a single step. */ /* This is not a single step. */
ptid_t ret; ptid_t ret;
CORE_ADDR tmp_pc; CORE_ADDR tmp_pc;
struct gdbarch *gdbarch = target_thread_architecture (inferior_ptid);
while (1) while (1)
{ {
ret = record_beneath_to_wait (record_beneath_to_wait_ops, ret = record_beneath_to_wait (record_beneath_to_wait_ops,
ptid, status, options); ptid, status, options);
if (single_step_breakpoints_inserted ())
remove_single_step_breakpoints ();
if (record_resume_step) if (record_resume_step)
return ret; return ret;
@ -1134,8 +1172,12 @@ record_wait (struct target_ops *ops,
} }
else else
{ {
/* This must be a single-step trap. Record the /* This is a single-step trap. Record the
insn and issue another step. */ insn and issue another step.
FIXME: this part can be a random SIGTRAP too.
But GDB cannot handle it. */
int step = 1;
if (!record_message_wrapper_safe (regcache, if (!record_message_wrapper_safe (regcache,
TARGET_SIGNAL_0)) TARGET_SIGNAL_0))
{ {
@ -1144,8 +1186,20 @@ record_wait (struct target_ops *ops,
break; break;
} }
if (gdbarch_software_single_step_p (gdbarch))
{
/* Try to insert the software single step breakpoint.
If insert success, set step to 0. */
set_executing (inferior_ptid, 0);
reinit_frame_cache ();
if (gdbarch_software_single_step (gdbarch,
get_current_frame ()))
step = 0;
set_executing (inferior_ptid, 1);
}
record_beneath_to_resume (record_beneath_to_resume_ops, record_beneath_to_resume (record_beneath_to_resume_ops,
ptid, 1, ptid, step,
TARGET_SIGNAL_0); TARGET_SIGNAL_0);
continue; continue;
} }