IIS日志文件分析器ReadLogs探秘(五) -电脑资料

电脑资料 时间:2019-01-01 我要投稿
【meiwen.anslib.com - 电脑资料】

    意外监控器所使用的CDB命令

    (作者:青苹果工作室编译

    意外监控器所使用的一些命令在调试的时候是有用的,

IIS日志文件分析器ReadLogs探秘(五)

。下面是这些命令及其相关的输出。

    Kv 命令

    意外监控器运行的第一个命令是Kv 。它显示的是在挑错时刻激活的流的函数调用返回堆栈。读这个堆栈是从底部向顶部:最顶部的函数是调用的最后一个函数,而最底部的函数则是这个流调用的第一个函数。

    输出样本(x86 平台):

    ChildEBP RetAddr Args to Child

    00f8fdf8 53d0f7f3 003070ac 00307078 00306d48 0x1000113c [Stdcall: 0]

    00f8fe5c 53d0ad45 00306ee4 00f8ff0c 00f8ff4c w3svc!AddFilterResponseHeaders+0x26

    00f8ff20 53d01ce6 00f8ff4c 00f8ff68 003154b0 w3svc!HTTP_REQUEST__DoDirList+0x2f7

    00f8ff50 53d01f56 00f8ff68 00315478 00315460 w3svc!&127;ole32_NULL_THUNK_DATA+0x96e

    00f8ff6c 53d04adb 00000166 00000000 00000001 w3svc!&127;ole32_NULL_THUNK_DATA+0xbde

    00f8ff88 539895d0 00315460 00000166 00000000 w3svc!HTTP_REQ_BASE__`vftable+0x1fd3

    00f8ffb8 77f04f2c abcdef01 776a2254 00000028 infocomm!AtqPoolThread+0x1c8

    00f8ffec 00000000 53989408 abcdef01 00000000 kernel32!BaseThreadStart+0x51

    输出样本(alpha 平台):

    Callee-SP Return-RA Call Site

    0815ffc0 77e6f5b8 : ntdll!DbgBreakPoint+0x4

    0815ffc0 77e6cc48 : KERNEL32!DebugBreak+0x8

    0815ffd0 00000000 : KERNEL32!BaseThreadStart+0x60

    函数的调用返回堆栈列出了在给定流中激活的所有函数。意思是函数1调用了函数2,函数2最终又调用了函数3,等等。当最后一个被调用的函数结束了其工作时,它就“展开”,或者说是返回了调用它的那个函数;而那个函数结束后也返回调用它的函数,依次类推。调用返回堆栈列出了什么调用了什么,以及函数正确运行后代码如何返回。因为这个堆栈是故障堆栈,你就可以知道在堆栈顶部列出的函数所发生的访问冲突。但是这不一定说明这个函数引发了实际问题。问题也许是由于另一个函数向堆栈传递了错误的指针,或者甚至于是由一个不同的流引起的。在堆和堆栈冲突中可以看到有关详细内容。

    请注意当确认文件没有装载符号,堆栈顶部的命令并不列出调用命令。当堆栈装载到ReadLogs时,通过使用装载的模块的列表,它试图将这个函数调用分解到一个友好的名字中。首先它获得进行调用的内存地址(0x1000113c), 然后寻找拥有这个内存地址的装载的DLL。

    !inetdbg.mod

    IIS调试器增加到CDB的一个扩展是Inetdbg.dll文件。如果这个文件存在于Windows NT 目录中(或本地调试目录中),这样CDB就可以使用这个命令了。如果在这个扩展命令之前增加一个! 符号,那么CDB就寻找这个DLL,然后将这个命令传递到扩展。这时,你调用Inetdbg 扩展,并在mod命令中传递。这个命令在Inetinfo 内存空间中堆积了所有当前装载的模块的列表,并返回下面的信息(这是一个省略的列表):

    输出样本:

    Start End Entry Path

    01000000 01006000 01001122 C:WINNTSystem32inetsrvinetinfo.exe

    77f60000 77fbc000 00000000 C:WINNTSystem32tdll.dll

    78000000 78047000 7800546d C:WINNTsystem32MSVCRT.dll

    77f00000 77f5e000 77f01000 C:WINNTsystem32KERNEL32.dll

    77dc0000 77dfe000 77dc1000 C:WINNTsystem32ADVAPI32.dll

    77e70000 77ec1000 77e7a2a2 C:WINNTsystem32USER32.dll

    77ed0000 77efc000 00000000 C:WINNTsystem32GDI32.dll

    10000000 10024000 10001650 C:InetPubscriptsselfdestruct.dll

    如果想要确定是什么代码正在Inetinfo 内存空间运行,这些信息是有用的。在前面的 kv 命令中,你的函数是未分解的。要分解它,你要使用内存地址-—0x1000113c,看它是否在Selfdestruct.dll的起始地址和结束地址范围内。

    !inetdbg.ver

    Inetdbg 可以使用的另一个扩展是ver 命令。这个命令列出了从装载的DLL中提取出来的所有版本信息。大多数DLL的版本信息都是在实际文件的头部。这个扩展就试图从这里获取这些信息:

    输出样本:

    Module @ 0x01000000 = inetinfo.exe

    dwFileFlags = 0x00000000 (FREE)

    CompanyName = Microsoft Corporation

    FileDescription = Internet Information Services Application v 1.0

    FileVersion = 4.00

    InternalName = INETINFO.EXE

    LegalCopyright = Copyright (C) Microsoft Corp. 1981-1996

    riginalFilename = INETINFO.EXE

    ProductName = Microsoft(R) Windows NT(TM)

    Operating System ProductVersion = 4.00

    Module @ 0x77f60000 = ntdll.dll

    dwFileFlags = 0x00000000 (FREE)

    CompanyName = Microsoft Corporation

    FileDescription = NT Layer DLL

    FileVersion = 4.00

    InternalName = ntdll.dll

    LegalCopyright = Copyright (C) Microsoft Corp. 1981-1996

    riginalFilename = ntdll.dll

    ProductName = Microsoft(R) Windows NT(TM)

    Operating System ProductVersion = 4.00

    在这个例子中,没有列出存在问题的DLL(Selfdestruct.dll),

电脑资料

IIS日志文件分析器ReadLogs探秘(五)》(http://meiwen.anslib.com)。Inetdbg.mod 不能显示那些不能恢复版本信息的DLL的任何信息。ReadLogs 将 ver 命令中每个条目的文件名与这里的条目相比较,然后将可以得到的版本信息增加到列表中所有的DLL上。如果没有可用的版本信息,ReadLogs 就仅仅增加这样一句话“没有这个DLL的可用的版本信息”。ReadLogs 就是用这个命令的输出来显示版本信息。如果想要确定你是否在运行一个给定DLL的适当版本,这个信息是非常有用的。

    注意:在某些运行Windows NT Service Pace (SP) 4的机器上, ver 命令运行是完全失败的。如果希望获取适当的版本信息,可以将这个命令运行两次。这时ReadLogs 就会特意寻找一个没有包含任何错误的输出的版本,并用这个设置来显示版本信息。如果这两次运行都失败了,ReadLogs 就不能显示版本信息了。

    ~*kb

    ~*kb命令指示调试器为内存空间上的每个流保存一套堆栈的副本(同kv)。(~ 命令说"选择一个流"; * 命令说 "所有的流",然后你可以加上你想要对所有流运行的任何命令,这里是 kb)。你可以用这个命令来看看在发生冲突的时候发生了一些别的什么。如果你在排除100%CPU利用率和死锁的故障,也可以使用这个信息。每个堆栈都同kv 堆栈的分析方法相同。

    运行调试器,你可以用这个信息排除100%CPU利用率的故障,在你捕捉到流计数器的地方还可以运行一个性能监控器日志。对于一个100%CPU利用率的问题,你可以手动给调试器挑错,然后停止PerfMon 日志。通过分析PerfMon 日志,你就获取了正在使用CPU的流的号码。你还可以在~*kb 命令所列出的有同样号码的流上使用ReadLogs (或手动检查调试日志文件)。这样就告诉你流在做什么并指出“罪犯”是谁。

    注意:要捕捉流的输出,你必须使用PerfMon 的日志功能,要等到100%利用率发生才能起动日志。仅仅在图表中看看流会得到错误的流号码。

    u eip-50 eip+20 (只在x86平台)

    这个u命令指示调试器显示存在于提供的地址范围内的汇编代码。这时你是在请求从扩展指令指针(EIP)寄存器所指向的50个字节之前到EIP指向的20个字节之后的那些代码。EIP寄存器通常指向要执行的代码的下一行。你可以看到在冲突发生时代码在做些什么。

    输出样本(缩略):

    ntdll!RtlpWaitForCriticalSection+0x45:

    77f6cc16 0000       add   [eax],al

    77f6cc18 008b0d805afa   add   [ebx+0xfa5a800d],cl

    77f6cc1e 7739       ja ntdll!RtlpWaitForCriticalSection+0x88 (77f6cc59)

    77f6cc20 48       dec   eax

    77f6cc21 2475       and   al,0x75

    77f6cc23 2333       and   esi,[ebx]

    77f6cc25 c0894604894608 ror   byte ptr [ecx+0x46890446],0x8

    77f6cc2c 89460c     mov   [esi+0xc],eax

    77f6cc2f 894610     mov   [esi+0x10],eax

    !locks

    这个!locks 命令显示的信息是关于当前运行代码的哪个部分被标记为关键部分(CS)。有关CS的详细讨论可以看理解锁那部分。

    输出样本:

    CritSec w3svc!MDIDMappingTable+100 at 68c2b1b0

    LockCount     0

    RecursionCount   1

    OwningThread   156

    EntryCount     0

    ContentionCount  0

    *** Locked

    !inetdbg.atq –g

    这个atq 命令显示的信息与IIS非同步流排队有关。流排队是IIS特有的功能。当一个新的请求进入IIS时,它就需要处理一个流。由于创建一个流从时间和CPU使用的方面来说是比较昂贵的,因此IIS保持着一套随时处理引入的请求的工作流;IIS则管

最新文章