public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* [hpux] interesting but difficult to unwind code
@ 2005-12-09  0:08 Randolph Chung
  2005-12-09  0:44 ` John David Anglin
  0 siblings, 1 reply; 7+ messages in thread
From: Randolph Chung @ 2005-12-09  0:08 UTC (permalink / raw)
  To: John David Anglin, Joel Brobecker, gdb

Here's a case that gdb cannot handle. This is from a piece of code that 
is probably compiled by the HP compiler -- it is HP's wdb. 
Interestingly, neither wdb or gdb can unwind through execute_command(). 
The code seems to include a few interesting features:

1) it has a branch right in the middle of the prologue at +16. This is a 
call to strlen()

2) It contains a stack adjustment beyond what is marked in the unwind 
info. This is probably due to alloca(). Note that there is nothing in 
the unwind data that indicates this. The line of code in wdb that 
generates this is probably:

  save_line = (char *) alloca (strlen (p) + 1);


(gdb) disassemble 0xcb52f
Dump of assembler code for function execute_command:
0x000cb44c <execute_command+0>: stw rp,-14(sp)
0x000cb450 <execute_command+4>: stw,ma r3,80(sp)
0x000cb454 <execute_command+8>: ldo 0(sp),r3
0x000cb458 <execute_command+12>:        stw r26,-a4(r3)
0x000cb45c <execute_command+16>:        b,l 0xcb41c <execute_command+24>,rp
0x000cb460 <execute_command+20>:        stw r25,-a8(r3)
0x000cb464 <execute_command+24>:        stw r4,-7c(r3)
0x000cb468 <execute_command+28>:        ldo 1(ret0),ret1
0x000cb46c <execute_command+32>:        stw r5,-78(r3)
0x000cb470 <execute_command+36>:        stw r6,-74(r3)
0x000cb474 <execute_command+40>:        ldw -10(sp),r26
0x000cb478 <execute_command+44>:        ldw -4(sp),r19
0x000cb47c <execute_command+48>:        addi 3f,ret1,r1
0x000cb480 <execute_command+52>:        depwi 0,31,6,r1
0x000cb484 <execute_command+56>:        ldi 38,rp
0x000cb488 <execute_command+60>:        sub sp,rp,ret1
0x000cb48c <execute_command+64>:        add sp,r1,sp
0x000cb490 <execute_command+68>:        stw r19,-4(sp)
0x000cb494 <execute_command+72>:        stw r26,-10(sp)
0x000cb498 <execute_command+76>:        ldw -a4(r3),r25
0x000cb49c <execute_command+80>:        ldo 0(ret1),r26
0x000cb4a0 <execute_command+84>:        b,l 0xcb424 <execute_command+32>,rp

(gdb) maintenance print unwind execute_command
unwind_table_entry (0x40286424):
         region_start = 0xcb44c <execute_command>
         region_end = 0xcb798 <execute_command+844>
         flags = Args_stored Save_RP
         Region_description = 0x0
         Entry_FR = 0x0
         Entry_GR = 0x4
         Total_frame_size = 0x10

I'm not sure if this is really ABI compliant.....
Any suggestions on what we can do here?

randolph

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

* Re: [hpux] interesting but difficult to unwind code
  2005-12-09  0:08 [hpux] interesting but difficult to unwind code Randolph Chung
@ 2005-12-09  0:44 ` John David Anglin
  2005-12-09  3:33   ` Randolph Chung
  0 siblings, 1 reply; 7+ messages in thread
From: John David Anglin @ 2005-12-09  0:44 UTC (permalink / raw)
  To: Randolph Chung; +Cc: brobecker, gdb

> Here's a case that gdb cannot handle. This is from a piece of code that 
> is probably compiled by the HP compiler -- it is HP's wdb. 

No, this code has been compiled by GCC.  The save of the frame
pointer at the incomming stack pointer address is the clue.  SAVE_SP
should be set to indicate this.  This should allow unwinding
through this function...

> Interestingly, neither wdb or gdb can unwind through execute_command(). 
> The code seems to include a few interesting features:
> 
> 1) it has a branch right in the middle of the prologue at +16. This is a 
> call to strlen()

Interesting.  It looks ok from a functional standpoint.

> 2) It contains a stack adjustment beyond what is marked in the unwind 
> info. This is probably due to alloca(). Note that there is nothing in 
> the unwind data that indicates this. The line of code in wdb that 
> generates this is probably:
> 
>   save_line = (char *) alloca (strlen (p) + 1);

GCC has never recorded alloca adjustments.  However, SAVE_SP will
be set in any frame using alloca.

> (gdb) disassemble 0xcb52f
> Dump of assembler code for function execute_command:
> 0x000cb44c <execute_command+0>: stw rp,-14(sp)
> 0x000cb450 <execute_command+4>: stw,ma r3,80(sp)
> 0x000cb454 <execute_command+8>: ldo 0(sp),r3
> 0x000cb458 <execute_command+12>:        stw r26,-a4(r3)
> 0x000cb45c <execute_command+16>:        b,l 0xcb41c <execute_command+24>,rp
> 0x000cb460 <execute_command+20>:        stw r25,-a8(r3)
> 0x000cb464 <execute_command+24>:        stw r4,-7c(r3)
> 0x000cb468 <execute_command+28>:        ldo 1(ret0),ret1
> 0x000cb46c <execute_command+32>:        stw r5,-78(r3)
> 0x000cb470 <execute_command+36>:        stw r6,-74(r3)
> 0x000cb474 <execute_command+40>:        ldw -10(sp),r26
> 0x000cb478 <execute_command+44>:        ldw -4(sp),r19
> 0x000cb47c <execute_command+48>:        addi 3f,ret1,r1
> 0x000cb480 <execute_command+52>:        depwi 0,31,6,r1
> 0x000cb484 <execute_command+56>:        ldi 38,rp
> 0x000cb488 <execute_command+60>:        sub sp,rp,ret1
> 0x000cb48c <execute_command+64>:        add sp,r1,sp
> 0x000cb490 <execute_command+68>:        stw r19,-4(sp)
> 0x000cb494 <execute_command+72>:        stw r26,-10(sp)

Note copy of info stored at -4 and -10 in the frame marker.  This
is mandated by the ABI but unfortunately psp isn't required to be
saved in the frame marker.  So it's not a whole lot of use.  Signal
frames are the only ones that I know save the psp for sure.  In
any case, r3 contains the previous stack pointer.

> 0x000cb498 <execute_command+76>:        ldw -a4(r3),r25
> 0x000cb49c <execute_command+80>:        ldo 0(ret1),r26
> 0x000cb4a0 <execute_command+84>:        b,l 0xcb424 <execute_command+32>,rp
> 
> (gdb) maintenance print unwind execute_command
> unwind_table_entry (0x40286424):
>          region_start = 0xcb44c <execute_command>
>          region_end = 0xcb798 <execute_command+844>
>          flags = Args_stored Save_RP

I don't understand why you don't see SAVE_SP in the flags.

Dave
-- 
J. David Anglin                                  dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6602)

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

* Re: [hpux] interesting but difficult to unwind code
  2005-12-09  0:44 ` John David Anglin
