Son of Strike (SOS)

SOS is a debugger extension used to debug managed code. As a debugging extension, it must be loaded into a Win32-compliant debugger, such as WinDbg. SOS can provide information about the inner workings of a managed application. This might require that the user have a better understanding of the internal workings and structures of the CLR. SOS abstracts as much of the details as possible, allowing you to concentrate on the problem—debugging the application. When using a debugging extension, the debugger and debugging extension collaborate. Without a doubt, you will rely on both to resolve any application bugs.

Any of the following statements loads the SOS.dll debugging extension. To load a particular version of SOS, provide the fully qualified directory path. Here are some examples of loading SOS:

  • .load sos

  • .load sos.dll

  • .load c:pathsos.dll

You might have multiple versions of the .NET Framework installed on your computer. There also will be comparable versions of SOS.dll—one for each version of the .NET Framework. The following command loads the correct version of SOS.dll for the appropriate version of the CLR:

  • .loadby sos mscorwks

SOS Example, Part I

This example provides an introduction to SOS. Some of the output from the example has been shortened for clarity.

  1. Start the Store application in the sos subfolder outside a debugger. Only one debugger can be attached to an application at any time. Open the Transaction dialog box, as shown in Figure 16-3. Do not complete or close this dialog box.

    The Store application’s Transaction dialog box

    Figure 16-3. The Store application’s Transaction dialog box

  2. Start the WinDbg debugger and attach to the Store application. Load SOS.

  3. Enter the !threads command, which lists the managed threads and related information. Here is the abbreviated result:

    0:004> !threads
    ThreadCount: 2
    UnstartedThread: 0
    BackgroundThread: 1
    PendingThread: 0
    DeadThread: 0
    Hosted Runtime: no
                                          PreEmptive   GC Alloc           Lock
           ID OSID ThreadOBJ    State     GC       Context       Domain   Count
       0    1  424 001501f8      6020 Enabled  013da5dc:013dadb8 001483a8     0
       2    2  c24 00153e40      b220 Enabled  00000000:00000000 001483a8     0
  4. Change to Thread 0, which is a managed thread. This is a native WinDbg command:

    0:004> ~0s
    eax=790ff90c ebx=01392b50 ecx=013a7704 edx=0000ce7d esi=00000000 edi=013da5b8
    eip=7c90eb94 esp=0012edb4 ebp=0012ee4c iopl=0         nv up ei pl zr na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    ntdll!KiFastSystemCallRet:
    7c90eb94 c3               ret
  5. Enter the !clrstack command to display the stack trace for thread 0. The -p option shows the parameters for each method:

    0:000> !clrstack -p
    OS Thread Id: 0x424 (0)
    ESP       EIP
    0012edc0 7c90eb94 [InlinedCallFrame: 0012edc0] System.Windows.Forms.UnsafeNativeMethods.WaitMessage()
    0012edbc 7b094838 System.Windows.Forms.Application+ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32, Int32, Int32)
        PARAMETERS:
            this = 0x013a76ac
            dwComponentID = <no data>
            reason = 0x00000004
            pvLoopData = 0x00000000
    
    0012eef8 7b22e03e System.Windows.Forms.Form.ShowDialog(System.Windows.Forms.IWin32Window)
        PARAMETERS:
            this = 0x013b4494
            owner = <no data>
  6. The ShowDialog method and its parameters appear in the stack trace. The this reference is the first parameter of the method. The address of the this reference is provided. Use the dumpobj command to dump the this reference with this address. The output shows the identity of the this object as a Store.Transaction type. From the fields of Store.Transaction, it appears that Store.Transaction is a form:

    0:000> !dumpobj 0x013b4494
    Name: Store.Transaction
    MethodTable: 00d453a4
    EEClass: 00db3034
    Size: 372(0x174) bytes
     (C:storeStore.exe)
    Fields:
          MT    Field   Offset                 Type VT     Attr    Value Name
    790fa098  4000184        4        System.Object  0 instance 00000000 __identity
    7a765ca4  40008bc        8 ...ponentModel.ISite  0 instance 00000000 site
    7a762e84  40008bd        c ....EventHandlerList  0 instance 013b6964 events
    790fa098  40008bb      108        System.Object  0   static 00000000 EventDisposed
    7b4777e4  40010fa       10 ...ntrolNativeWindow  0 instance 013b55c4 window
    7b4754b4  40010fb       14 ...ows.Forms.Control  0 instance 00000000 parent
    7b4754b4  40010fc       18 ...ows.Forms.Control  0 instance 00000000 reflectParent
    7b478924  40010fd       1c ...orms.CreateParams  0 instance 013b560c createParams
    790fe920  40010fe       34         System.Int32  0 instance      346 x
    790fe920  40010ff       38         System.Int32  0 instance       22 y
    790fe920  4001100       3c         System.Int32  0 instance      266 width

