public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* Re: ignore helper no longer works?
@ 2003-07-03  0:33 Jafa
  0 siblings, 0 replies; 6+ messages in thread
From: Jafa @ 2003-07-03  0:33 UTC (permalink / raw)
  To: gdb

Sorry about title (I just noticed) - I started thinking it was a problem
with ignore helper but I have confirmed it does work for step-into.... the
problem is with the hanndling of epilogue stubs.

Nick


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: ignore helper no longer works?
@ 2003-07-03 18:36 Jafa
  0 siblings, 0 replies; 6+ messages in thread
From: Jafa @ 2003-07-03 18:36 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb

Ok, the solution is obvious now that I am looking at it a different way...

When in an epilogue stub search for the return address on the stack, even
though the prologue code has indicated that the stub itself did not save the
return address. It doesn't matter who called the epilogue stub, just the
fact that they did means that they saved the return address in their own
prologue.

The only issue is that the stack backtrace will show the current function
being the epilogue stub and its caller being the real functions caller.

Thanks Andrew for your advice - it got me thinking along the right lines.

Nick

----- Original Message -----
From: "Jafa" <jafa@silicondust.com>
To: "Andrew Cagney" <ac131313@redhat.com>
Cc: <gdb@sources.redhat.com>
Sent: Thursday, July 03, 2003 10:25 AM
Subject: Re: ignore helper no longer works?


Hi Andrew,

>- When stepping, the need to identify and single step through
>trampolines / helpers.

I have updated the backtrace code so that if it detects that it is in an
epilogue stub then return a frame with no known return address (0) and no
known FP (0).

I can probably work out the FP of the previous function if need be, but have
no hope (without some simulation) of figuring out the return address.

Step-over at the end of a fucntion results in gdb running without stopping
(and it doesn't call ignore_helper).

One way to address this problem would be for gdb to call ignore_helper, and
then know not attempt a stack-backtrace.

Another solution (ok, crude hack) would be for the tdep to cache the last
known PC so that if it steps into a stub then it knows where it came from.

>- When stopped, the need to back trace out of a trampoline / helper.

I think it is accceptable not being able to do a backtrace if you are in an
epilogue helper.... the code now returns that the FP and PC are unknown to
abort the backtrace.

I am open to ideas (I figure this must be a rare but general problem). If
all else fails I will implement the crude hack above because I need to get
this working.

Thanks

Nick

----- Original Message -----
From: "Andrew Cagney" <ac131313@redhat.com>
To: "Jafa" <jafa@silicondust.com>
Cc: <gdb@sources.redhat.com>
Sent: Thursday, July 03, 2003 8:10 AM
Subject: Re: ignore helper no longer works?



> 1) Say it is my responsibility to determine the return address anywhere in
> code, even if it means writing a whole lot of code in gdb to simulate the
> execution of these stubs.
>
> 2) Fix gdb at a higher level so that it doesn't try to obtain a return
> address from a helper function - instead keep stepping (like it gdb used
to
> do).

Sounds like you've got two problems:

- When stepping, the need to identify and single step through
trampolines / helpers.

- When stopped, the need to back trace out of a trampoline / helper.

Given a core file, it isn't possible to `step'.  Your unwinder is going
to need to identify and dig itself out of that hole.  Main thing to do
is to not lie - from what I understand of your case, given a callee that
jumped to a helper, you'll end up displaying:
<helper>
caller

Andrew


> I can figure out the FP ok (all be it that it is painful without being
able
> to see the prologue) - the old system only asked for the FP and after
> detecting that it was the same frame, kept stepping.
>
> BTW - I have also noticed that gdb now does not call ignore_helper for any
> step-over operations, instead relying on the tdep to supply the return
> address for the stub. It think it always used to call ignore_helper and if
> it was a helper then it stepped rather that setting a breakpoint as if it
> was a function.
>
> I don't want to be too quick to butcher infrun - I would appreciate your
> advice.





^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: ignore helper no longer works?
  2003-07-03 15:10 ` Andrew Cagney
@ 2003-07-03 17:27   ` Jafa
  0 siblings, 0 replies; 6+ messages in thread
From: Jafa @ 2003-07-03 17:27 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb

Hi Andrew,

>- When stepping, the need to identify and single step through
>trampolines / helpers.

I have updated the backtrace code so that if it detects that it is in an
epilogue stub then return a frame with no known return address (0) and no
known FP (0).

I can probably work out the FP of the previous function if need be, but have
no hope (without some simulation) of figuring out the return address.

Step-over at the end of a fucntion results in gdb running without stopping
(and it doesn't call ignore_helper).

One way to address this problem would be for gdb to call ignore_helper, and
then know not attempt a stack-backtrace.

Another solution (ok, crude hack) would be for the tdep to cache the last
known PC so that if it steps into a stub then it knows where it came from.

>- When stopped, the need to back trace out of a trampoline / helper.

I think it is accceptable not being able to do a backtrace if you are in an
epilogue helper.... the code now returns that the FP and PC are unknown to
abort the backtrace.

I am open to ideas (I figure this must be a rare but general problem). If
all else fails I will implement the crude hack above because I need to get
this working.

Thanks

Nick

----- Original Message -----
From: "Andrew Cagney" <ac131313@redhat.com>
To: "Jafa" <jafa@silicondust.com>
Cc: <gdb@sources.redhat.com>
Sent: Thursday, July 03, 2003 8:10 AM
Subject: Re: ignore helper no longer works?



> 1) Say it is my responsibility to determine the return address anywhere in
> code, even if it means writing a whole lot of code in gdb to simulate the
> execution of these stubs.
>
> 2) Fix gdb at a higher level so that it doesn't try to obtain a return
> address from a helper function - instead keep stepping (like it gdb used
to
> do).

Sounds like you've got two problems:

- When stepping, the need to identify and single step through
trampolines / helpers.

- When stopped, the need to back trace out of a trampoline / helper.

Given a core file, it isn't possible to `step'.  Your unwinder is going
to need to identify and dig itself out of that hole.  Main thing to do
is to not lie - from what I understand of your case, given a callee that
jumped to a helper, you'll end up displaying:
<helper>
caller

Andrew


> I can figure out the FP ok (all be it that it is painful without being
able
> to see the prologue) - the old system only asked for the FP and after
> detecting that it was the same frame, kept stepping.
>
> BTW - I have also noticed that gdb now does not call ignore_helper for any
> step-over operations, instead relying on the tdep to supply the return
> address for the stub. It think it always used to call ignore_helper and if
> it was a helper then it stepped rather that setting a breakpoint as if it
> was a function.
>
> I don't want to be too quick to butcher infrun - I would appreciate your
> advice.




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: ignore helper no longer works?
  2003-07-03  2:27 Jafa
@ 2003-07-03 15:10 ` Andrew Cagney
  2003-07-03 17:27   ` Jafa
  0 siblings, 1 reply; 6+ messages in thread
From: Andrew Cagney @ 2003-07-03 15:10 UTC (permalink / raw)
  To: Jafa; +Cc: gdb


> 1) Say it is my responsibility to determine the return address anywhere in
> code, even if it means writing a whole lot of code in gdb to simulate the
> execution of these stubs.
> 
> 2) Fix gdb at a higher level so that it doesn't try to obtain a return
> address from a helper function - instead keep stepping (like it gdb used to
> do).

Sounds like you've got two problems:

- When stepping, the need to identify and single step through 
trampolines / helpers.

- When stopped, the need to back trace out of a trampoline / helper.

Given a core file, it isn't possible to `step'.  Your unwinder is going 
to need to identify and dig itself out of that hole.  Main thing to do 
is to not lie - from what I understand of your case, given a callee that 
jumped to a helper, you'll end up displaying:
	<helper>
	caller

Andrew