@ 2005-12-09  3:33   ` Randolph Chung
  2005-12-09  4:55     ` John David Anglin
  0 siblings, 1 reply; 7+ messages in thread
From: Randolph Chung @ 2005-12-09  3:33 UTC (permalink / raw)
  To: John David Anglin; +Cc: brobecker, gdb

> No, this code has been compiled by GCC.  The save of the frame
> pointer at the incomming stack pointer address is the clue.  SAVE_SP
> should be set to indicate this.  This should allow unwinding
> through this function...

hrm, is there a way to verify this other than the above? The fact that
the "args_stored" flag is set in the unwind record is also a bit
surprising, as (afaict) gcc doesn't emit this flag.

I downloaded this wdb binary from HP's website and their documentation
also seems to suggest that it is compiled with HP compilers.

>> 1) it has a branch right in the middle of the prologue at +16. This is a 
>> call to strlen()
> 
> Interesting.  It looks ok from a functional standpoint.

Yes, but I've never seen gcc do this.... does it?

>> 2) It contains a stack adjustment beyond what is marked in the unwind 
>> info. This is probably due to alloca(). Note that there is nothing in 
>> the unwind data that indicates this. The line of code in wdb that 
>> generates this is probably:
>>
>>   save_line = (char *) alloca (strlen (p) + 1);
> 
> GCC has never recorded alloca adjustments.  However, SAVE_SP will
> be set in any frame using alloca.

