通过程序集以编程方式检测上下文切换

时间:2012-09-25 18:15:28

标签: c windows assembly kernel

我知道在通过托管语言(如C#,Java等)在Windows机器上遇到上下文切换时,无法监听,检测和执行某些操作。但是,我想知道是否有办法使用汇编(或其他语言,也许是C)?如果是这样,你能否提供一个小代码片段,让我们知道如何做到这一点(因为我对内核编程相对较新)?

此代码本质上要设计的内容是在标准Windows UI的后台运行,并监听特定进程何时切入或切出CPU。听到这些动作中的任何一个后,它都会发出信号。为了澄清,我希望只检测直接涉及特定进程的上下文切换,而不是任何上下文切换。我最终希望实现的是,只要特定进程开始使用CPU,以及何时停止使用,就能通知另一台机器(通过互联网信号)。

我这样做的第一次尝试只涉及计算特定进程的CPU使用百分比,但最终证明这种方法过于粗略,无法捕获最精细的计算。例如,我编写了一个测试程序,它只执行操作2 + 2并将答案放在int中。 CPU使用方法没有提到这一点。因此,我正在寻找较低级别的东西,因此这个问题的起源。如果有可能的替代方案,我会非常乐意将它们放在一起。

2 个答案:

答案 0 :(得分:3)

Event Tracing for Windows (ETW),您可以配置它来接收有关系统中发生的各种事件的消息。

您应该能够接收有关线程调度事件的消息。事件的CSwitch class就是为了这个。

抱歉,我不知道您可以轻松重复使用的任何优秀ETW样本。阅读MSDN并环顾四周。

Simon指出了一个很好的链接,解释了为什么ETW有用。非常有启发性:http://randomascii.wordpress.com/2012/05/11/the-lost-xperf-documentationcpu-scheduling/

答案 1 :(得分:2)

请参阅下面的编辑。特别是#3,ETW似乎是要走的路。

理论上,您可以为旧int 2Eh和新sysenter安装自己的陷阱处理程序。然而,在实践中,由于Patchguard(自Vista以来)和签名要求,这不再像过去那样容易了。我不知道任何其他泛型意味着检测上下文切换,这意味着你必须自己动手。操作系统的所有上下文切换都通过调用门(前面提到的陷阱处理程序),如果您对调试/反汇编感到不舒服,ReactOS可以让您在后台窥视。

但是,在任何一种情况下都不应该有泛型方式来安装这样的东西而没有内核模式权限(通常称为ring 0) - 其他任何东西都会成为Windows中的安全漏洞。 我不知道Windows提供的方法可以达到你想要的效果。

“Undocumented Windows NT”这本书有一个关于确切主题的相当好的章节(尽管明显针对旧的int 2Eh方法)。

如果您只能使用某些功能,您可以使用某些过滤器驱动程序或用户模式API挂钩。取决于您的确切要求。

更新:阅读更新的问题,我认为你需要阅读内部内容,特别是关于IRQL的概念(不要与DOS时间的IRQ混淆)和调度程序。问题是,每秒可以 - 通常会 - 数百个上下文切换。但是,您的观察者进程(观察上下文切换的进程)将像任何用户模式进程一样可抢占。这意味着你无法实现实时信号或任何接近它的信号,这对方法提出了很大的问号。

你想要达到的实际目标是什么?上下文切换的数量并不能真正为您提供任何帮助。每个SEH异常都会导致上下文切换。你感兴趣的是什么?也许性能计数器可以更好地满足您的需求?

更新2:即使对于单个线程,大量的上下文切换也会在一秒钟内发布。因此,假设您安装了自己的陷阱处理程序,您仍然会(不利地)影响系统上的所有其他线程(毕竟您将捕获每个上下文切换,然后查看它是否是您关心的进程/线程,然后做你的事情或传递它。)

如果你能告诉我们你最终希望实现的目标,而不是已经预先定义的方法,我们可能会建议替代方案。

更新3:显然我在这方面的错误。 Windows附带了一些信号上下文切换的东西。可以利用ETW来利用这些。感谢西蒙指出。