sw subcommand
The sw subcommand allows a selected thread to be considered the current thread.
Format
sw [ {th_slot | th_Address} | {u | k} ]
Parameters
| Item | Description |
|---|---|
| u | Switches to user address space for the current thread. |
| k | Switches to kernel address space for the current thread. |
| th_slot | Specifies a thread slot number. This parameter must be a decimal value. |
| th_Address | Specifies the address of a thread slot. Symbols, hexadecimal values, or hexadecimal expressions can be used to specify the address. |
The u and k flags can be used to switch between the user and kernel address space for the current thread.
By default, KDB shows the virtual space for the current thread. Threads can be specified by slot number or address. The current thread can be reset to its initial context by entering the sw subcommand with no parameters. For the KDB kernel debugger, the initial context is also restored whenever you exit the KDB kernel debugger.
Other
switch
Examples
The following is an example of how to use the sw subcommand:
KDB(0)> sw 12 //switch to thread slot 12
Switch to thread: <thread+000900>
KDB(0)> f //print stack trace
thread+000900 STACK:
[000215FC]e_block_thread+000250 ()
[00021C48]e_sleep_thread+000070 (??, ??, ??)
[000200F4]errread+00009C (??, ??)
[001C89B4]rdevread+000120 (??, ??, ??, ??)
[0023A61C]cdev_rdwr+00009C (??, ??, ??, ??, ??, ??, ??)
[00216324]spec_rdwr+00008C (??, ??, ??, ??, ??, ??, ??, ??)
[001CEA3C]vnop_rdwr+000070 (??, ??, ??, ??, ??, ??, ??, ??)
[001BDB0C]rwuio+0000CC (??, ??, ??, ??, ??, ??, ??, ??)
[001BDF40]rdwr+000184 (??, ??, ??, ??, ??, ??)
[001BDD68]kreadv+000064 (??, ??, ??, ??)
[000037D8].sys_call+000000 ()
[D0046B68]read+000028 (??, ??, ??)
[1000167C]child+000120 ()
[10001A84]main+0000E4 (??, ??)
[1000014C].__start+00004C ()
KDB(0)> dr sr //display segment registers
s0 : 00000000 s1 : 007FFFFF s2 : 00000AB7 s3 : 007FFFFF s4 : 007FFFFF
s5 : 007FFFFF s6 : 007FFFFF s7 : 007FFFFF s8 : 007FFFFF s9 : 007FFFFF
s10 : 007FFFFF s11 : 007FFFFF s12 : 007FFFFF s13 : 6000058B s14 : 00000204
s15 : 60000CBB
KDB(0)> sw u //switch to user context
KDB(0)> dr sr //display segment registers
s0 : 60000000 s1 : 600009B1 s2 : 60000AB7 s3 : 007FFFFF s4 : 007FFFFF
s5 : 007FFFFF s6 : 007FFFFF s7 : 007FFFFF s8 : 007FFFFF s9 : 007FFFFF
s10 : 007FFFFF s11 : 007FFFFF s12 : 007FFFFF s13 : 6000058B s14 : 007FFFFF
s15 : 60000CBB
//Now it is possible to look at user code
//For example, find how read() is called by child()
KDB(0)> dc 1000167C //print child() code (seg 1 is now valid)
1000167C bl <1000A1BC>
KDB(0)> dc 1000A1BC 6 //print child() code
1000A1BC lwz r12,244(toc)
1000A1C0 stw toc,14(stkp)
1000A1C4 lwz r0,0(r12)
1000A1C8 lwz toc,4(r12)
1000A1CC mtctr r0
1000A1D0 bcctr
... //find stack pointer of child() routine with 'set 9; f'
[D0046B68]read+000028 (??, ??, ??)
=======================================================================
2FF22B50: 2FF2 2D70 2000 9910 1000 1680 F00F 3130 /.-p .........10
2FF22B60: F00F 1E80 2000 4C54 0000 0003 0000 4503 .... .LT......E.
2FF22B70: 2FF2 2B88 0000 D030 0000 0000 6000 0000 /.+....0....`...
2FF22B80: 6000 09B1 0000 0000 0000 0002 0000 0002 `...............
=======================================================================
[1000167C]child+000120 ()
...
(0)> dw 2FF22B50+14 1 //- stw toc,14(stkp)
2FF22B64: 20004C54 //toc address
(0)> dw 20004C54+244 1 //- lwz r12,244(toc)
20004E98: F00BF5C4 //function descriptor address
(0)> dw F00BF5C4 2 //- lwz r0,0(r12) - lwz toc,4(r12)
F00BF5C4: D0046B40 F00C1E9C //function descriptor (code and toc)
(0)> dc D0046B40 11 //- bcctr will branch to:
D0046B40 mflr r0
D0046B44 stw r31,FFFFFFFC(stkp)
D0046B48 stw r0,8(stkp)
D0046B4C stwu stkp,FFFFFFB0(stkp)
D0046B50 stw r5,3C(stkp)
D0046B54 stw r4,38(stkp)
D0046B58 stw r3,40(stkp)
D0046B5C addic r4,stkp,38
D0046B60 li r5,1
D0046B64 li r6,0
D0046B68 bl <D00ADC68> //read+000028The following example shows some of the differences between kernel and user mode for 64-bit process:
(0)> sw k //kernel mode
(0)> dr msr //kernel machine status register
msr : 000010B0 bit set: ME IR DR
(0)> dr r1 //kernel stack pointer
r1 : 2FF3B2A0 2FF3B2A0
(0)> f //stack frame (kernel MST)
thread+002A98 STACK:
[00031960]e_block_thread+000224 ()
[00041738]nsleep+000124 (??, ??)
[01CFF0F4]nsleep64_+000058 (0FFFFFFF, F0000001, 00000001, 10003730, 1FFFFEF0, 1FFFFEF8)
[000038B4].sys_call+000000 ()
[80000010000867C]080000010000867C (??, ??, ??, ??)
[80000010001137C]nsleep+000094 (??, ??)
[800000100058204]sleep+000030 (??)
[100000478]main+0000CC (0000000100000001, 00000000200FEB78)
[10000023C]__start+000044 ()
(0)> sw u //user mode
(0)> dr msr //user machine status register
msr : 800000004000D0B0 bit set: EE PR ME IR DR
(0)> dr r1 //user stack pointer
r1 : 0FFFFFFFFFFFFF00 0FFFFFFFFFFFFF00
(0)> f //stack frame (kernel MST extension)
thread+002A98 STACK:
[8000001000581D4]sleep+000000 (0000000000000064 [??])
[100000478]main+0000CC (0000000100000001, 00000000200FEB78)
[10000023C]__start+000044 ()