Right.

> Note copy of info stored at -4 and -10 in the frame marker.  This
> is mandated by the ABI but unfortunately psp isn't required to be
> saved in the frame marker.  So it's not a whole lot of use.  Signal
> frames are the only ones that I know save the psp for sure.  In
> any case, r3 contains the previous stack pointer.

The problem is that currently, absent some indication from the unwind
data that a frame pointer is present (e.g. Save_SP), we do not use the
saved frame pointer to do unwinding. This can probably be enhanced by
teaching gdb more about common prologue sequences that actually store
the psp into r3. Perhaps this is another argument for Joel's proposal to
do more detailed prologue analysis.

>> (gdb) maintenance print unwind execute_command
>> unwind_table_entry (0x40286424):
>>          region_start = 0xcb44c <execute_command>
>>          region_end = 0xcb798 <execute_command+844>
>>          flags = Args_stored Save_RP
> 
> I don't understand why you don't see SAVE_SP in the flags.

Yes, very odd....

randolph
-- 
Randolph Chung
Debian GNU/Linux Developer, hppa/ia64 ports
http://www.tausq.org/

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

* Re: [hpux] interesting but difficult to unwind code
  2005-12-09  3:33   ` Randolph Chung
@ 2005-12-09  4:55     ` John David Anglin
  0 siblings, 0 replies; 7+ messages in thread
From: John David Anglin @ 2005-12-09  4:55 UTC (permalink / raw)
  To: Randolph Chung; +Cc: brobecker, gdb

> > No, this code has been compiled by GCC.  The save of the frame
> > pointer at the incomming stack pointer address is the clue.  SAVE_SP
> > should be set to indicate this.  This should allow unwinding
> > through this function...
> 
> hrm, is there a way to verify this other than the above? The fact that
> the "args_stored" flag is set in the unwind record is also a bit
> surprising, as (afaict) gcc doesn't emit this flag.
> 
> I downloaded this wdb binary from HP's website and their documentation
> also seems to suggest that it is compiled with HP compilers.

I've changed my mind.  This code is compiled by a HP compiler.  So,
it better be ABI compliant.  I was confused by the code that has been
moved into the prologue.

GCC doesn't set "args_stored".  The register saves for r4, r5 and r6
are in different locations than gcc would use.  On checking, the frame
marker copy is slightly different.  Gcc doesn't copy slot at "-10" and
we actually save the previous stack pointer at sp - 4 when the frame
pointer is needed.

> >> 1) it has a branch right in the middle of the prologue at +16. This is a 
> >> call to strlen()
> > 
> > Interesting.  It looks ok from a functional standpoint.
> 
> Yes, but I've never seen gcc do this.... does it?

I've never seen it but in theory it could.

> >> (gdb) maintenance print unwind execute_command
> >> unwind_table_entry (0x40286424):
> >>          region_start = 0xcb44c <execute_command>
> >>          region_end = 0xcb798 <execute_command+844>
> >>          flags = Args_stored Save_RP
> > 
> > I don't understand why you don't see SAVE_SP in the flags.

It looks as if r3 is used as the argument pointer (previous stack pointer)
but there aren't any flag bits set to indicate this.  The only indication
is the copy at 0x000cb454.  I guess if you detect this you have to take
it as a matter of faith that the contents of r3 don't change.

