[Crash-utility] How do I get IA64 register R32 and above?

Dave Anderson anderson at prospeed.net
Tue Apr 23 21:15:53 UTC 2013


Correction: actually rse_function_params() was written by me,
but what I meant was that it uses the kernel's unw_access_gr()
function to read the argument registers.  Here's the part of
unw_access_gr() that that accesses registers 32 and above:


        } else {
                /* access a stacked register */
                addr = ia64_rse_skip_regs((unsigned long *) info->bsp,
regnum - 32);
                nat_addr = ia64_rse_rnat_addr(addr);
                if ((unsigned long) addr < info->regstk.limit
                    || (unsigned long) addr >= info->regstk.top)
                {
                        error(INFO, "unwind: ignoring attempt to access
register outside of rbs\n");
                        return -1;
                }
                if ((unsigned long) nat_addr >= info->regstk.top)
                        nat_addr = &info->sw->ar_rnat;
                nat_mask = (1UL << ia64_rse_slot_num(addr));
        }

I don't remember much about the ia64 backing store stuff, but
I guess it is possible that the arguments shown by "bt -f" may
very well be their current state.

Dave



----- Original Message -----
> On Mon, 2013-04-22 at 16:38 -0700, Jay Lan wrote:
> > Hi,
> >
> > I got an IA64 vmcore. The stack backtrace only
> > printed registers up to R31. How do I get the contents
> > of R32 and above?
> >
> > Thanks,
> > Jay
>
> Jay, here's an excerpt from an email I answered in 2006.  It's not clear
> that I remember anything about this now :-)   Hope it helps.
>
> Bob Montgomery
>
> --------------------------------
>
>
> >  #8 [BSP:e00000404ae490e8] mdc_replay_open at a00000020122f490
> >     (e0000040ffcd1f10)
> >     ...mdc/mdc_request.c: 332
> >  #9 [BSP:e00000404ae49078] ptlrpc_replay_interpret at a0000002013ed930
> >     (e0000040ff86f300)
> >     ...ptlrpc/client.c: 1636
> > #10 [BSP:e00000404ae48fe8] ptlrpc_check_set at a0000002013e14c0
> >     (e0000000015eda80)
> >
>
> There are three big secrets:
>
> 1) The saved values of the stack frame registers (r32, r33, ... up to
> the limit set by the alloc statement at the beginning of the function
> for that frame) are located at the Backing Store Pointer (BSP) shown for
> the frame.  If you want to see r32, r33, r34, r35 for frame #8, do
>         crash> x/4xg 0xe00000404ae490e8
>
> 2) The saved values of the stack frame registers are their current
> values, not necessarily the values passed in to the function (for those
> registers that were used as input registers, for example).  In other
> words, the first parameter is passed as r32, but r32 might be modified
> by that function before the point in the code represented by the stack
> trace.  Check for this by disassembling:
>         crash> dis mdc_replay_open | grep r32
> and looking to see where (if ever) r32 is modified (appears on the left
> hand side of an "=") in that function.
>
> 3)  Every 64th word in the backing store is a NaT register store, not a
> regular register.  So when you're counting words from the BSP pointer
> for that frame to match up with registers, skip any word whose address
> ends in 0x1f8, 0x3f8, 0x5f8, ...
>
> crash is trying to show you the passed parameters.  If that's working,
> those values in parentheses at each level should correspond to r32,
> r33 ... for as many as shown.  If I remember right, crash doesn't do
> that very well for functions in modules.
> ---------------------------------------------------------------

The "bt -f" option uses the rse_function_params() function backported
from the kernel's ia64 unwind facility.  And they do appear to be as
you described, i.e., at the BSP address location.  For example:

 crash> bt -f
  PID: 1      TASK: e0000100ff118000  CPU: 0   COMMAND: "init"
   #0 [BSP:e0000100ff119358] schedule at a000000100678b90
      (void)
   #1 [BSP:e0000100ff119328] schedule_timeout at a00000010067a1b0
      (1388)
   #2 [BSP:e0000100ff119250] do_select at a0000001001b0090
      (e0000100fe518180, e0000100ff11fce0, e0000100ff11fe10)
   #3 [BSP:e0000100ff1191f0] core_sys_select at a0000001001b0990
      (b, 60000fffffdf77a8, 0, 0, e0000100ff11fe10)
   #4 [BSP:e0000100ff119160] sys_select at a0000001001b18b0
      (b, 60000fffffdf77a8, 0, 0, 60000fffffdf7828)
   #5 [BSP:e0000100ff119160] ia64_ret_from_syscall at a00000010000be40
    EFRAME: e0000100ff11fe40
        B0: 400000000000aee0      CR_IIP: a000000000010620
   CR_IPSR: 00001213085a6010      CR_IFS: 0000000000000005
    AR_PFS: c000000000000005      AR_RSC: 000000000000000f
   AR_UNAT: 0000000000000000     AR_RNAT: 0000000000000000
    AR_CCV: 0000000000000000     AR_FPSR: 0009804c8a70033f
    LOADRS: 0000000000c00000 AR_BSPSTORE: 600007ffffdfc138
        B6: 20000000002cb1a0          B7: a00000010000fc20
        PR: 0000000000026241          R1: 2000000000328238
        R2: a000000000010640          R3: e0000100ff11fef8
        R8: 0000000000000001          R9: 0000000051763204
       R10: 0000000000000000         R11: c000000000000611
       R12: 60000fffffdf7670         R13: 20000000003b55f0
       R14: a000000100707f18         R15: 0000000000000441
       R16: e0000100ff118000         R17: 000000000000003f
       R18: a00000010000fc20         R19: 000000000000011d
       R20: 0009804c8a70033f         R21: 0009804c8a70033f
       R22: 0000000000000000         R23: 600007ffffdfc138
       R24: 0000000000000000         R25: 0000000000000000
       R26: c000000000000002         R27: 000000000000000f
       R28: a000000000010620         R29: 00000010085a2010
       R30: 0000000000000005         R31: 0000000000026241
        F6: 000000000000000000000     F7: 000000000000000000000
        F8: 000000000000000000000     F9: 000000000000000000000
       F10: 000000000000000000000    F11: 000000000000000000000
   #6 [BSP:e0000100ff119160] __kernel_syscall_via_break at a000000000010620
  crash>

So if I look at the BSP location for the sys_select() frame #4:

   #4 [BSP:e0000100ff119160] sys_select at a0000001001b18b0
      (b, 60000fffffdf77a8, 0, 0, 60000fffffdf7828)

the arguments match up:

  crash> rd e0000100ff119160 5
  e0000100ff119160:  000000000000000b 60000fffffdf77a8   .........w.....`
  e0000100ff119170:  0000000000000000 0000000000000000   ................
  e0000100ff119180:  60000fffffdf7828                    (x.....`
  crash>

I would presume that even if they were modified in sys_select() that
rse_function_params() would still reflect the arguments as they were
passed in to the function.  Otherwise, what's the point of the function?

And I don't know why it would behave any differently for a module function?

Dave





More information about the Crash-utility mailing list