f subcommand
The f subcommand displays all of the stack frames from the current instruction as deep as possible. Interrupts and system calls are crossed and the user stack is displayed.
Format
f [+x | -x] [th {slot | address} ]
Parameters
Item | Description |
---|---|
+x | Includes hexadecimal addresses as well as symbolic names for calls on the stack. This option remains set for future invocations of the stack subcommand until it is changed using the -x flag. |
-x | Suppresses the display of hexadecimal addresses for functions on the stack. This option remains in effect for future invocations of the stack subcommand until it is changed using the +x flag. |
slot | Indicates the thread slot number. It is a decimal value. |
Address | Indicates the effective address for a thread slot. It is a hexadecimal address, hexadecimal expression, or symbol. |
In the user space, trace back allows the display of symbolic names, but the KDB kernel debugger cannot directly access these symbols. Use the +x toggle to have hexadecimal addresses displayed (for example, to put a break point on one of these addresses). If invoked with no parameter, the stack for the current thread is displayed. The stack for a particular thread can be displayed by specifying its slot number or address.
For some compilation options, specifically -O, routine parameters are not saved in the stack. KDB warns about this by displaying [??] at the end of the line. In this case, the displayed routine parameters might be wrong.
Other
stack, where
Examples
The following is an example of how to use the f subcommand. In the following example, a break point is set on v_gettlock and when the break point is encountered, the stack is displayed. The first parameter of the open() syscall is displayed and saved by copen() in register R31. Register R31 is saved in the stack by openpath(). The first parameter is found by looking at the memory pointed to by register R31.
KDB(2)> f //show the stack
thread+012540 STACK:
[0004AC84]v_gettlock+000000 (00012049, C0011E80, 00000080, 00000000 [??]) <-- Optimized code, note [??]
[00085C18]v_pregettlock+0000B4 (??, ??, ??, ??)
[000132E8]isync_vcs1+0000D8 (??, ??)
____ Exception (2FF3B400) ____
[000131FC].backt+000000 (00012049, C0011E80 [??]) <-- Optimized code, note [??]
[0004B220]vm_gettlock+000020 (??, ??)
[0019A64C]iwrite+00013C (??)
[0019D194]finicom+0000A0 (??, ??)
[0019D4F0]comlist+0001CC (??, ??)
[0019D5BC]_commit+000030 (00000000, 00000001, 09C6E9E8, 399028AA,
0000A46F, 0000E2AA, 2D3A4EAA, 2FF3A730)
[001E1B18]jfs_setattr+000258 (??, ??, ??, ??, ??, ??)
[001A5ED4]vnop_setattr+000018 (??, ??, ??, ??, ??, ??)
[001E9008]spec_setattr+00017C (??, ??, ??, ??, ??, ??)
[001A5ED4]vnop_setattr+000018 (??, ??, ??, ??, ??, ??)
[01B655C8]pty_vsetattr+00002C (??, ??, ??, ??, ??, ??)
[01B6584C]pty_setname+000084 (??, ??, ??, ??, ??, ??)
[01B60810]pty_create_ptp+0002C4 (??, ??, ??, ??, ??)
[01B60210]pty_open_comm+00015C (??, ??, ??, ??)
[01B5FFC0]call_pty_open_comm+0000B8 (??, ??, ??, ??)
[01B6526C]ptm_open+000140 (??, ??, ??, ??, ??)
(2)> more (^C to quit) ?
[01A9A124]open_wrapper+0000D0 (??)
[01A8DF74]csq_protect+000258 (??, ??, ??, ??, ??, ??)
[01A96348]osr_open+0000BC (??)
[01A9C1C8]pse_clone_open+000164 (??, ??, ??, ??)
[001ADCC8]spec_clone+000178 (??, ??, ??, ??, ??)
[001B3FC4]openpnp+0003AC (??, ??, ??, ??, ??)
[001B4178]openpath+000064 (??, ??, ??, ??, ??, ??)
[001B43E8]copen+000130 (??, ??, ??, ??, ??)
[001B44BC]open+000014 (??, ??, ??)
[000037D8].sys_call+000000 ()
[10002E74]doit+00003C (??, ??, ??)
[10003924]main+0004CC (??, ??)
[1000014C].__start+00004C ()
KDB(2)> set 10 //show saved registers
display_stacked_regs is true
KDB(2)> f //show the stack
thread+012540 STACK:
[0004AC84]v_gettlock+000000 (00012049, C0011E80, 00000080, 00000000 [??])
...
[001B3FC4]openpnp+0003AC (??, ??, ??, ??, ??)
r24 : 2FF3B6E0 r25 : 2FF3B400 r26 : 10002E78 r27 : 00000000 r28 : 00000002
r29 : 2FF3B3C0 r30 : 00000000 r31 : 20000510
[001B4178]openpath+000064 (??, ??, ??, ??, ??, ??)
[001B43E8]copen+000130 (??, ??, ??, ??, ??)
r27 : 2A22A424 r28 : E3014000 r29 : E6012540 r30 : 0C87B000 r31 : 00000000
[001B44BC]open+000014 (??, ??, ??)
...
KDB(2)> dc open 6 //look for parameter R3
.open+000000 stwu stkp,FFFFFFC0(stkp)
.open+000004 mflr r0
.open+000008 addic r7,stkp,38
.open+00000C stw r0,48(stkp)
.open+000010 li r6,0
.open+000014 bl <.copen>
KDB(2)> dc copen 9 //look for parameter R3
.copen+000000 stmw r27,FFFFFFEC(stkp)
.copen+000004 addi r28,r4,0
.copen+000008 mflr r0
.copen+00000C lwz r4,D5C(toc) D5C(toc)=audit_flag
.copen+000010 stw r0,8(stkp)
.copen+000014 stwu stkp,FFFFFFA0(stkp)
.copen+000018 cmpi cr0,r4,0
.copen+00001C mtcrf cr5,r28
.copen+000020 addi r31,r3,0
KDB(2)> d 20000510 //display memory location @R31
20000510: 2F64 6576 2F70 7463 0000 0000 416C 6C20 /dev/ptc....All
In the following example, you must find what the lsfs subcommand is waiting for. The answer is given with getfssize parameters, which are saved in the stack.
# ps -ef|grep lsfs
root 63046 39258 0 Apr 01 pts/1 0:00 lsfs
# kdb
Preserving 587377 bytes of symbol table
First symbol sys_resource
PFT:
id....................0007
raddr.............01000000 eaddr.............B0000000
size..............01000000 align.............01000000
valid..1 ros....0 holes..0 io.....0 seg....0 wimg...2
PVT:
id....................0008
raddr.............003BC000 eaddr.............B2000000
size..............001FFDA0 align.............00001000
valid..1 ros....0 holes..0 io.....0 seg....0 wimg...2
(0)> dcal 63046 //print hexadecimal value of PID
Value decimal: 63046 Value hexa: 0000F646
(0)> tpid 0000F646 //show threads of this PID
SLOT NAME STATE TID PRI CPUID CPU FLAGS WCHAN
thread+025440 795 lsfs SLEEP 31B31 03C 000 00000004 057DB5BC
(0)> sw 795 //set current context on this thread
Switch to thread: <thread+025440>
(0)> f //show the stack
thread+025440 STACK:
[000205C0]e_block_thread+000250 ()
[00020B1C]e_sleep_thread+000040 (??, ??, ??)
[0002AAA0]iowait+00004C (??)
[0002B40C]bread+0000DC (??, ??)
[0020AF4C]readblk+0000AC (??, ??, ??, ??)
[001E90D8]spec_rdwr+00007C (??, ??, ??, ??, ??, ??, ??, ??)
[001A6328]vnop_rdwr+000070 (??, ??, ??, ??, ??, ??, ??, ??)
[00198278]rwuio+0000CC (??, ??, ??, ??, ??, ??, ??, ??)
[001986AC]rdwr+000184 (??, ??, ??, ??, ??, ??)
[001984D4]kreadv+000064 (??, ??, ??, ??)
[000037D8].sys_call+000000 ()
[D0046A18]read+000028 (??, ??, ??)
[1000A0E4]get_superblk+000054 (??, ??, ??)
[100035F8]read_super+000024 (??, ??, ??, ??)
[10005C00]getfssize+0000A0 (??, ??, ??)
[10002D18]prnt_stanza+0001E8 (??, ??, ??)
[1000349C]do_ls+000294 (??, ??)
[10000524]main+0001E8 (??, ??)
[1000014C].__start+00004C ()
(0)> sw u //enable user context of the thread
(0)> dc 10005C00-a0 8 //look for parameters R3, R4, R5
10005B60 mflr r0
10005B64 stw r31,FFFFFFFC(stkp)
10005B68 stw r0,8(stkp)
10005B6C stwu stkp,FFFFFEE0(stkp)
10005B70 stw r3,108(stkp)
10005B74 stw r4,104(stkp)
10005B78 stw r5,10C(stkp)
10005B7C addi r3,r4,0
(0)> set 9 //print stack frame
display_stack_frames is true
(0)> f //show the stack
thread+025440 STACK:
[000205C0]e_block_thread+000250 ()
...
[100035F8]read_super+000024 (??, ??, ??, ??)
=======================================================================
2FF225D0: 2FF2 26F0 2A20 2429 1000 5C04 F071 71C0 /.&.* $)..\..qq.
2FF225E0: 2FF2 2620 2000 4D74 D000 4E18 F071 F83C /.& .Mt..N..q.<
2FF225F0: F075 2FF8 F074 36A4 F075 0FE0 F075 1FF8 .u/..t6..u...u..
2FF22600: F071 AE80 8080 8080 0000 0004 0000 0006 .q..............
=======================================================================
[10005C00]getfssize+0000A0 (??, ??, ??)
...
(0)> dw 2FF225D0+104 //print parameters (offset 0x104 0x108 0x10c)
2FF226D4: 2000DCC8 2000DC78 00000000 00000004
(0)> d 2000DC78 20 //print first parameter
2000DC78: 2F74 6D70 2F73 7472 6970 655F 6673 2E32 /tmp/stripe_fs.2
2000DC88: 3433 3632 0000 0000 0000 0000 0000 0004 4362............
(0)> d 2000DCC8 20 //print second parameter
2000DCC8: 2F64 6576 2F73 6C76 3234 3336 3200 0000 /dev/slv24362...
2000DCD8: 0000 0000 0000 0000 0000 0000 0000 0004 ................
(0)> q //leave debugger
#