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+000028

The 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 ()