zoukankan      html  css  js  c++  java
  • windbg 边学边记attach 进程和open dump的两个方式查看线程的占用cpu资源

    首先我是attach到进程的方式,附加到进程把. vs里边有个远程调试就是通过连接到远程机附加到进程操作的.在 有公网IP情况下挺好用,但涉及到nat穿越之类的,因为用户的不方便设置,这种调试方式也有局限性.

    6、 lmf

    列出当前进程中加载的所有dll文件和对应的路径

    奇怪没找到我程序里边加载的dll  乖乖滴.难道attach 进程把dll关了吗? 用空用dump 试试.

    11!runaway 可以显示每一个线程的cpu消耗 

    这个命令挺好,直接找到哪个线程占得时间久 ,如果一直占着,那这个线程里边一定是有死循环,或者不停的操作某个东西

    线程6号 占用时间1分钟31秒

    我看有人通过抓dump  才查看,那种应该是最准的吧, windbg  附加到进程里之后,程序卡掉了,占资源的dll 也停下来了.    总结下文的操作,发现加载到进程跟dump 的方式竟然一样,不一样的估计是加载到进程里增大资源影响程序的运行效果的公正性吧.但差距不大吧.

    通过dump多抓几次,每次都一样占时间的那个线程就是问题所在的线程.

    12、 ~     命令是用来切换目标线程

    0:018> ~ 可以显示线程的信息
    0:018> ~0s   把当前的线程切换到0号线程,也就是主线程,切换后提示符会变为0:000.

    13 、~* 命令列出当前进程中的所有线程的详细信息

    14、~*kb    命令列出所有线程的堆栈

    15、 k     命令用来显示当前线程的堆栈,如下

    转到六号线程 

     

    没有多少信息 这是0:007> !clrstack转到这个线程  没有列出线程的占用资源情况

    应该继续下边的命令

    !clrstack 
    15、 k     命令用来显示当前线程的堆栈,如下

    0:018> k
    跟d命令一样,k后面也可以跟很多后缀,比如kb kp,kn,kv,kl等,这些后缀控制了显示的格式和信息。
    栈指令k[b|p|P|v]
    这四条指令显示的内容类似,但是每个指令都有特色;

    KB显示三个参数;

    Kp显示所有的参数,但需要Full Symbols或Private PDBSymbols支持。KP与Kp相似,只是KP将参数换行显示了;

    Kv用于显示FPO和调用约定;

    KD,用于显示Stack的Dump,在跟踪栈时比较有用。
    这些指令区分大小。

    16 、u   命令把指定地址上的代码翻译成汇编输出

    0:018> u 7739d023 
    USER32!NtUserWaitMessage:
    7739d023 b84a120000 mov eax,0x124a
    7739d028 ba0003fe7f mov edx,0x7ffe0300
    7739d02d ff12 call dword ptr [edx]
    7739d02f c3 ret
    如果符号文件加载正确,可以用uf命令直接反汇编整个函数,比如uf USER32! NtUserWaitMessage

     

    通过抓dump的方式

    0:000> !runaway
    User Mode Time
    Thread Time
    7:1dec 0 days 0:00:37.578
    0:1278 0 days 0:00:00.078
    8:1274 0 days 0:00:00.015
    6:2248 0 days 0:00:00.015
    17:1378 0 days 0:00:00.000
    16:1ff0 0 days 0:00:00.000
    15:3a4 0 days 0:00:00.000
    14:1e88 0 days 0:00:00.000
    13:1dc4 0 days 0:00:00.000
    12:ec4 0 days 0:00:00.000
    11:1b98 0 days 0:00:00.000
    10:2074 0 days 0:00:00.000
    9:9f4 0 days 0:00:00.000
    5:154c 0 days 0:00:00.000
    4:1bd4 0 days 0:00:00.000
    3:8ac 0 days 0:00:00.000
    2:48c 0 days 0:00:00.000
    1:75c 0 days 0:00:00.000

    0:000> ~7s
    ntdll!NtWaitForSingleObject+0xa:
    00007ffd`284f386a c3 ret

     调整到7号线程上下文 

    0:007> !clrstack
    No export clrstack found

    看来我是.net 环境没load 正确的sos 吧

    想通过加载sos.dll 出现下边错误 . 

    0:007> .load C:/WINDOWS/Microsoft.NET/Framework/v4.0.30319/sos.dll
    The call to LoadLibrary(C:/WINDOWS/Microsoft.NET/Framework/v4.0.30319/sos.dll) failed, Win32 error 0n193
    "%1 不是有效的 Win32 应用程序。"
    Please check your debugger configuration and/or network access.

      问题一:WinDBG分X86和X64两个版本
    
      如果你用的是32位的WinDBG,那直接打开就行;你如果用的是64位的版本,那么如果调试64位代码也直接打开,如果调试x86的代码,要使用Wow64下的WinDBG.exe。
    
      问题二:确定SOS和CLR的位置和版本
    
      如果安装了Visual Studio的机器,可以打开VS的命令行,输入where sos.dll命令,可以找到sos.dll的全路径(需要说明的是,找到的不一定是全部的文件)。它的一般位置在C:WindowsMicrosoft.NETFramework?version?SOS.dll。其中Framework?包括Framework和Framework64两个版本;version?包括v2.0.50727,v3.0,v3.5和v4.0.30319等版本。文件确切路径的选择依据要调试程序的版本而定,一般为C:WindowsMicrosoft.NETFrameworkv4.0.30319SOS.dll,CLR为同一目录下的CLR.dll文件。
    
      问题三:加载SOS和CLR
    
      运气好的话,使用命令.load C:WindowsMicrosoft.NETFrameworkv4.0.30319SOS.dll可以加载成功。如果失败,特别是出现The call to LoadLibrary(C:WindowsMicrosoft.NETFrameworkv4.0.30319sos.dll) failed, Win32 error 0n193这样的错误,请确认加载sos.dll的版本是否正确。
    
      此外,加载不出错,并不见得可以直接使用。可以尝试命令.loadby sos clr。如果命令成功,那么测试环境好了。如果出现了“Unable to find module 'clr'”这样的错误。请键入g让调试程序运行一会儿,停下来的时候再尝试命令.loadby sos clr,这时一般都会成功。

    C:Program Files (x86)Microsoft Visual Studio 14.0VC>where sos.dll
    C:WindowsMicrosoft.NETFramework64v4.0.30319SOS.dll

    0:007> .load C:WindowsMicrosoft.NETFramework64v4.0.30319SOS.dll

    什么提示也没有,看来是正确了吗

    继续上边的

    0:007> ~7s
    ntdll!NtWaitForSingleObject+0xa:
    00007ffd`284f386a c3 ret

    终于成功:

    0:007> !clrstack
    OS Thread Id: 0x1dec (7)
            Child SP               IP Call Site
    000000001d05f1c8 00007ffd284f386a [InlinedCallFrame: 000000001d05f1c8] Cognex.DataMan.LegacyUtils.PInvoke.WaitForSingleObject(IntPtr, UInt32)
    000000001d05f1c8 00007ffca7bb59dc [InlinedCallFrame: 000000001d05f1c8] Cognex.DataMan.LegacyUtils.PInvoke.WaitForSingleObject(IntPtr, UInt32)
    000000001d05f1a0 00007ffca7bb59dc DomainBoundILStubClass.IL_STUB_PInvoke(IntPtr, UInt32)
    000000001d05f250 00007ffca7bb5909 Cognex.DataMan.LegacyUtils.PInvoke.WaitOne(IntPtr, UInt32)
    000000001d05f280 00007ffca7bb580c Cognex.DataMan.LegacyUtils.BlockingCollection`1[[System.__Canon, mscorlib]].DequeueWithCancellation(Cognex.DataMan.LegacyUtils.CancellationToken)
    000000001d05f2d0 00007ffca7bb5544 Cognex.DataMan.CogNamer.CogNamerListener.CogNamerDispatcherThreadFunc(System.Object)
    000000001d05f320 00007ffcfcacaffe System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
    000000001d05f3f0 00007ffcfcacae97 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
    000000001d05f420 00007ffcfcacae52 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
    000000001d05f470 00007ffcfca1c142 System.Threading.ThreadHelper.ThreadStart()
    000000001d05f6c8 00007ffd07213cd3 [GCFrame: 000000001d05f6c8] 
    000000001d05fa18 00007ffd07213cd3 [DebuggerU2MCatchHandlerFrame: 000000001d05fa18] 

    接触了几天了,今天终于是操作了一个流程下来,能看到这个线程的托管代码了

    000000001d05f1c8 00007ffd284f386a [InlinedCallFrame: 000000001d05f1c8] Cognex.DataMan.LegacyUtils.PInvoke.WaitForSingleObject(IntPtr, UInt32)
    000000001d05f1c8 00007ffca7bb59dc [InlinedCallFrame: 000000001d05f1c8] Cognex.DataMan.LegacyUtils.PInvoke.WaitForSingleObject(IntPtr, UInt32)
    000000001d05f1a0 00007ffca7bb59dc DomainBoundILStubClass.IL_STUB_PInvoke(IntPtr, UInt32)

    也列出了其中占资源大的托管代码

    参考

    http://www.360doc.com/content/12/0524/13/8053702_213354653.shtml
  • 相关阅读:
    C++设计模式-Bridge桥接模式
    解决VS2010打开Web页面时经常由于内存较低而导致VS2010自动关闭的问题
    Js继承小结
    MAC上的包管理利器
    Objective-C的hook方案(一): Method Swizzling
    OleContainer操作Excel以二进制方式读写数据库
    复制文件时,如何显示进度条(使用TFileStream一点一点读,或者使用BlockRead,并插入application.ProcessMessages)
    ADO异步查询显示进度条
    D2010 RTTI + Attribute 简单实现ORM
    Delphi默认窗体随想
  • 原文地址:https://www.cnblogs.com/zuochanzi/p/6912808.html
Copyright © 2011-2022 走看看