Dave
-- 
J. David Anglin                                  dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6602)

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

* Re: [hpux] interesting but difficult to unwind code
  2005-12-09 18:47 Carl Burch
  2005-12-10  0:43 ` John David Anglin
@ 2005-12-11 14:45 ` Randolph Chung
  1 sibling, 0 replies; 7+ messages in thread
From: Randolph Chung @ 2005-12-11 14:45 UTC (permalink / raw)
  To: Carl Burch; +Cc: gdb, brobecker, dave

>    If you have our odump tool, "odump -comp a.out" will show you the 
> compiler and options used to build each object for a PA32 executable :

thanks.

>    There are two bits in the "struct unwind_table_entry" defined in
> config/pa/tm-hppa.h (at least in the WDB sources) that cover alloca() use
> and +Oentrysched use:
> 
>     unsigned int sched_entry_seq:1;     /* 25 */
> 		...
>     unsigned int alloca_frame:1;        /* 35 */
> 
> Unfortunately, even HP gdb doesn't print out those fields for a "maintenance
> print unwind" command.

I'll fix this this FSF gdb. Thanks for pointing this out!

Meanwhile with these pointers I've fixed the unwinding problem described 
previously in my local tree. Will do some more testing and send the 
patch to gdb-patches. Thanks for your help Carl.

randolph

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

* Re: [hpux] interesting but difficult to unwind code
  2005-12-09 18:47 Carl Burch
@ 2005-12-10  0:43 ` John David Anglin
  2005-12-11 14:45 ` Randolph Chung
  1 sibling, 0 replies; 7+ messages in thread
From: John David Anglin @ 2005-12-10  0:43 UTC (permalink / raw)
  To: Carl Burch; +Cc: gdb, brobecker, randolph

>    There are two bits in the "struct unwind_table_entry" defined in
> config/pa/tm-hppa.h (at least in the WDB sources) that cover alloca() use
> and +Oentrysched use:
> 
>     unsigned int sched_entry_seq:1;     /* 25 */
> 		...
>     unsigned int alloca_frame:1;        /* 35 */
> 
> Unfortunately, even HP gdb doesn't print out those fields for a "maintenance
> print unwind" command

These two flags are documented in the PA 2.0 runtime document (pages 8-236
and 8-237).  Looks like "maintenance print unwind", etc., need a bit of an
update.

Dave
-- 
J. David Anglin                                  dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6602)

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

* Re: [hpux] interesting but difficult to unwind code
@ 2005-12-09 18:47 Carl Burch
  2005-12-10  0:43 ` John David Anglin
  2005-12-11 14:45 ` Randolph Chung
  0 siblings, 2 replies; 7+ messages in thread
From: Carl Burch @ 2005-12-09 18:47 UTC (permalink / raw)
  To: gdb; +Cc: brobecker, dave, randolph


> > > No, this code has been compiled by GCC.  The save of the frame
> > > pointer at the incomming stack pointer address is the clue.  SAVE_SP
> > > should be set to indicate this.  This should allow unwinding
> > > through this function...
> > hrm, is there a way to verify this other than the above? The fact that
> > the "args_stored" flag is set in the unwind record is also a bit
> > surprising, as (afaict) gcc doesn't emit this flag.
  
   If you have our odump tool, "odump -comp a.out" will show you the 
compiler and options used to build each object for a PA32 executable :

spider cdb_debug 78: odump -comp ../gdb | more

Compilation Unit Dictionary from ../gdb:

Index Chunk     Language                                    Name
        Product_id ; Version_id
        Compile time ; Source time

	...

   5   0  HPC                                                ../../../Src/gnu/gd
