Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scripting Windbg脚本-自动解析堆栈的每个帧_Scripting_Windbg - Fatal编程技术网

Scripting Windbg脚本-自动解析堆栈的每个帧

Scripting Windbg脚本-自动解析堆栈的每个帧,scripting,windbg,Scripting,Windbg,喂 我最近查看了一些堆栈,我手动找到了一个特定的东西,我想得到它的地址,这样我就可以用?深入研究它 例如: 00 00000005`9c88a558 00007ffa`bc2713ed ntdll!NtWaitForMultipleObjects+0xa 01 00000005`9c88a560 00007ffa`be477d51 KERNELBASE!WaitForMultipleObjectsEx+0xed 02 00000005`9c88a840 00007ffa`be477773 ker

我最近查看了一些堆栈,我手动找到了一个特定的东西,我想得到它的地址,这样我就可以用
深入研究它

例如:

00 00000005`9c88a558 00007ffa`bc2713ed ntdll!NtWaitForMultipleObjects+0xa
01 00000005`9c88a560 00007ffa`be477d51 KERNELBASE!WaitForMultipleObjectsEx+0xed
02 00000005`9c88a840 00007ffa`be477773 kernel32!WerpLaunchAeDebug+0x23a1
03 00000005`9c88adb0 00007ffa`bc351c1f kernel32!WerpLaunchAeDebug+0x1dc3
04 00000005`9c88ade0 00007ffa`bedaf1b3 KERNELBASE!UnhandledExceptionFilter+0x23f
05 00000005`9c88aed0 00007ffa`bed91e26 ntdll!memset+0xaaf3
06 00000005`9c88af10 00007ffa`beda349d ntdll!_C_specific_handler+0x96
07 00000005`9c88af80 00007ffa`bed648d7 ntdll!_chkstk+0x9d
08 00000005`9c88afb0 00007ffa`beda262a ntdll!RtlRaiseException+0xf67
09 00000005`9c88b680 00007ffa`aafc1b52 ntdll!KiUserExceptionDispatcher+0x3a
0a 00000005`9c88bd80 00007ffa`ab14e820 function1(class foo1 * bar1 = 0x00000000`0eee4e10)+0xd2 [c:\path\source1.cpp @ 783]
0b 00000005`9c88bdc0 00007ffa`ab11b854 function2(class foo2 * bar2 = 0x00000000`0f034010)+0x540 [c:\path\source2.cpp @ 23044]
0c 00000005`9c88d420 00007ffa`ab06151c function3(class foo3 * bar3 = 0x00000005`9c88dd50)+0x584 [c:\path\source3.cpp @ 5671]
0d 00000005`9c88dcf0 00007ffa`aae1ef08 function4(class foo3 * bar3 = 0x00000000`80001a55)+0x3bc [c:\path\source4.cpp @ 218]
0e 00000005`9c88e7c0 00007ffa`aae2956b function5(unsigned short fcode = 0x3032, class foo3 * bar3 = 0x00007ffa`ab08e8de)+0x1fb8 [path\source5.cpp @ 108]
0f 00000005`9c88fab0 00007ffa`bed254f4 kernel32!BaseThreadInitThunk+0x22
10 00000005`9c88fae0 00000000`00000000 ntdll!RtlUserThreadStart+0x34
我感兴趣的是提取
0x000000059c88dd50
0x0000000080001a55
0x00007ffaab08e8de
的3个地址,并将它们自动传递给一组
??((foo3*)0x000000059c88dd50)->WhatIAmInterestedIn
等命令,以便我可以快速扫描输出以查找感兴趣的结果

有没有一种方法可以编写这个解析脚本,这样我就可以在当前线程的堆栈中搜寻
bar3
的任何实例,获取该地址并在
n
x
命令中使用它,只需在命令窗口中回显它找到的任何内容,即使是内存访问错误,它也可以为我加快速度


我在想
!对于每一帧,我必须承认,我甚至不知道如何在Windbg内询问特定帧是否有
bar3
和地址,除非用我自己的眼睛

任何最新版本的调试器都具有内置功能,可以使用JavaScript针对目标编写脚本。商店中的WinDbg Preview也具有有限的Intellisense用户界面。你可以很容易地做这样的事情。以以下为例:

"use strict";

function* returnAllParameters(localName)
{
    var stack = host.currentThread.Stack;
    for (var frame of stack.Frames)
    {
        // Catch any exceptions that might occur due to inability to find PDB
        try
        {
            var locals = frame.Parameters;
            var local = locals[localName];
            if (local !== undefined)
            {
                yield local;
            }
        }
        catch(ex)
        {
        }
    }
}
这一结果的一个示例:

0:000> dx @$scriptContents.returnAllParameters("pExceptionRecord")
@$scriptContents.returnAllParameters("pExceptionRecord")                 : [object Generator]
    [0x0]            : 0x8be2f0ed00 [Type: _EXCEPTION_RECORD *]

如果您有源代码,则可以按照messmers脚本检查参数和局部变量
(没有源和私有pdb参数和局部变量将抛出未定义的错误)

如果您没有源代码,并且希望摸索字符串输出 你可以用这样的东西

function test(argstr)
{
    var backtrace = host.namespace.Debugger.Utility.Control.ExecuteCommand("kb")
    var collection = []
    var i = 0
    for (var frame of backtrace ) 
    {
        if( frame.toString().includes(argstr) ) {
        host.diagnostics.debugLog("found " + argstr + " at " + frame + "\n" )
        collection[i++] = frame.toString().split(" ")
        }
    }
    return collection
}
这是一个堆栈和文本解析的输出

0:003> dx @$scriptContents.test("Rtl")

found Rtl at 03 02cdfe8c 76df37be 76e2f1d3 00000000 00000000 ntdll!__RtlUserThreadStart+0x70
found Rtl at 04 02cdfea4 00000000 76e2f1d3 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b
@$scriptContents.test("Rtl")                 : 

    length           : 0x2
    [0x0]            : 03,
    [0x1]            : 04,
clicking the dml 0x0 
you get the first collection and so on as below

0:003> dx -r1 @$scriptContents.test("Rtl")[0]
found Rtl at 03 02cdfe8c 76df37be 76e2f1d3 00000000 00000000 ntdll!__RtlUserThreadStart+0x70
found Rtl at 04 02cdfea4 00000000 76e2f1d3 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b
@$scriptContents.test("Rtl")[0]                 : 03,02cdfe8c,76df37be,76e2f1d3,00000000,00000000,ntdll!__RtlUserThreadStart+0x70
    length           : 0x7
    [0x0]            : 03
    [0x1]            : 02cdfe8c
    [0x2]            : 76df37be
    [0x3]            : 76e2f1d3
    [0x4]            : 00000000
    [0x5]            : 00000000
    [0x6]            : ntdll!__RtlUserThreadStart+0x70
0:003> dx -r1 @$scriptContents.test("Rtl")[1]
found Rtl at 03 02cdfe8c 76df37be 76e2f1d3 00000000 00000000 ntdll!__RtlUserThreadStart+0x70
found Rtl at 04 02cdfea4 00000000 76e2f1d3 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b
@$scriptContents.test("Rtl")[1]                 : 04,02cdfea4,00000000,76e2f1d3,00000000,00000000,ntdll!_RtlUserThreadStart+0x1b
    length           : 0x7
    [0x0]            : 04
    [0x1]            : 02cdfea4
    [0x2]            : 00000000
    [0x3]            : 76e2f1d3
    [0x4]            : 00000000
    [0x5]            : 00000000
    [0x6]            : ntdll!_RtlUserThreadStart+0x1b
0:003> kb
 # ChildEBP RetAddr  Args to Child              
00 02cdfe10 76e2f20f 747e8f74 00000000 00000000 ntdll!DbgBreakPoint
01 02cdfe40 752ced6c 00000000 02cdfe8c 76df37eb ntdll!DbgUiRemoteBreakin+0x3c
02 02cdfe4c 76df37eb 00000000 747e8fb8 00000000 kernel32!BaseThreadInitThunk+0xe
03 02cdfe8c 76df37be 76e2f1d3 00000000 00000000 ntdll!__RtlUserThreadStart+0x70
04 02cdfea4 00000000 76e2f1d3 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b

我以前也做过类似的事情,就是把链子拴在上面。也许像这样的东西会有用:
~*e!为每一帧!如果(@#local==“bar3”){??bar3}
谢谢!使用
!如果($spat(“@#local”,“bar3”)==1{.echo“Yes”}。否则{.echo“No”}
我可以得到每帧一个好的“Yes”或“No”。。。我现在只想得到每个
bar3
的地址。。。正在取得进展。我不需要,我需要。我不需要地址。我能
??直接输入bar3->WhatIAmInterestedIn
,可以吗?因为我已经为这个框架设置了上下文。我从来不知道!!!通过执行
!为每一帧!如果($spat(“@#local”,“hUser”)==1{bar3->WhatIAmInterestedIn}
我从
得到大量噪音!对于每个帧
-有没有一种方法可以让我安静地完成?MS帮助说明:“如果包含CommandString,调试器将在为该帧执行命令之前显示该帧及其索引。”-但如果可能的话,我想停止它这样做。使这些扩展命令保持沉默听起来很棘手。你可能会有一些运气与一些创造性的呼吁。也许您可以设置
.outmask 0
,然后只在打印变量之前以及脚本完成时设置
.outmask/d
。我从未尝试过,所以这只是一个猜测。是否有任何文档说明如何使用诸如
host.currentThread.Stack
之类的东西,以及还有哪些其他可用的API?我在WinDbg预览版中使用了新的脚本支持,最大的障碍是缺少文档——仅仅依靠示例是没有乐趣的。您应该能够访问并查看一些文档。host.*API在中介绍。您应该在WinDbg预览的脚本窗口中获得某种程度的智能感知。此外,可以在调试器中探索host.namespace.Debugger.*下的任何内容。您只需“dx调试器”并单击周围即可。在JavaScript中,任何内容都应该大体相同。您可以添加“-v”以查看所有方法,添加“-h”以查看任何可用的帮助文本(例如:dx-v-h调试器)。