gpt4 book ai didi

multithreading - x86 保留 EFLAGS 位 1 == 0 : how can this happen?

转载 作者:行者123 更新时间:2023-12-04 06:48:45 31 4
gpt4 key购买 nike

我正在使用 Win32 API 来停止/启动/检查/更改线程状态。一般来说效果很好。有时它会失败,我试图找出原因。

我有一个线程通过以下方式强制在其他线程上进行上下文切换:

thread stop
fetch processor state into windows context block
read thread registers from windows context block to my own context block
write thread registers from another context block into windows context block
restart thread

这非常有效......但是......很少,上下文切换似乎失败。
(症状:我的多线程系统以奇怪的寄存器内容执行奇怪的地方)。

上下文控制通过以下方式完成:
if ((suspend_count=SuspendThread(WindowsThreadHandle))<0)
{ printf("TimeSlicer Suspend Thread failure");
...
}
...
Context.ContextFlags = (CONTEXT_INTEGER | CONTEXT_CONTROL | CONTEXT_FLOATING_POINT);
if (!GetThreadContext(WindowsThreadHandle,&Context))
{ printf("Context fetch failure");
...
}

call ContextSwap(&Context); // does the context swap

if (ResumeThread(WindowsThreadHandle)<0)
{ printf("Thread resume failure");
...
}

没有任何打印语句被执行。我得出的结论是,Windows 认为上下文操作都可靠地发生了。

哦,是的,我确实知道被停止的线程何时不计算[例如,在系统函数中],并且不会尝试停止/上下文切换它。我知道这一点是因为每个执行除计算之外的任何事情的线程都设置了一个特定于线程的“不要碰我”标志,而它正在执行除计算之外的任何事情。 (设备驱动程序程序员会认为这是“中断禁用”指令的等价物)。

所以,我想知道上下文 block 内容的可靠性。
我对从上下文 block 中提取的各种寄存器值添加了各种健全性测试;您实际上可以确定 ESP 是否正常(在 TIB 中定义的堆栈区域的范围内),PC 在我期望的程序中或在系统调用中,等等。这并不奇怪。

我决定检查条件代码位(EFLAGS)是否被正确读出;如果这是错误的,它将导致切换任务在其状态为
恢复。因此,我添加了以下代码来验证声称的 EFLAGS 寄存器是否包含根据英特尔引用手册 ( http://en.wikipedia.org/wiki/FLAGS_register) 仅看起来像 EFLAGS 的内容。
   mov        eax, Context.EFlags[ebx]  ; ebx points to Windows Context block
mov ecx, eax ; check that we seem to have flag bits
and ecx, 0FFFEF32Ah ; where we expect constant flag bits to be
cmp ecx, 000000202h ; expected state of constant flag bits
je @f
breakpoint ; trap if unexpected flag bit status
@@:

在我的 Win 7 AMD Phenom II X6 1090T(六核)上,
它偶尔会使用断点捕获,ECX = 0200h。在我的 Win 7 Intel i7 系统上以同样的方式失败。我会忽略这一点,
除了它暗示 EFLAGS 没有被正确存储,正如我所怀疑的那样。

根据我对 Intel(以及 AMD)引用手册的阅读,第 1 位是保留的,并且始终具有值“1”。不是我在这里看到的。

显然,MS 通过在线程停止时执行复杂的操作来填充上下文 block 。我希望他们准确地存储状态。该位未正确存储。
如果他们没有正确存储这个位,他们还没有存储什么?

为什么这个位的值有时可能/应该为零的任何解释?

编辑:我的代码在捕获断点时转储寄存器和堆栈。
堆栈区包含上下文 block 作为局部变量。
EAX 和堆栈中上下文 block 中 EFLAGS 的正确偏移处的值都包含值 0244h。所以上下文 block 中的值确实是错误的。

EDIT2:我将掩码和比较值更改为
    and        ecx, 0FFFEF328h         ; was FFEF32Ah where we expect flag bits to be
cmp ecx, 000000200h

这似乎运行可靠,没有任何提示。显然,Win7 没有正确执行 eflags 的第 1 位,这似乎无关紧要。

仍然对解释感兴趣,但显然这不是我偶尔的上下文切换崩溃的根源。

最佳答案

微软长期以来一直在不真正使用的地方隐藏一些位。 Raymond Chen 举了很多例子,例如:使用不是字节对齐的指针的低位。

在这种情况下,Windows 可能需要将它的一些线程上下文存储在现有的 CONTEXT 中。结构,并决定使用 EFLAGS 中未使用的位.无论如何,你不能用那个位做任何事情,当你调用 SetThreadContext 时,Windows 会取回那个位。 .

关于multithreading - x86 保留 EFLAGS 位 1 == 0 : how can this happen?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22777727/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com