多线程 – x86保留EFLAGS位1 == 0:这怎么可能发生?
我正在使用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认为上下文操作都是可靠的. 哦,是的,我确实知道什么时候停止的线程没有计算[例如,在系统功能中]并且不会尝试停止/上下文切换它.我知道这一点,因为每个执行除计算之外的任何事情的线程都设置了一个特定于线程的“请勿触摸我”标志,而它正在进行非计算. (设备驱动程序程序员会将此视为“中断禁用”指令的等效项). 所以,我想知道上下文块的内容的可靠性. 我决定检查条件代码位(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(hex core)上, 根据我对英特尔(以及AMD)参考手册的阅读,第1位保留,值始终为“1”.不是我在这里看到的. 显然,MS通过在线程停止上执行复杂的操作来填充上下文块.我希望他们准确地存储状态.该位未正确存储. 为什么这个位的值有时/应该为零的任何解释? 编辑:我的代码转储寄存器和堆栈捕获断点. 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会得到这一点. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |