Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [RFC/RFA/hppa] unwind pc in bottom frame using correct register
@ 2004-12-04  5:31 Joel Brobecker
  2004-12-04  7:51 ` Randolph Chung
  0 siblings, 1 reply; 8+ messages in thread
From: Joel Brobecker @ 2004-12-04  5:31 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 6435 bytes --]

This is where I truly show how ignorant I am about the hppa
archictecture... I need to stop working on GDB for now, as I need
to prepare my trip to Paris on sunday morning (will be working from
there for the week).

This is an interesting bug that I hit... I used the little Ada program
copied at the end of this email. If you have a GNAT compiler, you can
build it using the following command:

        % gnatmake -g task_switch

I tried switching to a specific thread, and I'm having some trouble.
The interesting part is that the thread switch would fail the first
time I attempt it (this is with gdb-6.3 but the same goes with head):

        (gdb) b break_me
        Breakpoint 1 at 0xa684: file task_switch.adb, line 43.
        (gdb) run
        Starting program: /[...]/task_switch 
        [New thread 2 (system thread 18450)]
        [New thread 3 (system thread 18451)]
        [Switching to thread 3 (system thread 18451)]
        
        Breakpoint 1, task_switch.break_me () at task_switch.adb:43
        43         end Break_Me;
        (gdb) thread 2
        [Switching to thread 2 (system thread 18450)]#0  0x7b040820 in ?? ()
        (gdb) bt
        #0  0x7b040820 in ?? ()
        warning: Cannot find bounds of current function (@0x0),
        unwinding will fail.

The "0x7b040820" address is wrong. And this also cause the "bt"
failure.

If I quit GDB, and then retry, this time it "works". Try it several
times after, it will alway "work". Rebuild the program, and it will
stop working ONE time. Then it'll "work".

        (gdb) thread 2
        [Switching to thread 2 (system thread 18666)]#0  0x00013220 in system.tasking.rendezvous.accept_trivial ()
        (gdb) bt
        #0  0x00013220 in system.tasking.rendezvous.accept_trivial ()
        #1  0x7aedf448 in _lwp_cond_timedwait () from /usr/lib/libpthread.1
        #2  0x7aedf184 in pthread_cond_wait () from /usr/lib/libpthread.1
        #3  0x7aedf120 in pthread_cond_wait () from /usr/lib/libpthread.1
        #4  0x000164b0 in system.tasking.rendezvous.wait_for_call ()
        #5  0x0001345c in system.tasking.rendezvous.accept_trivial ()
        #6  0x0000a4b8 in task_switch.callee (<_task>=0x4001d020)
            at task_switch.adb:29
        #7  0x0000a458 in task_switch__calleeB___3 () at task_switch.adb:24
        #8  0x0001780c in system.tasking.stages.task_wrapper ()
        #9  0x000176e0 in system__tasking__stages__task_wrapper ()
        #10 0x7aee0f60 in __pthread_create_system () from /usr/lib/libpthread.1
        #11 0x7aee0f08 in __pthread_create_system () from /usr/lib/libpthread.1

But if you look a bit closer, you see that the callstack is not
that good yet. Indeed, frame #0 is not correct. The rest of the frame
looks OK, but only by chance most probably.

That's when I found that hppa_unwind_pc() always returns the value of
the PCOQ register. On the other hand, the register used by
hppa_target_read_pc() to get PC depends on the value of the flags
register (we get the PC either from PCOQ, or GR31). I have quickly
scanned some of the docs I found on hppa, and couldn't find what this
refers to. So I am a bit in the dark.  I have asked one of my coworkers
in Paris to illuminate me, so I expect to be more knowledgeable on
monday :-).

In any case, this seemed inconsistent, so I came up with the idea
of calling hppa_target_read_pc() when uwinding the PC from the
sentinel frame. And that fixes the problem nicely:

        (gdb) bt
        #0  0x7afff708 in __ksleep () from /usr/lib/libc.2
        #1  0x7aedf448 in _lwp_cond_timedwait () from /usr/lib/libpthread.1
        #2  0x7aedf184 in pthread_cond_wait () from /usr/lib/libpthread.1
        #3  0x7aedf120 in pthread_cond_wait () from /usr/lib/libpthread.1
        #4  0x000164b0 in system.tasking.rendezvous.wait_for_call ()
        #5  0x0001345c in system.tasking.rendezvous.accept_trivial ()
        #6  0x0000a4b8 in task_switch.callee (<_task>=0x4001d020)
            at task_switch.adb:29
        #7  0x0000a458 in task_switch__calleeB___3 () at task_switch.adb:24
        #8  0x0001780c in system.tasking.stages.task_wrapper ()
        #9  0x000176e0 in system__tasking__stages__task_wrapper ()
        #10 0x7aee0f60 in __pthread_create_system () from /usr/lib/libpthread.1
        #11 0x7aee0f08 in __pthread_create_system () from /usr/lib/libpthread.1

This is much more plausible, and is actually what we get with
gdb-5.3 (minus the linker stubs).

I only spotted one problem in the testsuite: We get an error when trying
to get the flags register off a core file. We get 2 new fails in
corefile.exp. So I added an additional check against being in a core
file, and voila, no regression.

It's all a bit experimental, because of my lack of knowledge of the hppa
architecture. But I feel I might be on the right track, so I'm posting
the patch here, before leaving.

2004-12-03  Joel Brobecker  <brobecker@gnat.com>

        * hppa-tdep.c (hppa_unwind_pc): Use hppa_target_read_pc to fetch
        the PC for the sentinel frame, except when debugging a core file.

Tested on hppa2.0w-hp-hpux11.00. How does it look?

BTW: It would be nice to also comment on the fact that we don't
     call hppa_target_read_pc() if !target_has_execution and explain
     why. But I don't know why we don't have access to the flags reg
     yet. So I'll add that as a followup patch as soon as I have figured
     it out.

-- 
Joel

procedure Task_Switch is

   -------------------
   -- Declaractions --
   -------------------

   task type Callee is
      entry Finito;
   end Callee;
   type Callee_Ptr is access Callee;

   task type Caller is
   end Caller;
   type Caller_Ptr is access Caller;

   procedure Break_Me;

   My_Caller : Caller_Ptr;
   My_Callee : Callee_Ptr;

   ------------
   -- Bodies --
   ------------

   task body Callee is
   begin
      --  Just wait until we are told to terminate this task.
      --  This is just to maintain this task alive.
      accept Finito do
         null;
      end Finito;
   end Callee;

   task body Caller is
   begin
      Break_Me;
      My_Callee.Finito;
   end Caller;

   procedure Break_Me is
   begin
      null;
   end Break_Me;

begin

   --  Make sure to create the Callee task first... And then give it
   --  enough time to complete its activation phase before we start
   --  the Caller task.
   My_Callee := new Callee;
   delay 0.1;

   My_Caller := new Caller;

end Task_Switch;


[-- Attachment #2: readpc.diff --]
[-- Type: text/plain, Size: 838 bytes --]

Index: hppa-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/hppa-tdep.c,v
retrieving revision 1.183
diff -u -p -r1.183 hppa-tdep.c
--- hppa-tdep.c	1 Dec 2004 06:54:56 -0000	1.183
+++ hppa-tdep.c	4 Dec 2004 04:15:30 -0000
@@ -2185,6 +2185,12 @@ hppa_unwind_dummy_id (struct gdbarch *gd
 static CORE_ADDR
 hppa_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
+  /* If unwinding the PC from the sentinel frame, then which register
+     to read depends on the value of the status register.  Use
+     hppa_target_read_pc(), it knows where to get the PC.  */
+  if (target_has_execution && frame_relative_level (next_frame) < 0)
+    return hppa_target_read_pc (inferior_ptid);
+
   return frame_unwind_register_signed (next_frame, HPPA_PCOQ_HEAD_REGNUM) & ~3;
 }
 

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

* Re: [RFC/RFA/hppa] unwind pc in bottom frame using correct register
  2004-12-04  5:31 [RFC/RFA/hppa] unwind pc in bottom frame using correct register Joel Brobecker
@ 2004-12-04  7:51 ` Randolph Chung
  2004-12-04  8:46   ` Joel Brobecker
  0 siblings, 1 reply; 8+ messages in thread
From: Randolph Chung @ 2004-12-04  7:51 UTC (permalink / raw)
  To: gdb-patches; +Cc: brobecker

> --- hppa-tdep.c	1 Dec 2004 06:54:56 -0000	1.183
> +++ hppa-tdep.c	4 Dec 2004 04:15:30 -0000
> @@ -2185,6 +2185,12 @@ hppa_unwind_dummy_id (struct gdbarch *gd
>  static CORE_ADDR
>  hppa_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
>  {
> +  /* If unwinding the PC from the sentinel frame, then which register
> +     to read depends on the value of the status register.  Use
> +     hppa_target_read_pc(), it knows where to get the PC.  */
> +  if (target_has_execution && frame_relative_level (next_frame) < 0)
> +    return hppa_target_read_pc (inferior_ptid);
> +
>    return frame_unwind_register_signed (next_frame, HPPA_PCOQ_HEAD_REGNUM) & ~3;
>  }

this is wrong... perhaps you can do:

  if (frame_unwind_register_signed (next_frame, HPPA_FLAG_REGNUM) & 2)
    pc = frame_unsigned_register_signed (next_frame, 31);
  else
    pc = frame_unsigned_register_signed (next_frame, HPPA_PCOQ_HEAD_REGNUM);
  pc &= ~3;
  return pc;

this should work on corefiles too.....

the bit about HPPA_FLAG_REGNUM seems to be an hpux specific thing. I
think the syscall stub does something special so we try to return r31
instead of pcoqh. I haven't looked at this in detail...

i don't like having two versions of essentially the same function
either; Andrew mentioned in another email that this is a bug, but i
didn't understand if he meant this is a core-gdb bug or a hppa-specific
bug...

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


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

* Re: [RFC/RFA/hppa] unwind pc in bottom frame using correct register
  2004-12-04  7:51 ` Randolph Chung