SOS Commands

Table 16-7 gives an overview of some of the SOS commands. For a complete listing, use the !help command.

Table 16-7. SOS commands

Command

Description

!ClrStack option

Displays the call stack of the current thread.

Here are some of the options:

  • The -l option lists the local variables.

  • The -p option lists the function parameters.

  • The -a option combines both the -l and -p options.

!DumpHeap option startaddress endaddress

Displays objects that are on the managed heap and then displays statistics about the type of objects on the managed heap.

Here are some of the options:

  • The –stat option displays the type of objects alone.

  • The –min option excludes objects beneath the specified memory address from the list.

  • The –max option excludes objects located above the specified memory address from the list.

  • The –mt option lists objects with the specified method table.

  • The startaddress parameter is the starting address; for example:

    • !DumpHeap 7b471e40.

  • The endaddress parameter is the end address for the command:

    • !DumpHeap 7b471e40 7b471e88.

!DumpIL mdaddress

Displays the Microsoft Intermediate Language (MSIL) of a method, based on the method descriptor.

!DumpMT mtaddress

Displays information about the method table. The –md option lists the methods of the method table.

!DumpObj objaddress

Displays information on the specific object.

!DumpStackObjects option

Lists objects that are referenced from the current stack.

!EEHeap options

Displays information on generations 0, 1, 2, and the large object heap. (The large object heap is explained in the section "Generations," later in this chapter.) The gc option limits the display to information pertaining to the generations and the large object heap.

!EEVersion

Displays information about the runtime environment, such as the version number.

!FinalizeQueue option

Lists objects currently on the finalization queue.

!GCroot option objaddress

Shows how references are rooted, which is the path from the object to the root. In C#, root objects include static and local references. These objects represent the base of a branch in the object graph. The –nostacks option excludes references held on the stack.

!IP2MD jitaddress

Displays the method descriptor of a jitted method.

!Name2EE programtarget

If the target is a type, provides information on that type. If the target is a method name, displays information on the method descriptor.

!Syncblk

Lists the entries of the sync block table.

!Threads

Lists the managed threads.

!Token2EE token

For this command, the token must reference the typedef or methoddef table. If it is a typedef token, the command displays information on the referenced type. If it is a methoddef token, the command displays information on the referenced methods.

!u

This command displays the disassembly for a jitted method.

!Help command

Displays help for SOS commands. Without the command option, the command provides an overview of all the commands.

SOS Example, Part II

