multithreading - 在调用堆栈中搜索

标签 multithreading windbg

我正在分析多线程 C++ 应用程序的内存和故障转储。

this VisualCommunity question 中所述,我对所有不等待也不 sleep 的线程感兴趣。
目前,我通过以下方式使用 Visual Studio(Threads 窗口)得到了这个答案:
1. 将所有线程复制到 Excel 工作表(第 1 列),
2.将“WaitFor”过滤的线程复制到Excel表(第2列),
3. 将“ sleep ”过滤的线程也复制到 Excel 工作表(在第 2 列的底部),并且
4.使用±MATCH(Column1_1;Column2_$1:Column2_$143;0) Excel 工作表函数以获得我的结果(在 #N/A 上过滤这些结果)。

我想知道我是否可以在 Windbg 中做类似(但更容易)的事情。

目前我可以要求一个完整的调用堆栈列表(使用 Windbg 命令 ~* kb)。

我可以做一个 Search call stack在 Windbg 中(很可能在 ~* kb 命令中添加了一些东西)?是否有任何扩展的可能性(如正则表达式)?

最佳答案

如果复制粘贴,命令必须在单行中删除 Where() 处的换行符

0:057> dx -r1 @$curprocess.Threads.Select(p=>p.Stack).Select(p=>p.Frames).Select(t=>t[1]).Where
( ( p=>p.ToDisplayString().Contains("Wait") == true ))

命令的结果
@$curprocess.Threads.Select(p=>p.Stack).Select(p=>p.Frames).Select(t=>t[1]).  
Where( ( p=>p.ToDisplayString().Contains("Wait") == true ))                
    [0x9dc]          : ntdll!NtWaitForMultipleObjects + 0xc [Switch To]
    [0x480]          : ntdll!NtWaitForMultipleObjects + 0xc [Switch To]
    [0xc4]           : ntdll!NtWaitForMultipleObjects + 0xc [Switch To]
    [0xae8]          : ntdll!NtWaitForSingleObject + 0xc [Switch To]
    [0xeac]          : ntdll!NtWaitForKeyedEvent + 0xc [Switch To]
    [0xf08]          : ntdll!NtWaitForMultipleObjects + 0xc [Switch To]
    [0xdd4]          : ntdll!NtWaitForSingleObject + 0xc [Switch To]
    [0xc64]          : ntdll!NtWaitForSingleObject + 0xc [Switch To]
    [0x89c]          : ntdll!NtWaitForKeyedEvent + 0xc [Switch To]
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    [0x162c]         : ntdll!NtWaitForKeyedEvent + 0xc [Switch To]

再次错误条件的命令必须是单行
0:057> dx -r1 @$curprocess.Threads.Select(p=>p.Stack).Select(p=>p.Frames).Select(t=>t[1]).Where  
( ( p=>p.ToDisplayString().Contains("Wait") == false ))

结果
@$curprocess.Threads.Select(p=>p.Stack).Select(p=>p.Frames).Select(t=>t[1]). 
Where( ( p=>p.ToDisplayString().Contains("Wait") == false ))                
    [0x208]          : ntdll!NtRemoveIoCompletion + 0xc [Switch To]
    [0x3ec]          : ntdll!NtRemoveIoCompletion + 0xc [Switch To]
    [0xadc]          : user32!NtUserGetMessage + 0xc [Switch To]
    [0x1794]         : ntdll!NtDelayExecution + 0xc [Switch To]
    [0xe78]          : ntdll!NtRemoveIoCompletion + 0xc [Switch To]
    [0x1164]         : ntdll!DbgUiRemoteBreakin + 0x3c [Switch To]

Lieven 建议的来自 pde 的 !busy 与内置命令之间的输出比较,稍微修改以排除“RemoveIo”和“Wait”堆栈
0:037> dx @$curprocess.Threads.Select(p=>p.Stack).Select(p=>p.Frames).Select(t=>t[1]).Where(    
(p=>p.ToDisplayString().Contains("Wait") != true)).Where(p=>p.ToDisplayString().   
Contains("Remove") != true)

结果
@$curprocess.Threads.Select(p=>p.Stack).Select(p=>p.Frames).Select(t=>t[1]).  
Where( (p=>p.ToDisplayString().Contains("Wait") !=   
true)).Where(p=>p.ToDisplayString().Contains("Remove") != true)                
    [0xd78]          : user32!NtUserGetMessage + 0xc [Switch To]
    [0xe44]          : user32!NtUserGetMessage + 0xc [Switch To]
    [0x514]          : ntdll!DbgUiRemoteBreakin + 0x3c [Switch To]
0:037> !busy

#  37 TID:0d78 kb kbn kbnL kn knL kpn kPn
 # ChildEBP RetAddr  
00 1737fdd8 770ccde0 ntdll!KiFastSystemCallRet
01 1737fddc 770cce13 user32!NtUserGetMessage+0xc
xxxx
0b 1737ff24 00000000 ntdll!_RtlUserThreadStart+0x1b

   50 TID:0e44 kb kbn kbnL kn knL kpn kPn
 # ChildEBP RetAddr  
00 1fb8fa18 770ccde0 ntdll!KiFastSystemCallRet
01 1fb8fa1c 770c18d9 user32!NtUserGetMessage+0xc
xxxxxx
07 1fb8fb20 00000000 ntdll!_RtlUserThreadStart+0x1b

   53 TID:0514 kb kbn kbnL kn knL kpn kPn
 # ChildEBP RetAddr  
00 144cf778 7780f20f ntdll!DbgBreakPoint
01 144cf7a8 7748ed6c ntdll!DbgUiRemoteBreakin+0x3c
xxxxxxx
05 144cf848 00000000 ntdll!_RtlUserThreadStart+0x1b

Threads: 3 of 54
Frames : 1
Command: knL
Mode   : Basic

关于multithreading - 在调用堆栈中搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54232880/

相关文章:

WinDbg .for 循环

asp.net-mvc - !ClrStack - ASP.NET MVC 应用程序中的调用显示 <NO DATA>

c++ - 在 Windows 中禁用 LFH?

c++ - 同时从 2 个线程读取全局变量

Java多线程: Calling a method on an object that extends Thread

java - executor.shutdown()的使用

c++ - 在 Windbg 中,当抛出特定的 C++ 异常时,我可以跳过中断吗?

c# - 使用 WinDbg 转储时大对象堆的 'Free' block 是什么意思

c++ - 在 Qt 的线程中设置小部件标签文本

python - 从多进程切换到多线程 Dask.DataFrame