跟踪挂钩的自修改代码?

时间:2010-12-29 01:05:14

标签: c linux self-modifying

我正在寻找将跟踪/日志记录挂钩插入到一些性能敏感的驱动程序代码中的最少开销方法。这个日志记录的东西必须始终被编译,但大多数时候什么也不做(但什么也不做)。

没有什么比仅仅使用全局开/关字更简单,做if(enabled){log()}。但是,如果可能的话,我甚至可以避免每次碰到我的一个钩子时加载这个词的费用。在我看来,我可能会使用自修改代码 - 即在我调用跟踪函数的任何地方,当我想要禁用挂钩时,我用NOP覆盖跳转,并在我想要时替换跳转启用它们。

快速谷歌没有发现任何先前的艺术 - 有人做过吗?是否可行,是否有任何重大障碍我不能预见到?

(Linux,x86_64)

4 个答案:

答案 0 :(得分:4)

如果你的编译驱动程序突然大两倍,那有关吗?

构建两个代码路径 - 一个具有日志记录,一个没有。使用全局函数指针跳转到性能敏感部分,并根据需要覆盖它们。

答案 1 :(得分:4)

是的,这种技术已在Linux内核中实现,目的完全相同(跟踪钩子)。

请参阅the LWN article on Jump Labels作为起点。

实际上并没有任何重大的障碍,而是一些小的障碍:多线程进程(在启用或禁用代码时,您必须停止所有其他线程);不连贯的指令缓存(你需要确保在每个核心上刷新I-cache)。

答案 2 :(得分:0)

如果有办法以某种方式声明一个全局寄存器,你可以从外部将每个入口点的单词值加载到驱动程序中,然后检查寄存器。当然,那么你会拒绝将该寄存器用于优化器,这可能会产生一些令人不快的性能后果。

答案 3 :(得分:0)

我写的不是关于这是否可能的问题,而是如果你获得了重要的东西。

一方面,您不希望每次记录可能性时都测试“启用日志记录”,另一方面需要测试“启用日志记录”并使用是或否案例代码覆盖代码。或者你的司机“记住”这不是最后一次,因为这次不需要做任何事情吗?

与每次测试相比,必要的逻辑似乎并不重要。