@ 2004-12-04  8:46   ` Joel Brobecker
  2004-12-04 10:53     ` Randolph Chung
  0 siblings, 1 reply; 8+ messages in thread
From: Joel Brobecker @ 2004-12-04  8:46 UTC (permalink / raw)
  To: Randolph Chung; +Cc: gdb-patches

Thanks for the feedback,

> > --- hppa-tdep.c	1 Dec 2004 06:54:56 -0000	1.183
> > +++ hppa-tdep.c	4 Dec 2004 04:15:30 -0000
> > @@ -2185,6 +2185,12 @@ hppa_unwind_dummy_id (struct gdbarch *gd
> >  static CORE_ADDR
> >  hppa_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
> >  {
> > +  /* If unwinding the PC from the sentinel frame, then which register
> > +     to read depends on the value of the status register.  Use
> > +     hppa_target_read_pc(), it knows where to get the PC.  */
> > +  if (target_has_execution && frame_relative_level (next_frame) < 0)
> > +    return hppa_target_read_pc (inferior_ptid);
> > +
> >    return frame_unwind_register_signed (next_frame, HPPA_PCOQ_HEAD_REGNUM) & ~3;
> >  }
> 
> this is wrong... perhaps you can do:
> 
>   if (frame_unwind_register_signed (next_frame, HPPA_FLAG_REGNUM) & 2)
>     pc = frame_unsigned_register_signed (next_frame, 31);
>   else
>     pc = frame_unsigned_register_signed (next_frame, HPPA_PCOQ_HEAD_REGNUM);
>   pc &= ~3;
>   return pc;


:-(

Almost works. We get the first frame right, but then the backtraces
are broken because we get identical frames. This sort of makes sense
to me, since once you are past frame 0, you know which register to
unwind by inspecting the function associated to the frame (either prologue
analysis, or using the unwind info, or ...). No? So I would venture
that the SS_INSYSCALL thingy might be specific to the innermost frame?

With your patch, we get:

        (gdb) bt
        #0  0x7afff708 in __ksleep () from /usr/lib/libc.2
        #1  0x7afff708 in __ksleep () from /usr/lib/libc.2

or

        (gdb) bt
        #0  0x7afff760 in __kwakeup () from /usr/lib/libc.2
        #1  0x7afff760 in __kwakeup () from /usr/lib/libc.2

More on this if/when I understand hppa_target_read_pc() better.

> the bit about HPPA_FLAG_REGNUM seems to be an hpux specific thing. I
> think the syscall stub does something special so we try to return r31
> instead of pcoqh. I haven't looked at this in detail...

If it's HP/UX specific, it must be hurting hppa-linux?

> i don't like having two versions of essentially the same function
> either; Andrew mentioned in another email that this is a bug, but i
> didn't understand if he meant this is a core-gdb bug or a hppa-specific
> bug...

-- 
Joel


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

* Re: [RFC/RFA/hppa] unwind pc in bottom frame using correct register
  2004-12-04  8:46   ` Joel Brobecker
@ 2004-12-04 10:53     ` Randolph Chung
  2004-12-04 12:42       ` Mark Kettenis
  0 siblings, 1 reply; 8+ messages in thread
From: Randolph Chung @ 2004-12-04 10:53 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: gdb-patches

> Almost works. We get the first frame right, but then the backtraces
> are broken because we get identical frames. This sort of makes sense
> to me, since once you are past frame 0, you know which register to
> unwind by inspecting the function associated to the frame (either prologue
> analysis, or using the unwind info, or ...). No? So I would venture
> that the SS_INSYSCALL thingy might be specific to the innermost frame?

hrm, yes.... you are right.

> > the bit about HPPA_FLAG_REGNUM seems to be an hpux specific thing. I
> > think the syscall stub does something special so we try to return r31
> > instead of pcoqh. I haven't looked at this in detail...
> 
> If it's HP/UX specific, it must be hurting hppa-linux?

well, on hppa-linux the "flags" register is always 0, so we always read
pcoqh.

as you said i think we need to first better understand what is this
SS_INSYSCALL thing....

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


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

* Re: [RFC/RFA/hppa] unwind pc in bottom frame using correct register
  2004-12-04 10:53     ` Randolph Chung
@ 2004-12-04 12:42       ` Mark Kettenis
  2004-12-08  4:33         ` Randolph Chung
  0 siblings, 1 reply; 8+ messages in thread
From: Mark Kettenis @ 2004-12-04 12:42 UTC (permalink / raw)
  To: randolph; +Cc: brobecker, gdb-patches

   Date: Sat, 4 Dec 2004 00:46:24 -0800
   From: Randolph Chung <randolph@tausq.org>

Funny, I was just looking at the same issue yesterday.

   > Almost works. We get the first frame right, but then the backtraces
   > are broken because we get identical frames. This sort of makes sense
   > to me, since once you are past frame 0, you know which register to
   > unwind by inspecting the function associated to the frame (either prologue
   > analysis, or using the unwind info, or ...). No? So I would venture
   > that the SS_INSYSCALL thingy might be specific to the innermost frame?

   hrm, yes.... you are right.

   > > the bit about HPPA_FLAG_REGNUM seems to be an hpux specific thing. I
   > > think the syscall stub does something special so we try to return r31
   > > instead of pcoqh. I haven't looked at this in detail...
   > 
   > If it's HP/UX specific, it must be hurting hppa-linux?

   well, on hppa-linux the "flags" register is always 0, so we always read
   pcoqh.

Given that this "flags" register isn't a real ISA register but an
HP-UX-specific thingy that makes sense.  For OpenBSD/NetBSD I don't
explicitly set the "flags" register, which means it'll contain 0 as
long as you don't change it.  Hmm, I think the code that looks at this
"flags" register should be moved into hppa-hpux-tdep.c.

   as you said i think we need to first better understand what is this
   SS_INSYSCALL thing....

Well, I've never seen the HP-UX source code, but it seems that the
pcoqh and pcoqt returned by ttrace(2) when the program being debugged
is in a system call, are the pcoqh and pcoqt for the currently running
kernel code, which are quite useless to us.  Apparently, at that stage
%r31 contains the address where the system call will return to, which
actually is what we're interested in.

Anyway, the problems Joel sees can be fixed by explicitly setting
"flags" to zero in all unwound frames.  This somehow seems the correct
approach since this "flags" register is only meaningful in the
sentinel frame.  This is implemented by the attached patch (wich will
no longer apply after Randolph's recent change, but you get the idea).

Alternatively, we can ditch this "flags" register alltogether, and let
the native code deal with it.  Unfortunately that means that any
implementations of the remote protocol will have to be changed to.

Anyway, if y'all agree I can check in something along the lines of the
patch below tomorrow.

Mark


Index: hppa-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/hppa-tdep.c,v
retrieving revision 1.183
diff -u -p -r1.183 hppa-tdep.c
--- hppa-tdep.c 1 Dec 2004 06:54:56 -0000 1.183
+++ hppa-tdep.c 4 Dec 2004 11:02:43 -0000
@@ -2185,6 +2185,12 @@ hppa_unwind_dummy_id (struct gdbarch *gd
 static CORE_ADDR
 hppa_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
+  ULONGEST flags;
+
+  flags = frame_unwind_register_unsigned (next_frame, HPPA_FLAGS_REGNUM);
+  if (flags & 2)
+    return frame_unwind_register_signed (next_frame, HPPA_R31_REGNUM) & ~3;
+
   return frame_unwind_register_signed (next_frame, HPPA_PCOQ_HEAD_REGNUM) & ~3;
 }
 
@@ -2413,6 +2419,18 @@ hppa_frame_prev_register_helper (struct 
       *realnump = -1;
       return;
     }
+  if (regnum == HPPA_FLAGS_REGNUM)
+    {
+      if (valuep)
+	store_unsigned_integer (valuep, 4, 0);
+
+      /* It's a computed value.  */
+      *optimizedp = 0;
+      *lvalp = not_lval;
+      *addrp = 0;
+      *realnump = -1;
+      return;
+    }
 
   trad_frame_get_prev_register (next_frame, saved_regs, regnum,
 				optimizedp, lvalp, addrp, realnump, valuep);


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

* Re: [RFC/RFA/hppa] unwind pc in bottom frame using correct register
  2004-12-04 12:42       ` Mark Kettenis
@ 2004-12-08  4:33         ` Randolph Chung
  2004-12-08  8:21           ` Randolph Chung
  0 siblings, 1 reply; 8+ messages in thread
From: Randolph Chung @ 2004-12-08  4:33 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: brobecker, gdb-patches

> Anyway, the problems Joel sees can be fixed by explicitly setting
> "flags" to zero in all unwound frames.  This somehow seems the correct
> approach since this "flags" register is only meaningful in the
> sentinel frame.  This is implemented by the attached patch (wich will
> no longer apply after Randolph's recent change, but you get the idea).

hrm, something is broken. on hppa64-hp-hpux11.11 this is causing a lot
of unwinding failures. the hpux unwind_pc method is getting flags that
have the magic "2" bit set, so it gets the pc from 31 instead of the
pcoqh register.

i don't quite yet understand why this is happening. if i do "print
$flags" on frame #0 the value seems reasonable.

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


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

* Re: [RFC/RFA/hppa] unwind pc in bottom frame using correct register
  2004-12-08  4:33         ` Randolph Chung
@ 2004-12-08  8:21           ` Randolph Chung
  2004-12-08 22:20             ` Mark Kettenis
  0 siblings, 1 reply; 8+ messages in thread
From: Randolph Chung @ 2004-12-08  8:21 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: brobecker, gdb-patches

> hrm, something is broken. on hppa64-hp-hpux11.11 this is causing a lot
> of unwinding failures. the hpux unwind_pc method is getting flags that
> have the magic "2" bit set, so it gets the pc from 31 instead of the
> pcoqh register.

figured it out.. we were only clearing the first half of the register on
64-bit... i committed the following patch to fix the problem.

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


2004-12-07  Randolph Chung  <tausq@debian.org>

	* hppa-tdep.c (hppa_frame_prev_register_helper): Zero out the entire
	register for both 32- and 64-bit targets.

Index: hppa-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/hppa-tdep.c,v
retrieving revision 1.188
diff -u -p -r1.188 hppa-tdep.c
--- hppa-tdep.c	8 Dec 2004 01:48:02 -0000	1.188
+++ hppa-tdep.c	8 Dec 2004 06:09:45 -0000
@@ -2459,7 +2467,10 @@ hppa_frame_prev_register_helper (struct 
   if (regnum == HPPA_FLAGS_REGNUM)
     {
       if (valuep)
-	store_unsigned_integer (valuep, 4, 0);
+	store_unsigned_integer (valuep, 
+			        register_size (get_frame_arch (next_frame), 
+					       regnum), 
+				0);
 
       /* It's a computed value.  */
       *optimizedp = 0;


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

* Re: [RFC/RFA/hppa] unwind pc in bottom frame using correct register
  2004-12-08  8:21           ` Randolph Chung
@ 2004-12-08 22:20             ` Mark Kettenis
  0 siblings, 0 replies; 8+ messages in thread
From: Mark Kettenis @ 2004-12-08 22:20 UTC (permalink / raw)
  To: randolph; +Cc: brobecker, gdb-patches

   Date: Tue, 7 Dec 2004 22:12:39 -0800
   From: Randolph Chung <randolph@tausq.org>

   > hrm, something is broken. on hppa64-hp-hpux11.11 this is causing a lot
   > of unwinding failures. the hpux unwind_pc method is getting flags that
   > have the magic "2" bit set, so it gets the pc from 31 instead of the
   > pcoqh register.

Duh!  Sorry 'bout that.  The `ss_flags' field is declared as an `int'
so I thought it was 4 bytes everywhere.

   figured it out.. we were only clearing the first half of the register on
   64-bit... i committed the following patch to fix the problem.

Thanks,

Mark


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

end of thread, other threads:[~2004-12-08 20:01 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-12-04  5:31 [RFC/RFA/hppa] unwind pc in bottom frame using correct register Joel Brobecker
2004-12-04  7:51 ` Randolph Chung
2004-12-04  8:46   ` Joel Brobecker
2004-12-04 10:53     ` Randolph Chung
2004-12-04 12:42       ` Mark Kettenis
2004-12-08  4:33         ` Randolph Chung
2004-12-08  8:21           ` Randolph Chung
2004-12-08 22:20             ` Mark Kettenis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox