【问题标题】:Write windbg command output to file, but not console将 windbg 命令输出写入文件,但不写入控制台
【发布时间】:2017-09-12 17:32:21
【问题描述】:

在windbg中,我正在寻找一种机制来获取命令的输出(特别是断点内的命令)并将其附加到文件中,并且写入控制台。

目前我使用.logappend C:\path\to\log 设置进程,然后启用几个断点:

bp WIN32U!{function} ".echo '===WIN32K-START==='; k; .echo '===WIN32K-END==='; g"

这很好用,除了写入控制台的输出量会导致严重的性能问题。我希望有一种方法可以在我的日志文件中获得相同的输出,而无需写入 windbg 控制台的开销。

【问题讨论】:

  • 您的问题到底是什么?一个明确的问题陈述有很长的路要走。它也可以帮助未来的访客。
  • @IInspectable 我的问题是是否有办法将命令输出写入文件,而无需将其写入 windbg 控制台。
  • @ThomasWeller 我继续使用最新的 WinDbgX 进行测试,它的性能似乎与现有的 WinDbg 版本大致相同。
  • @ThomasWeller 关闭输出窗口似乎不是一件事,单击“X”会导致它暂时消失,但它会马上回来。
  • @AlexGaynor:听到新版本没有提供承诺的性能优势,我很难过。在第 9 频道上,他们讨论了旧版本同步输出的必要性,该输出在新版本中已被删除或至少有所改进。 :-(

标签: windows windbg


【解决方案1】:

你想要.outmask 元命令:https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/-outmask--control-output-mask-

.outmask 允许您控制将哪些消息类型发送到输出窗口和日志文件。 /l 开关可以让您只更改到达输出窗口的类型,而不影响哪些类型将到达日志文件。

例如,此命令将关闭所有输出到输出窗口,同时仍将正常消息发送到日志文件:

.outmask- /l 0xffff

虽然.outmask- /l 1 可能是您所需要的,它只会关闭正常的消息输出,但错误和警告仍会显示在输出窗口中。完成后使用.outmask /d 将输出设置重置为默认值。

结合.printf 输出不同消息类型的能力,您可以做到这一点,这样您仍然对正在发生的事情有所了解。使用.outmask- /l 1 关闭正常的消息输出到窗口。现在您可以在某个断点命令中使用.printf /oe "message" 来编写错误消息,该错误消息仍将发送到输出窗口,以便您了解过程中某些点发生的情况。

【讨论】:

    【解决方案2】:

    您可以修补 dbgeng!g_OutputControl 全局以禁用写入控制台并仅写入日志文件

    但我不知道你是否会有性能提升

    寻找一个txt文件

    C:\>dir /b *.txt
    File Not Found
    

    打开调试会话

    C:\>cdb calc
    
    
    Microsoft (R) Windows Debugger Version 10.0.15063.400 X86
    
    ntdll!LdrpDoDebuggerBreak+0x2c:
    774005a6 cc              int     3
    

    在打开的调试会话中
    生成一个父调试器来调试运行你的被调试对象的windbg

    0:000> .dbgdbg
    Debugger spawned, connect with
        "-remote npipe:icfenable,pipe=cdb_pipe,server=xxxx"
    

    在生成的父补丁中全局和分离

    ed dbgeng!g_OutputControl 0
    .detach
    q
    

    在调试会话中打开一个日志文件

    0:000> .logappend c:\foo.txt
    Opened log file 'c:\foo.txt'
    

    设置条件断点并启动会话

    0:000> bp ntdll!RtlEnterCriticalSection "kb;gc"
    0:000> bl
     0 e 773a7790     0001 (0001)  0:**** ntdll!RtlEnterCriticalSection "kb;gc"
    0:000> g
    

    这里没有控制台输出

    按 ctrl+c 停止会话并退出会话

    eax=7ffde000 ebx=00000000 ecx=00000000 edx=773ff1d3 esi=00000000 edi=00000000
    eip=77394108 esp=016ef8a8 ebp=016ef8d4 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    ntdll!DbgBreakPoint:
    77394108 cc              int     3
    0:001> q
    quit:
    

    检查日志文件并确认是否有大量数据写入其中
    RtlEnterCriticalSection Api 是一个很火的 Api

    C:\>dir /b *.txt
    foo.txt
    
    C:\>ls -l foo.txt
    -rw-rw-rw-  1  0 **1754920** 2017-09-15 00:27 foo.txt
    

    C:>head foo.txt

    Opened log file 'c:\foo.txt'
    0:000> bp ntdll!RtlEnterCriticalSection "kb;gc"
    0:000> bl
     0 e 773a7790     0001 (0001)  0:**** ntdll!RtlEnterCriticalSection "kb;gc"
    0:000> g
    ChildEBP RetAddr  Args to Child
    000cf114 77425f4b 000d0138 7724d80b 00000000 ntdll!RtlEnterCriticalSection
    000cf158 773ea40a 000d0000 50180162 00000044 ntdll!RtlDebugAllocateHeap+0x9d
    000cf23c 773b5ae0 00000044 00000000 00000000 ntdll!RtlpAllocateHeap+0xc4
    000cf2c0 77384726 000d0000 40180060 00000044 ntdll!RtlAllocateHeap+0x23a
    

    有超过 22k 行写入此文件

    C:\>wc -l foo.txt
    22543 foo.txt
    

    C:>tail foo.txt

    000cf838 773c37be 00462d6c 7ffdb000 00000000 ntdll!__RtlUserThreadStart+0x70
    000cf850 00000000 00462d6c 7ffdb000 00000000 ntdll!_RtlUserThreadStart+0x1b
    (c80.8ec): Break instruction exception - code 80000003 (first chance)
    eax=7ffde000 ebx=00000000 ecx=00000000 edx=773ff1d3 esi=00000000 edi=00000000
    eip=77394108 esp=016ef8a8 ebp=016ef8d4 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    ntdll!DbgBreakPoint:
    77394108 cc              int     3
    0:001> q
    quit:
    
    C:\>
    

    【讨论】:

      猜你喜欢
      • 2012-12-18
      • 2017-08-27
      • 1970-01-01
      • 1970-01-01
      • 2017-09-30
      • 2013-09-09
      • 2012-06-11
      相关资源
      最近更新 更多