Now that a few more commands have been introduced, an additional example is helpful. This example lists the source, MSIL, and assembly code of the btnTransaction_Click button handler, which is informative.

  1. Start the Store application in the sos subfolder and then attach WinDbg to the application. Load SOS.

  2. Dump information about the btnTransaction_Click method with the !name2ee command. Notice that the method has not been jitted yet, which means that the method has not been invoked. A method is jitted the first time it is invoked. Here is the code:

    0:004> !name2ee store.exe Store.Form1.btnTransaction_Click
    Module: 00d40c14 (Store.exe)
    Token: 0x06000004
    MethodDesc: 00d43968
    Name: Store.Form1.btnTransaction_Click(System.Object, System.EventArgs)
    Not JITTED yet. Use !bpmd -md 00d43968 to break on run.
    0:004> !u 00d43968
    Not jitted yet
  3. Restart the Store application from break mode using the g(o) command. Click Add Transactions. In WinDbg, press Ctrl+Break to interrupt the application. Dump information on the Store.Form1.btnTransaction_Click method again. This time, the method is shown as jitted, and the virtual address of the cached native binary is displayed:

    0:004> !name2ee store.exe Store.Form1.btnTransaction_Click
    Module: 00d40c14 (Store.exe)
    Token: 0x06000004
    MethodDesc: 00d43968
    Name: Store.Form1.btnTransaction_Click(System.Object, System.EventArgs)
    JITTED Code Address: 00de07c0
  4. The !u command displays the assembly code of a jitted method. Execute the !u command on the btnTransaction_Click method using the address shown for the method descriptor (Method Desc) by the !name2ee command:

    0:004> !u 00d43968
    Normal JIT generated code
    Store.Form1.btnTransaction_Click(System.Object, System.EventArgs)
    Begin 00de07c0, size 3e9
    00de07c0 55               push    ebp
    00de07c1 8bec             mov     ebp,esp
    00de07c3 57               push    edi
    00de07c4 56               push    esi
    00de07c5 53               push    ebx
    00de07c6 83ec50           sub     esp,0x50
    00de07c9 33c0             xor     eax,eax
    00de07cb 8945d0           mov     [ebp-0x30],eax
    00de07ce 8945c4           mov     [ebp-0x3c],eax
    00de07d1 33c0             xor     eax,eax
    00de07d3 8945e8           mov     [ebp-0x18],eax
    00de07d6 894dc0           mov     [ebp-0x40],ecx
    00de07d9 8955dc           mov     [ebp-0x24],edx
    00de07dc 833dc80dd40000   cmp     dword ptr [00d40dc8],0x0
  5. The next challenge is to list the MSIL code for the btnTransaction_Click method. The dumpil command shows the MSIL code of the method. Method descriptor is the only parameter, which also is provided by the !name2ee command:

    0:004> !dumpil 00d43968
    ilAddr = 0040247c
    IL_0000: nop
    .try
    {
      IL_0001: nop
      IL_0002: ldarg.0
      IL_0003: ldfld Store.Form1::txtNumber
      IL_0008: callvirt System.Windows.Forms.Control::get_Text
      IL_000d: call System.Int32::Parse
      IL_0012: stloc.0
      IL_0013: nop
      IL_0014: leave.s IL_001d
    } // end .try
    .catch
    {
      IL_0016: pop
      IL_0017: nop
      IL_0018: ldc.i4.1
      IL_0019: stloc.0
      IL_001a: nop
      IL_001b: leave.s IL_001d
    } // end .catch
  6. The final task is to display the source code. Set the source code path in WinDbg. From the File menu, choose the Source File Path command and then enter the source code path. This should be the path for the store.exe source code in the sos subfolder. Next, enter the lsf command to set form1.cs as the current source code file. List the source with the ls command. For this example, 40 lines are displayed, beginning with line 10. You now have displayed the source, intermediate language, and assembly code for a function:

    0:004> lsf form1.cs
    0:004> ls 10, 40
        22:
        23:         private void btnTransaction_Click(object sender, EventArgs e)
        24:         {
        25:             int numofTransactions;
        26:             try
        27:             {
        28:                 numofTransactions= int.Parse(txtNumber.Text);
        29:             }
        30:             catch
        31:             {
        32:                 numofTransactions = 1;
        33:             }
        34:             for (int count = 0; count < numofTransactions; ++count)
        35:             {
        36:                 int itemTotal=0;
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.196.146