> I can figure out the FP ok (all be it that it is painful without being able
> to see the prologue) - the old system only asked for the FP and after
> detecting that it was the same frame, kept stepping.
> 
> BTW - I have also noticed that gdb now does not call ignore_helper for any
> step-over operations, instead relying on the tdep to supply the return
> address for the stub. It think it always used to call ignore_helper and if
> it was a helper then it stepped rather that setting a breakpoint as if it
> was a function.
> 
> I don't want to be too quick to butcher infrun - I would appreciate your
> advice.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: ignore helper no longer works?
@ 2003-07-03  2:27 Jafa
  2003-07-03 15:10 ` Andrew Cagney
  0 siblings, 1 reply; 6+ messages in thread
From: Jafa @ 2003-07-03  2:27 UTC (permalink / raw)
  To: gdb

Ok, thinking about this further...

The problem is that theses epilogue stubs are responsibe for storting out
the return address (typically poping off the stack after poping a variable
number of other stuff). They are executed by jumping to them thus I have no
idea how it got there or what the return address is unless I simulate the
remainder of the stub to see what it does to sort out the return address.

So I can two options:

1) Say it is my responsibility to determine the return address anywhere in
code, even if it means writing a whole lot of code in gdb to simulate the
execution of these stubs.

2) Fix gdb at a higher level so that it doesn't try to obtain a return
address from a helper function - instead keep stepping (like it gdb used to
do).

I can figure out the FP ok (all be it that it is painful without being able
to see the prologue) - the old system only asked for the FP and after
detecting that it was the same frame, kept stepping.

BTW - I have also noticed that gdb now does not call ignore_helper for any
step-over operations, instead relying on the tdep to supply the return
address for the stub. It think it always used to call ignore_helper and if
it was a helper then it stepped rather that setting a breakpoint as if it
was a function.

I don't want to be too quick to butcher infrun - I would appreciate your
advice.

Thanks

Nick

----- Original Message -----
From: "Jafa" <jafa@silicondust.com>
To: <gdb@sources.redhat.com>
Sent: Wednesday, July 02, 2003 5:25 PM
Subject: ignore helper no longer works?


Hi guys,

I now have the ip2k frame handling code working using the new scheme
including giving valid results in any position within the prologue. Stack
backtraces and finish both work reliably.

Gcc for the ip2k has a habit of using a lot of stub functions - typically
3-4 instruction sequences which are just snippits of code with a return
instruction (not valid functions).

From the user's point-of-view, if they click step-into they want to step
into the c-level function - not an invisible stub that happens to have been
inserted by gcc to set up the parameters to that function.

The solution has been to register a IGNORE_HELPER_CALL function that tells
gdb that it has just stepped into a helper/stub and to treat it as an
extension of the current function (ie just keep stepping).

The problem is that gcc also tends to use a stub for the epilogue of
functions (jump to a stub that cleans up the stack and returns).

With the old frame handling system this worked fine - gdb just kept stepping
through the epilogue stub.

With the new system it fails... it asks for the frame information of the
epilogue stub (which is not a function). There are a large number of stubs
and it would pose quite a problem to attempt to get gdb understand them all
(not to mention keeping up with our gcc guy thinking up new stubs).

I am fully open to ideas :-)

BTW - MIPS will have the same problem as it uses epilogue stubs as well.

Thanks

Nick

Trace of 'next' at the end of a function leading into an epilogue stub...

(gdb) n
{ frame_register_unwind (frame=-1,regnum="sp",...) -> *optimizedp=0 *lvalp=2
*addrp=0x102 *bufferp=[0ff3] }
{ flush_cached_frames () }
{ create_sentinel_frame (...) ->
{level=-1,type=NORMAL_FRAME,unwind=0x4dd1d4,pc=<unknown>,id={stack=0x0,code=
0x0},func=<unknown>} }
{ get_prev_frame (this_frame=-1) { frame_register_unwind
(frame=-1,regnum="pc",...) -> *optimizedp=0 *lvalp=2 *addrp=0x100
*bufferp=[8047] }
{ frame_pc_unwind (this_frame=-1) -> 0x201008e }
->
{level=0,type=UNKNOWN_FRAME,unwind=<unknown>,pc=0x201008e,id=<unknown>,func=
<unknown>} }
{ frame_register_unwind (frame=-1,regnum="sp",...) -> *optimizedp=0 *lvalp=2
*addrp=0x102 *bufferp=[0ff3] }
{ flush_cached_frames () }
{ create_sentinel_frame (...) ->
{level=-1,type=NORMAL_FRAME,unwind=0x4dd1d4,pc=<unknown>,id={stack=0x0,code=
0x0},func=<unknown>} }
{ get_prev_frame (this_frame=-1) { frame_register_unwind
(frame=-1,regnum="pc",...) -> *optimizedp=0 *lvalp=2 *addrp=0x100
*bufferp=[0a56] }
{ frame_pc_unwind (this_frame=-1) -> 0x20014ac }
->
{level=0,type=UNKNOWN_FRAME,unwind=<unknown>,pc=0x20014ac,id=<unknown>,func=
<unknown>} }
{ frame_register_unwind (frame=-1,regnum="sp",...) -> *optimizedp=0 *lvalp=2
*addrp=0x102 *bufferp=[0ff3] }
{ frame_register_unwind (frame=0,regnum="pc",...) ip2k_frame_unwind_cache:
{ frame_func_unwind (fi=-1) -> 0x20014ac }
{ frame_register_unwind (frame=-1,regnum="sp",...) -> *optimizedp=0 *lvalp=2
*addrp=0x102 *bufferp=[0ff3] }
 entry_pc = 0x020014ac
 current_pc = 0x020014ac
 return_pc = 0x02011836
 entry_sp = 0x01000ff3
 normal_sp = 0x01000ff3
 current_sp = 0x01000ff3
-> *optimizedp=0 *lvalp=0 *addrp=0x0 *bufferp=[8c1b] }
{ frame_pc_unwind (this_frame=0) -> 0x2011836 }
{ get_frame_id (fi=0) ip2k_frame_this_id
-> {stack=0x1000ff3,code=0x0} }
{ frame_id_p (l={stack=0x1000ff5,code=0x0}) -> 1 }
{ frame_register_unwind (frame=-1,regnum="sp",...) -> *optimizedp=0 *lvalp=2
*addrp=0x102 *bufferp=[0ff3] }
{ flush_cached_frames () }
{ frame_id_p (l={stack=0x1000ff5,code=0x0}) -> 1 }
{ create_sentinel_frame (...) ->
{level=-1,type=NORMAL_FRAME,unwind=0x4dd1d4,pc=<unknown>,id={stack=0x0,code=
0x0},func=<unknown>} }
{ get_prev_frame (this_frame=-1) { frame_register_unwind
(frame=-1,regnum="pc",...) -> *optimizedp=0 *lvalp=2 *addrp=0x100
*bufferp=[8c1b] }
{ frame_pc_unwind (this_frame=-1) -> 0x2011836 }
->
{level=0,type=UNKNOWN_FRAME,unwind=<unknown>,pc=0x2011836,id=<unknown>,func=
<unknown>} }
{ get_frame_id (fi=0) ip2k_frame_this_id
ip2k_frame_unwind_cache:
{ frame_func_unwind (fi=-1) -> 0x2011804 }
{ frame_register_unwind (frame=-1,regnum="sp",...) -> *optimizedp=0 *lvalp=2
*addrp=0x102 *bufferp=[0ff5] }
 correction of 8 applied
 entry_pc = 0x02011804
 current_pc = 0x02011836
 return_pc = 0x020114b0
 entry_sp = 0x01000fff
 normal_sp = 0x01000ffd
 current_sp = 0x01000ff5
-> {stack=0x1000fff,code=0x0} }
{ frame_id_eq (l={stack=0x1000ff5,code=0x0},r={stack=0x1000fff,code=0x0}) ->
0 }
{ flush_cached_frames () }


^ permalink raw reply	[flat|nested] 6+ messages in thread

* ignore helper no longer works?
@ 2003-07-03  0:27 Jafa
  0 siblings, 0 replies; 6+ messages in thread
From: Jafa @ 2003-07-03  0:27 UTC (permalink / raw)
  To: gdb

Hi guys,

I now have the ip2k frame handling code working using the new scheme
including giving valid results in any position within the prologue. Stack
backtraces and finish both work reliably.

Gcc for the ip2k has a habit of using a lot of stub functions - typically
3-4 instruction sequences which are just snippits of code with a return
instruction (not valid functions).

From the user's point-of-view, if they click step-into they want to step
into the c-level function - not an invisible stub that happens to have been
inserted by gcc to set up the parameters to that function.

The solution has been to register a IGNORE_HELPER_CALL function that tells
gdb that it has just stepped into a helper/stub and to treat it as an
extension of the current function (ie just keep stepping).

The problem is that gcc also tends to use a stub for the epilogue of
functions (jump to a stub that cleans up the stack and returns).

With the old frame handling system this worked fine - gdb just kept stepping
through the epilogue stub.

With the new system it fails... it asks for the frame information of the
epilogue stub (which is not a function). There are a large number of stubs
and it would pose quite a problem to attempt to get gdb understand them all
(not to mention keeping up with our gcc guy thinking up new stubs).

I am fully open to ideas :-)

BTW - MIPS will have the same problem as it uses epilogue stubs as well.

Thanks

Nick

Trace of 'next' at the end of a function leading into an epilogue stub...

(gdb) n
{ frame_register_unwind (frame=-1,regnum="sp",...) -> *optimizedp=0 *lvalp=2
*addrp=0x102 *bufferp=[0ff3] }
{ flush_cached_frames () }
{ create_sentinel_frame (...) ->
{level=-1,type=NORMAL_FRAME,unwind=0x4dd1d4,pc=<unknown>,id={stack=0x0,code=
0x0},func=<unknown>} }
{ get_prev_frame (this_frame=-1) { frame_register_unwind
(frame=-1,regnum="pc",...) -> *optimizedp=0 *lvalp=2 *addrp=0x100
*bufferp=[8047] }
{ frame_pc_unwind (this_frame=-1) -> 0x201008e }
->
{level=0,type=UNKNOWN_FRAME,unwind=<unknown>,pc=0x201008e,id=<unknown>,func=
<unknown>} }
{ frame_register_unwind (frame=-1,regnum="sp",...) -> *optimizedp=0 *lvalp=2
*addrp=0x102 *bufferp=[0ff3] }
{ flush_cached_frames () }
{ create_sentinel_frame (...) ->
{level=-1,type=NORMAL_FRAME,unwind=0x4dd1d4,pc=<unknown>,id={stack=0x0,code=
0x0},func=<unknown>} }
{ get_prev_frame (this_frame=-1) { frame_register_unwind
(frame=-1,regnum="pc",...) -> *optimizedp=0 *lvalp=2 *addrp=0x100
*bufferp=[0a56] }
{ frame_pc_unwind (this_frame=-1) -> 0x20014ac }
->
{level=0,type=UNKNOWN_FRAME,unwind=<unknown>,pc=0x20014ac,id=<unknown>,func=
<unknown>} }
{ frame_register_unwind (frame=-1,regnum="sp",...) -> *optimizedp=0 *lvalp=2
*addrp=0x102 *bufferp=[0ff3] }
{ frame_register_unwind (frame=0,regnum="pc",...) ip2k_frame_unwind_cache:
{ frame_func_unwind (fi=-1) -> 0x20014ac }
{ frame_register_unwind (frame=-1,regnum="sp",...) -> *optimizedp=0 *lvalp=2
*addrp=0x102 *bufferp=[0ff3] }
 entry_pc = 0x020014ac
 current_pc = 0x020014ac
 return_pc = 0x02011836
 entry_sp = 0x01000ff3
 normal_sp = 0x01000ff3
 current_sp = 0x01000ff3
-> *optimizedp=0 *lvalp=0 *addrp=0x0 *bufferp=[8c1b] }
{ frame_pc_unwind (this_frame=0) -> 0x2011836 }
{ get_frame_id (fi=0) ip2k_frame_this_id
-> {stack=0x1000ff3,code=0x0} }
{ frame_id_p (l={stack=0x1000ff5,code=0x0}) -> 1 }
{ frame_register_unwind (frame=-1,regnum="sp",...) -> *optimizedp=0 *lvalp=2
*addrp=0x102 *bufferp=[0ff3] }
{ flush_cached_frames () }
{ frame_id_p (l={stack=0x1000ff5,code=0x0}) -> 1 }
{ create_sentinel_frame (...) ->
{level=-1,type=NORMAL_FRAME,unwind=0x4dd1d4,pc=<unknown>,id={stack=0x0,code=
0x0},func=<unknown>} }
{ get_prev_frame (this_frame=-1) { frame_register_unwind
(frame=-1,regnum="pc",...) -> *optimizedp=0 *lvalp=2 *addrp=0x100
*bufferp=[8c1b] }
{ frame_pc_unwind (this_frame=-1) -> 0x2011836 }
->
{level=0,type=UNKNOWN_FRAME,unwind=<unknown>,pc=0x2011836,id=<unknown>,func=
<unknown>} }
{ get_frame_id (fi=0) ip2k_frame_this_id
ip2k_frame_unwind_cache:
{ frame_func_unwind (fi=-1) -> 0x2011804 }
{ frame_register_unwind (frame=-1,regnum="sp",...) -> *optimizedp=0 *lvalp=2
*addrp=0x102 *bufferp=[0ff5] }
 correction of 8 applied
 entry_pc = 0x02011804
 current_pc = 0x02011836
 return_pc = 0x020114b0
 entry_sp = 0x01000fff
 normal_sp = 0x01000ffd
 current_sp = 0x01000ff5
-> {stack=0x1000fff,code=0x0} }
{ frame_id_eq (l={stack=0x1000ff5,code=0x0},r={stack=0x1000fff,code=0x0}) ->
0 }
{ flush_cached_frames () }

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2003-07-03 18:36 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-07-03  0:33 ignore helper no longer works? Jafa
  -- strict thread matches above, loose matches on Subject: below --
2003-07-03 18:36 Jafa
2003-07-03  2:27 Jafa
2003-07-03 15:10 ` Andrew Cagney
2003-07-03 17:27   ` Jafa
2003-07-03  0:27 Jafa

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).