* Breakpoints in delay slots
@ 2006-10-18 10:59 Andrew STUBBS
2006-10-18 14:04 ` Daniel Jacobowitz
` (4 more replies)
0 siblings, 5 replies; 11+ messages in thread
From: Andrew STUBBS @ 2006-10-18 10:59 UTC (permalink / raw)
To: GDB List
Hi all,
There is an occasional issue debugging programs on processors that use
delay slots - in my case the SH4.
The problem occurs when a breakpoint is placed on the delay slot
instruction. This can happen when this instruction happens to be the
first instruction of a source line, or when the user sets the breakpoint
on a specific address.
In the case of the SH4, the breakpoint instruction (at least the one we
use) is illegal in a delay slot. This means that, instead of triggering
the breakpoint, an illegal slot exception is raised which the user
program is expected to handle and usually results in a panic.
In any case, even if the breakpoint were handled as normal, there is the
problem of where the program should be resumed. It is incorrect to set
the PC to the slot instruction because this will ignore the branch. The
correct thing is to set the PC to the address of the branch/slot pair -
i.e. 2 bytes back in the case of the SH4.
There is no general way to identify a delay slot from instruction
analysis - any instruction may be preceded by data which looks like a
branch with a slot, and there is the danger of reading addresses outside
memory - so there is no way to avoid the situation in the first place.
Similarly, there is no way to identify that a breakpoint just hit was in
a slot unless you make a note of how it was hit.
I need a way to solve this problem. Any suggestions?
In a bare machine context, I have access to the running program's
exception handler so I considered putting an exception handler in which
would identify exceptions caused by breakpoints and trigger an
artificial breakpoint. This would stop the program and return control to
the debugger, but GDB would not identify this as a breakpoint it knows
about and the registers and source code location would all be confused.
Then, upon restarting the program, the handler would return to the
branch/slot pair, but the breakpoint would still be there, and the
program would enter an infinite loop.
The above technique might work if GDB could be taught to understand the
artificial breakpoint. Perhaps it could check unknown traps to see if
they occur at a particular symbol name or there is a particular pattern
at that location (something non-specific defined by the *-tdep file),
and then take steps to fix-up the situation.
Alternatively, in some configurations at least, GDB could set a hidden
breakpoint on the exception handler and somehow prevent the user program
from ever seeing the exception. However, although this might work for
me, it won't work for any configuration in which a remote stub uses the
normal trap mechanism for breakpoints - exceptions in exception handlers
are bad.
In Linux, or some other operating system where the program does not own
the exception handler, part of this problem will have to be solved in
the kernel, but I don't believe it can be fixed-up transparently so that
the debugger can't tell - there is still the issue of where to restart;
GDB will tell it to restart at the breakpoint address, not the branch
address.
Andrew Stubbs
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: Breakpoints in delay slots
2006-10-18 10:59 Breakpoints in delay slots Andrew STUBBS
@ 2006-10-18 14:04 ` Daniel Jacobowitz
2006-10-18 18:51 ` Michael Snyder
` (3 subsequent siblings)
4 siblings, 0 replies; 11+ messages in thread
From: Daniel Jacobowitz @ 2006-10-18 14:04 UTC (permalink / raw)
To: gdb
On Wed, Oct 18, 2006 at 11:59:08AM +0100, Andrew STUBBS wrote:
> Hi all,
>
> There is an occasional issue debugging programs on processors that use
> delay slots - in my case the SH4.
>
> The problem occurs when a breakpoint is placed on the delay slot
> instruction. This can happen when this instruction happens to be the
> first instruction of a source line, or when the user sets the breakpoint
> on a specific address.
>
> In the case of the SH4, the breakpoint instruction (at least the one we
> use) is illegal in a delay slot. This means that, instead of triggering
> the breakpoint, an illegal slot exception is raised which the user
> program is expected to handle and usually results in a panic.
>
> In any case, even if the breakpoint were handled as normal, there is the
> problem of where the program should be resumed. It is incorrect to set
> the PC to the slot instruction because this will ignore the branch. The
> correct thing is to set the PC to the address of the branch/slot pair -
> i.e. 2 bytes back in the case of the SH4.
>
> There is no general way to identify a delay slot from instruction
> analysis - any instruction may be preceded by data which looks like a
> branch with a slot, and there is the danger of reading addresses outside
> memory - so there is no way to avoid the situation in the first place.
> Similarly, there is no way to identify that a breakpoint just hit was in
> a slot unless you make a note of how it was hit.
>
> I need a way to solve this problem. Any suggestions?
This is a remarkable mess. Unsurprisingly you aren't the first person
to have this sort of problem, so GDB has a certain amount of support
for delay slots, but MIPS at least is much friendlier: you can use the
same breakpoint instruction, and there's a bit in the cause register
that lets you know you were in a delay slot.
When you have a symbol file, does that suffice to let you know what
is code and what is data?
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: Breakpoints in delay slots
2006-10-18 10:59 Breakpoints in delay slots Andrew STUBBS
2006-10-18 14:04 ` Daniel Jacobowitz
@ 2006-10-18 18:51 ` Michael Snyder
2006-10-19 9:52 ` Andrew STUBBS
2006-10-19 19:51 ` Mark Kettenis
` (2 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Michael Snyder @ 2006-10-18 18:51 UTC (permalink / raw)
To: Andrew STUBBS; +Cc: GDB List
On Wed, 2006-10-18 at 11:59 +0100, Andrew STUBBS wrote:
> Hi all,
>
> There is an occasional issue debugging programs on processors that use
> delay slots - in my case the SH4.
>
> The problem occurs when a breakpoint is placed on the delay slot
> instruction. This can happen when
(1)
> this instruction happens to be the first instruction of a source line, or
(2)
> when the user sets the breakpoint on a specific address.
>
> In the case of the SH4, the breakpoint instruction (at least the one we
> use) is illegal in a delay slot. This means that, instead of triggering
> the breakpoint, an illegal slot exception is raised which the user
> program is expected to handle and usually results in a panic.
>
> In any case, even if the breakpoint were handled as normal, there is the
> problem of where the program should be resumed. It is incorrect to set
> the PC to the slot instruction because this will ignore the branch. The
> correct thing is to set the PC to the address of the branch/slot pair -
> i.e. 2 bytes back in the case of the SH4.
>
> There is no general way to identify a delay slot from instruction
> analysis - any instruction may be preceded by data which looks like a
> branch with a slot, and there is the danger of reading addresses outside
> memory - so there is no way to avoid the situation in the first place.
> Similarly, there is no way to identify that a breakpoint just hit was in
> a slot unless you make a note of how it was hit.
>
> I need a way to solve this problem. Any suggestions?
Sorry to be terse, but...
(1) -O0
(2) "Don't do that".
Michael
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: Breakpoints in delay slots
2006-10-18 18:51 ` Michael Snyder
@ 2006-10-19 9:52 ` Andrew STUBBS
2006-10-19 23:20 ` Michael Snyder
0 siblings, 1 reply; 11+ messages in thread
From: Andrew STUBBS @ 2006-10-19 9:52 UTC (permalink / raw)
To: Michael Snyder; +Cc: GDB List
Michael Snyder wrote:
> Sorry to be terse, but...
>
> (1) -O0
Actually it can still happen that the first instruction in a line is the
nop in the delay slot, but that can be considered a compiler bug.
> (2) "Don't do that".
That's hardly the developer's choice.
In the real world people sometimes have to debug optimised code and
"don't do it" is not a useful answer.
Andrew
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Breakpoints in delay slots
2006-10-19 9:52 ` Andrew STUBBS
@ 2006-10-19 23:20 ` Michael Snyder
0 siblings, 0 replies; 11+ messages in thread
From: Michael Snyder @ 2006-10-19 23:20 UTC (permalink / raw)
To: Andrew STUBBS; +Cc: GDB List
On Thu, 2006-10-19 at 10:52 +0100, Andrew STUBBS wrote:
> Michael Snyder wrote:
> > Sorry to be terse, but...
> >
> > (1) -O0
>
> Actually it can still happen that the first instruction in a line is the
> nop in the delay slot, but that can be considered a compiler bug.
>
> > (2) "Don't do that".
>
> That's hardly the developer's choice.
>
> In the real world people sometimes have to debug optimised code and
> "don't do it" is not a useful answer.
Well, I know, but in some cases it's the only answer we have.
There are some problems in debugging optimized code that are
not soluble, or not practically soluble.
Moreover, I separated (1) from (2) deliberately. In the absence
of the compiler placing a delay slot at the beginning of a function
or line, for the user to explicitly place a breakpoint in a delay
slot can arguably be called pilot error.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Breakpoints in delay slots
2006-10-18 10:59 Breakpoints in delay slots Andrew STUBBS
2006-10-18 14:04 ` Daniel Jacobowitz
2006-10-18 18:51 ` Michael Snyder
@ 2006-10-19 19:51 ` Mark Kettenis
2006-10-20 8:42 ` Andrew STUBBS
2006-10-20 8:51 ` Andrew STUBBS
2006-10-20 21:18 ` Jim Blandy
4 siblings, 1 reply; 11+ messages in thread
From: Mark Kettenis @ 2006-10-19 19:51 UTC (permalink / raw)
To: andrew.stubbs; +Cc: gdb
> Date: Wed, 18 Oct 2006 11:59:08 +0100
> From: Andrew STUBBS <andrew.stubbs@st.com>
>
> Hi all,
>
> There is an occasional issue debugging programs on processors that use
> delay slots - in my case the SH4.
>
> The problem occurs when a breakpoint is placed on the delay slot
> instruction. This can happen when this instruction happens to be the
> first instruction of a source line, or when the user sets the breakpoint
> on a specific address.
>
> In the case of the SH4, the breakpoint instruction (at least the one we
> use) is illegal in a delay slot. This means that, instead of triggering
> the breakpoint, an illegal slot exception is raised which the user
> program is expected to handle and usually results in a panic.
>
> In any case, even if the breakpoint were handled as normal, there is the
> problem of where the program should be resumed. It is incorrect to set
> the PC to the slot instruction because this will ignore the branch. The
> correct thing is to set the PC to the address of the branch/slot pair -
> i.e. 2 bytes back in the case of the SH4.
>
> There is no general way to identify a delay slot from instruction
> analysis - any instruction may be preceded by data which looks like a
> branch with a slot, and there is the danger of reading addresses outside
> memory - so there is no way to avoid the situation in the first place.
This is because the SH4 can have "data words" in the instruction
stream isn't it?
> Similarly, there is no way to identify that a breakpoint just hit was in
> a slot unless you make a note of how it was hit.
>
> I need a way to solve this problem. Any suggestions?
As Daniel already mentioned this does sound pretty similar to what
MIPS does. There is however an important difference in that MIPS will
actually generate a trap on the branch instruction and set a flag in a
register to indicate that the trap actually occured in the delay slot.
My solution would be to emulate what MIPS does. So in the exception
handler for the illegal slot exception, check whether you've hit a
breakpoint. If so report SIGTRAP back to GDB and make sure that if
you get a continue from GDB, you back up the instruction pointer to
the branch instruction preceding the delay slot. This will require
you to implement sh_single_step_through_delay().
Incidentally we're currently porting OpenBSD to the SH4, and my
current plan for OpenBSD/sh is to do what I sketched above.
Mark
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Breakpoints in delay slots
2006-10-19 19:51 ` Mark Kettenis
@ 2006-10-20 8:42 ` Andrew STUBBS
2006-10-22 19:47 ` Mark Kettenis
0 siblings, 1 reply; 11+ messages in thread
From: Andrew STUBBS @ 2006-10-20 8:42 UTC (permalink / raw)
To: Mark Kettenis; +Cc: gdb
Mark Kettenis wrote:
> This is because the SH4 can have "data words" in the instruction
> stream isn't it?
No, not if you are saying what I think you are saying, but there can be
data very close to the instructions. It can occur immediately before a
function (I don't know that the compiler does this, but hand written
assembler might), or, due to the small range of offsets available, there
may be a constant pool within the body of the function which the code
branches past.
> As Daniel already mentioned this does sound pretty similar to what
I haven't seen anything from Daniel???? I have found it on the web
archive now though.
> MIPS does. There is however an important difference in that MIPS will
> actually generate a trap on the branch instruction and set a flag in a
> register to indicate that the trap actually occured in the delay slot.
>
> My solution would be to emulate what MIPS does. So in the exception
> handler for the illegal slot exception, check whether you've hit a
> breakpoint. If so report SIGTRAP back to GDB and make sure that if
> you get a continue from GDB, you back up the instruction pointer to
> the branch instruction preceding the delay slot. This will require
> you to implement sh_single_step_through_delay().
How does one fix the problem that GDB doesn't associate the trap with
the breakpoint? Not only will it tell the user there was an unexpected
trap, ignore any conditions or commands, and show the source location as
somewhere else, but it won't take any measures to avoid the breakpoint
on the restart.
Thanks
Andrew
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Breakpoints in delay slots
2006-10-20 8:42 ` Andrew STUBBS
@ 2006-10-22 19:47 ` Mark Kettenis
0 siblings, 0 replies; 11+ messages in thread
From: Mark Kettenis @ 2006-10-22 19:47 UTC (permalink / raw)
To: andrew.stubbs; +Cc: mark.kettenis, gdb
> Date: Fri, 20 Oct 2006 09:42:33 +0100
> From: Andrew STUBBS <andrew.stubbs@st.com>
>
> > My solution would be to emulate what MIPS does. So in the exception
> > handler for the illegal slot exception, check whether you've hit a
> > breakpoint. If so report SIGTRAP back to GDB and make sure that if
> > you get a continue from GDB, you back up the instruction pointer to
> > the branch instruction preceding the delay slot. This will require
> > you to implement sh_single_step_through_delay().
>
> How does one fix the problem that GDB doesn't associate the trap with
> the breakpoint? Not only will it tell the user there was an unexpected
> trap, ignore any conditions or commands, and show the source location as
> somewhere else, but it won't take any measures to avoid the breakpoint
> on the restart.
Ah, looks like I wasn't quite clear about this. You'll have your stub
(or OS kernel) report the address of the delay slot as where it
stopped (such that gdb will do the right thing for hitting the
breakpoint). But the stub will remember that it actually hit a
breakpoint in a delay slot. Later when gdb asks the stub to continue,
you make it back up to the address of the branch instruction before
you let it run again.
Mark
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Breakpoints in delay slots
2006-10-18 10:59 Breakpoints in delay slots Andrew STUBBS
` (2 preceding siblings ...)
2006-10-19 19:51 ` Mark Kettenis
@ 2006-10-20 8:51 ` Andrew STUBBS
2006-10-20 14:26 ` Daniel Jacobowitz
2006-10-20 21:18 ` Jim Blandy
4 siblings, 1 reply; 11+ messages in thread
From: Andrew STUBBS @ 2006-10-20 8:51 UTC (permalink / raw)
To: GDB List
In reply to the message from Daniel that I never got, but appears in the
web archive. (Now that I look I never got my own message back either.)
> This is a remarkable mess. Unsurprisingly you aren't the first person
> to have this sort of problem, so GDB has a certain amount of support
> for delay slots, but MIPS at least is much friendlier: you can use the
> same breakpoint instruction, and there's a bit in the cause register
> that lets you know you were in a delay slot.
>
> When you have a symbol file, does that suffice to let you know what
> is code and what is data?
Unfortunately not. At least, the only way I can think of is to check
whether it has a line number or not, and the answer is that even the
data has a line number - that of the instruction immediately preceding it.
Andrew
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: Breakpoints in delay slots
2006-10-20 8:51 ` Andrew STUBBS
@ 2006-10-20 14:26 ` Daniel Jacobowitz
0 siblings, 0 replies; 11+ messages in thread
From: Daniel Jacobowitz @ 2006-10-20 14:26 UTC (permalink / raw)
To: Andrew STUBBS; +Cc: GDB List
On Fri, Oct 20, 2006 at 09:51:31AM +0100, Andrew STUBBS wrote:
> Unfortunately not. At least, the only way I can think of is to check
> whether it has a line number or not, and the answer is that even the
> data has a line number - that of the instruction immediately preceding it.
That's a shame. ARM invented a mechanism to solve this problem, which
works quite well for them, but it was a bit of a pain getting it
deployed.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Breakpoints in delay slots
2006-10-18 10:59 Breakpoints in delay slots Andrew STUBBS
` (3 preceding siblings ...)
2006-10-20 8:51 ` Andrew STUBBS
@ 2006-10-20 21:18 ` Jim Blandy
4 siblings, 0 replies; 11+ messages in thread
From: Jim Blandy @ 2006-10-20 21:18 UTC (permalink / raw)
To: Andrew STUBBS; +Cc: GDB List
Andrew STUBBS <andrew.stubbs@st.com> writes:
> The problem occurs when a breakpoint is placed on the delay slot
> instruction. This can happen when this instruction happens to be the
> first instruction of a source line, or when the user sets the
> breakpoint on a specific address.
Yeah. As others have said, this is a pain.
The important thing to note here is that there's a bit of processor
state that I gather you don't have access to on the SH4 --- the 'next
PC', to which control will go after the current instruction. If the
SH4 doesn't provide GDB enough information to predict where
non-exceptional flow should go on resumption, or if it exists but the
kernel doesn't make it available to GDB, then that's the fundamental
bug.
The SPARC (or am I thinking of the HPPA?) actually makes this
explicit, with an NPC ("next pc") register. In a delay slot, PC will
point at the instruction in the delay slot, and NPC points to the
target of the branch.
MIPS effectively provides the same information with the bit in the
cause register.
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2006-10-22 19:47 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-10-18 10:59 Breakpoints in delay slots Andrew STUBBS
2006-10-18 14:04 ` Daniel Jacobowitz
2006-10-18 18:51 ` Michael Snyder
2006-10-19 9:52 ` Andrew STUBBS
2006-10-19 23:20 ` Michael Snyder
2006-10-19 19:51 ` Mark Kettenis
2006-10-20 8:42 ` Andrew STUBBS
2006-10-22 19:47 ` Mark Kettenis
2006-10-20 8:51 ` Andrew STUBBS
2006-10-20 14:26 ` Daniel Jacobowitz
2006-10-20 21:18 ` Jim Blandy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox