我正在分析多线程 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/