代码之家  ›  专栏  ›  技术社区  ›  Pure.Krome

windbg帮助->如何读取此调用堆栈中的代码?

  •  8
  • Pure.Krome  · 技术社区  · 16 年前

    我有一个Windows服务的转储文件。例外是我的代码不能移动文件(出于某种原因)。现在,在我的代码中,有很多地方我可以在文件系统周围移动文件。所以,使用windbg,我尝试查看异常发生的代码。

    这是我的!堆栈转储。

    0:016> !clrstack -p
    OS Thread Id: 0xdf8 (16)
    Child-SP         RetAddr          Call Site
    0000000019edea70 0000064278a15e4f System.IO.__Error.WinIOError(Int32, System.String)
    PARAMETERS:
        errorCode = <no data>
        maybeFullPath = <no data>
    
    0000000019edead0 0000064280181ce5 System.IO.File.Move(System.String, System.String)
    PARAMETERS:
        sourceFileName = <no data>
        destFileName = <no data>
    
    0000000019edeb50 0000064280196532 MyClass.Foo.DoSomeStuffInHere(System.String)
    PARAMETERS:
        this = 0x0000000000c30aa8
        filePathAndName = 0x0000000000d1aad0
    

    现在,这有很大帮助…

    0:016> !do 0x0000000000d1aad0
    Name: System.String
    MethodTable: 00000642784365e8
    EEClass: 000006427803e4f0
    Size: 88(0x58) bytes
    (C:\WINDOWS\assembly\GAC_64\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
    String: C:\BlahBlahFolder\FooFolder\4469.jpg
    Fields:
    -snipped-
    

    所以我找到了移动失败的文件。克威尔但我只想看看这个方法myclass.foo.dosomestuffinhere(system.string)中调用file.move(..)的代码。那个方法有很多文件。移动..所以我可以放置try/catch/debug/trace信息。但我希望通过使用windbg来帮助找到这个问题,从而提高效率。

    有什么想法吗?

    2 回复  |  直到 15 年前
        1
  •  3
  •   TheSoftwareJedi jac    16 年前

    除非应用程序以调试模式部署,否则无法获得准确的代码行。如果是这样的话,我相信它会显示在!调用堆栈。

        2
  •  3
  •   AaronBa    15 年前

    这是一个困难的问题,可能需要走出只受管理调试的舒适区。

    您要做的是为函数映射IL myclass.foo.dosomestuffhinhere.我的课是.foo.dosomestuffinhere 去分解那个功能。下面的示例是x86,但是x64可以遵循相同的步骤。

    这在下面的链接中被引用。 Debugging Unexpected Process Termination

    白皮书中的示例文本: 在托管堆栈中, debugging.unexpected.btnta_单击 … 查看debugging.unexpected.btnsta_ck事件中的代码。

    private void btnSTA_Click(object sender, System.EventArgs e)
    {
       DebuggingCOMLib.STAClass staobj =  new DebuggingCOMLib.STAClass();
       staobj.RaiseError(1,5);
       Label1.Text += "STA Call Completed sucessfully";
    }
    

    如果源代码不可用,则可以通过向调用堆栈帧提供指令指针来检查程序集。 !U命令 . 可以从中检索指令指针!clrstack:输出。

    0096f970  03a00e06 [DEFAULT] [hasThis] Void
    Debugging.Unexpected.btnSTA_Click(Object,Class System.EventArgs)
    

    要分解此函数,请键入 !U03A00 E06 .

        0:010> !u 03a00e06 
        Normal JIT generated code
        [DEFAULT] [hasThis] Void Debugging.Unexpected.btnSTA_Click(Object,Class 
        System.EventArgs)
        Begin 03a00de0, size 54
       <snip>
        03a00e18 8b15a89c1702     mov     edx,[02179ca8] ("STA Call Completed 
        sucessfully")
        03a00e1e e83d3590ff       call    03304360 (System.String.Concat)
        <snip>
        03a00e2f 5e               pop     esi
        03a00e30 5f               pop     edi
        03a00e31 c20400           ret     0x4
    

    好吧,现在怎么样?
    扫描你自己!类线的U输出

    call    03304360 (System.IO.File.Move)
    

    还有,你可以跑!IP2MD 03A00 E06 获取methodDesc,然后运行 !垃圾堆 检查IL代码是否更容易。

    您可以计算 system.io.file.move(系统.io.file.move) !U输出 然后在IL中倒数相同的数字。然后,您可以使用.NET Reflector分解该方法,并将C_映射到IL,并比较结果。

    很多步骤,但它会让你得到相同的结果:—)

    谢谢, 亚伦