b/main.c
/CLO/Components/WDB/build/hppa1.1-hp-hpux11.00/gdb
ccom options =  -g -DAportable -Oq00,al,ag,cn,Lm,sz,Ic,vo,lc,mf,Po,es,rs,sp,in,v
c,pi,fa,pe,Rr,Fl,pv,pa,nf,cp,lx,st,ap,Pg,ug,lu,lb,uj,dp,fs,bp,wp,cl,mo,xn,Ex,mp,
rp,ap,dn,Sg,pt,kt,Em,pc,np! -ESconstlit -Ae
driver_command =   /CLO/BUILD_ENV/opt/ansic/bin/cc -Ae -D_LOAD_MODULE_DESC_EXT +
DAportable -D_PSTAT64  -g +Ww2223 -D__HP_CURSES -DSEEK_64_BITS -D__HP_CURSES -DS
EEK_64_BITS -I. -I../../../Src/gnu/gdb -I../../../Src/gnu/gdb/config -DHAVE_CONF
IG_H -I../../../Src/gnu/gdb/../include/opcode -I../../../Src/gnu/gdb/../readline
/.. -I../bfd -I../../../Src/gnu/gdb/../bfd -I../../../Src/gnu/gdb/../include -I.
./../../Src/gnu/gdb/../../BUILD_ENV/usr/include -I../../../Src/gnu/gdb/../includ
e/elf -I../intl -I../../../Src/gnu/gdb/../intl -DUI_OUT=1 -DTUI=1 -I../../../Src
/gnu/gdb/tui

          HP92453-01  ; W113101
          Compile Time: Thu Dec 08 2005 23:21:13.000000000 PST
          Source  Time: Thu Nov 17 2005 02:36:02.000000000 PST

   For PA64 objects the more familiar elfdump tool shows the same info via
the -dc option.

> > I downloaded this wdb binary from HP's website and their documentation
> > also seems to suggest that it is compiled with HP compilers.

   That's right.

> I've changed my mind.  This code is compiled by a HP compiler.  So,
> it better be ABI compliant.  I was confused by the code that has been
> moved into the prologue.

   That optimization is done by the HP PA-RISC compilers under the
+Oentrysched option.  Here's what the man page has to say about it :

      +O[no]entrysched
                     Perform [do not perform] instruction scheduling on a
                     subprogram's entry and exit code sequences.  This
                     optimization can occur at optimization levels 1, 2, 3,
                     and 4.  The default is +Onoentrysched.

The unwind implications are that an aggressive form of (Ada-style) unwind
called context restoration won't work, but regular stack tracebacks do.

> GCC doesn't set "args_stored".  The register saves for r4, r5 and r6
> are in different locations than gcc would use.  On checking, the frame
> marker copy is slightly different.  Gcc doesn't copy slot at "-10" and
> we actually save the previous stack pointer at sp - 4 when the frame
> pointer is needed.

> > >> (gdb) maintenance print unwind execute_command
> > >> unwind_table_entry (0x40286424):
> > >>          region_start = 0xcb44c <execute_command>
> > >>          region_end = 0xcb798 <execute_command+844>
> > >>          flags = Args_stored Save_RP
> > > 
> > > I don't understand why you don't see SAVE_SP in the flags.

   There are two bits in the "struct unwind_table_entry" defined in
config/pa/tm-hppa.h (at least in the WDB sources) that cover alloca() use
and +Oentrysched use:

    unsigned int sched_entry_seq:1;     /* 25 */
		...
    unsigned int alloca_frame:1;        /* 35 */

Unfortunately, even HP gdb doesn't print out those fields for a "maintenance
print unwind" command

						- Carl Burch
						  HP WDB Team

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

end of thread, other threads:[~2005-12-11 14:45 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-12-09  0:08 [hpux] interesting but difficult to unwind code Randolph Chung
2005-12-09  0:44 ` John David Anglin
2005-12-09  3:33   ` Randolph Chung
2005-12-09  4:55     ` John David Anglin
2005-12-09 18:47 Carl Burch
2005-12-10  0:43 ` John David Anglin
2005-12-11 14:45 ` Randolph Chung

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).