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