我收到了一个 20 核 CPU,但某个核心出现间歇性故障。据称英特尔已确认了该问题,但没有进一步说明,而且保修期内无法更换,至少我是这么认为的(我现在无法核实)。CPU 已退还给所有者并提供给我。如果我在 BIOS 中禁用该核心,我可能会得到一个免费的 19 核 CPU。好开心!
为了在压力测试和使用之前识别出有缺陷的内核,我可以反复运行与一个或几个内核相关的软件,看看哪个软件最终会出现故障。或者在 BIOS 中依次禁用每个内核。但
运行 40 个 prime95 线程或其他压力软件,或者运行一个容易导致整个 CPU 出现错误检查的软件,似乎更为优雅。当系统出现 BSOD 时,理论上我可以使用 WinDbg 找到故障线程,然后从中找出错误检查时运行的物理(或逻辑?)核心,在 BIOS 中禁用特定识别的核心,并重新检查 CPU 可靠性,以防出现我不知道的第二个有缺陷的核心。
我可以运行 20 份单线程软件,但我想将此用作“教学时刻”。
我如何在崩溃转储上使用 WinDbg 来跟踪运行错误检查的线程的物理核心编号?
答案1
我知道已经晚了一年,但因为没有人回答。您可以!running -i -t
在 windbg 调试器连接的内核或小型转储中发出,这将显示在逻辑核心上运行的所有线程调用堆栈。
如果您有 1 个插槽,具有 4 个物理核心,具有超线程/同步多线程,则操作系统将看到 8 个逻辑核心,因此您有 8 个活动线程。
这是我的目标机器的样本:
6: kd> !running -i -t
System Processors: (00000000000000ff)
Idle Processors: (00000000000000ba)
Prcbs Current (pri) Next (pri) Idle
0 fffff80633125180 ffffa5067382c080 ( 8) fffff80635638400 ................
# Child-SP RetAddr Call Site
00 ffffb585`704d6878 fffff806`35273151 0xfffff806`34f90003
01 ffffb585`704d6880 fffff806`3533591c nt!HvcallpExtendedFastHypercall+0x51
02 ffffb585`704d6890 fffff806`35335b10 nt!HvlpFastFlushListTb+0xac
03 ffffb585`704d6950 fffff806`353355f3 nt!HvlpFlushRangeListTb+0x88
04 ffffb585`704d69b0 fffff806`352f9642 nt!HvlFlushRangeListTb+0x63
[..]
1c ffffb585`704d78b0 fffff806`356df621 nt!IopSynchronousServiceTail+0x2d8
1d ffffb585`704d7950 fffff806`3527ac15 nt!NtQueryVolumeInformationFile+0x431
1e ffffb585`704d7a10 00007ffb`4ec9c9e4 nt!KiSystemServiceCopyEnd+0x25
1f 0000000f`24cfed48 00000000`00000000 0x00007ffb`4ec9c9e4
1 ffff918159ea5180 ffff918159eb6240 ( 0) ffff918159eb6240 ................
# Child-SP RetAddr Call Site
00 ffffb585`6e22f720 fffff806`3516269c nt!PpmIdleGuestExecute+0x1e
01 ffffb585`6e22f760 fffff806`35161dee nt!PpmIdleExecuteTransition+0x70c
02 ffffb585`6e22fa80 fffff806`3526ce88 nt!PoIdle+0x36e
03 ffffb585`6e22fbe0 00000000`00000000 nt!KiIdleLoop+0x48
2 ffff918159f54180 ffffa506714860c0 (15) ffff918159f65240 ................
# Child-SP RetAddr Call Site
00 ffffb585`6f42f920 fffff806`351b9ee7 nt!KeAbPostRelease+0x11f
01 ffffb585`6f42f970 fffff802`6a4f3f5c nt!ExReleasePushLockSharedEx+0x37
02 ffffb585`6f42f9b0 fffff02f`9262d81a dxgkrnl!CCompositionFrameCollection::FindCompositionFrame+0x9c
03 ffffb585`6f42f9f0 fffff806`3527ac15 win32kbase!NtDCompositionGetFrameSurfaceUpdates+0x14a
04 ffffb585`6f42fa80 00007ffb`4c8136e4 nt!KiSystemServiceCopyEnd+0x25
05 0000000d`a5cff2b8 00000000`00000000 0x00007ffb`4c8136e4
3 ffff91815a080180 ffff91815a091240 ( 0) ffff91815a091240 ................
# Child-SP RetAddr Call Site
00 ffffb585`6e24f720 fffff806`3516269c nt!PpmIdleGuestExecute+0x1e
01 ffffb585`6e24f760 fffff806`35161dee nt!PpmIdleExecuteTransition+0x70c
02 ffffb585`6e24fa80 fffff806`3526ce88 nt!PoIdle+0x36e
03 ffffb585`6e24fbe0 00000000`00000000 nt!KiIdleLoop+0x48
4 ffff91815a180180 ffff91815a191240 ( 0) ffff91815a191240 ................
# Child-SP RetAddr Call Site
00 ffffb585`6e25f720 fffff806`3516269c nt!PpmIdleGuestExecute+0x1e
01 ffffb585`6e25f760 fffff806`35161dee nt!PpmIdleExecuteTransition+0x70c
02 ffffb585`6e25fa80 fffff806`3526ce88 nt!PoIdle+0x36e
03 ffffb585`6e25fbe0 00000000`00000000 nt!KiIdleLoop+0x48
5 ffff91815a1d9180 ffff91815a1ea240 ( 0) ffff91815a1ea240 ................
# Child-SP RetAddr Call Site
00 ffffb585`6e26f720 fffff806`3516269c nt!PpmIdleGuestExecute+0x1e
01 ffffb585`6e26f760 fffff806`35161dee nt!PpmIdleExecuteTransition+0x70c
02 ffffb585`6e26fa80 fffff806`3526ce88 nt!PoIdle+0x36e
03 ffffb585`6e26fbe0 00000000`00000000 nt!KiIdleLoop+0x48
6 ffff91815a306180 ffffa5066f961040 (13) ffff91815a317240 ................
# Child-SP RetAddr Call Site
00 ffffb585`6fa66df0 fffff802`6bf01497 kmsysinfo!GetProcTopology+0x2ab [C:\Users\qwe\source\repos\kmsysinfo\cpufeatures.c @ 703]
01 ffffb585`6fa66ec0 fffff802`6bf0278f kmsysinfo!GetCpuInfo+0x157 [C:\Users\qwe\source\repos\kmsysinfo\cpufeatures.c @ 782]
02 ffffb585`6fa677e0 fffff802`6bf11020 kmsysinfo!DriverEntry+0x15f [C:\Users\qwe\source\repos\kmsysinfo\hpkmsysinfo.c @ 402]
03 ffffb585`6fa678a0 fffff806`3579f72e kmsysinfo!GsDriverEntry+0x20 [minkernel\tools\gs_support\kmodefastfail\gs_driverentry.c @ 47]
04 ffffb585`6fa678d0 fffff806`3579ee6e nt!IopLoadDriver+0x4c2
05 ffffb585`6fa67ab0 fffff806`3519b3c5 nt!IopLoadUnloadDriver+0x4e
06 ffffb585`6fa67af0 fffff806`35112ce5 nt!ExpWorkerThread+0x105
07 ffffb585`6fa67b90 fffff806`352709ca nt!PspSystemThreadStartup+0x55
08 ffffb585`6fa67be0 00000000`00000000 nt!KiStartSystemThread+0x2a
7 ffff91815a400180 ffff91815a411240 ( 0) ffff91815a411240 ................
# Child-SP RetAddr Call Site
00 ffffb585`6e28f720 fffff806`3516269c nt!PpmIdleGuestExecute+0x1e
01 ffffb585`6e28f760 fffff806`35161dee nt!PpmIdleExecuteTransition+0x70c
02 ffffb585`6e28fa80 fffff806`3526ce88 nt!PoIdle+0x36e
03 ffffb585`6e28fbe0 00000000`00000000 nt!KiIdleLoop+0x48
我们看到的是 8 个线程,您可以根据加载了公共 MS 符号的调用堆栈来判断它们在做什么。
- 线程 0:与 NtQueryVolumeInformationFile 和虚拟机管理程序相关的内容
- 线程 1:空闲
- 主题 2:与 graphics/directx 相关的内容
- 线程 3:空闲
- 线程 4:空闲
- 线程 5:空闲
- 线程 6:我正在编写的内核驱动程序,触发了 DebugBreak()
- 线程 7:空闲
在您的场景中,错误检查将会在线程调用堆栈上清楚地看到。
恐怕我不认为 windbg 可以向您提供物理核心/插槽,甚至没有任何 WDM API 可以为您提供此功能,即使 WDM API 可能命名 KeQueryActive处理器和 *处理器相关的内核 API,它们总是返回逻辑核心信息。Windows 并不真正区分物理核心,只有 BIOS 才这样做。
但是,您可以通过 CPUID.0xB 直接从芯片组查询此信息,调用 OS API 来设置内核线程亲和性,遍历所有逻辑核心,查询 x2APIC ID,进行一堆疯狂的位移位,如 intel-64-architecture-processor-topology-enumeration.pdf 中定义的那样,然后您可以获得包计数(插槽)、物理核心和逻辑核心。不幸的是,所有这些都需要内核代码,并且无法在 minidump 上运行。也许有人可以告诉我一些我不知道的 windbg 技巧,以便完成上述操作。