代码之家  ›  专栏  ›  技术社区  ›  Zohar81

iokit驱动程序中的全局变量

  •  1
  • Zohar81  · 技术社区  · 7 年前

    我在基于iokit的驱动程序中使用了一些全局变量,即在主类实例之外。但是,由于使用未初始化的全局变量或尝试双重释放,这会在驱动程序启动时导致一些意外的恐慌 拆卸时的全局变量。

    iokit驱动程序生命周期中全局变量的生命周期是什么? 如果我在声明时设置全局变量,

    例如,如果我从类型 lck_grp_t * my_lock_grp ...

    1. 我是否可以假设我的全局变量已经分配,并且在iokit驱动程序到达 ::start 方法? ( my_lock_grp = lck_grp_alloc_init("my-locks", my_lock_grp_attr); )

    2. 当我试图在iokit上释放全局变量时,是否可以假定它仍然有效 ::free 方法?( lck_grp_free(my_lock_grp) )

    3. 一般的问题是,与驱动程序实例本身相比,基于iokit的驱动程序中全局变量的生命周期是什么。

    1 回复  |  直到 7 年前
        1
  •  1
  •   pmdj    7 年前

    它的寿命肯定和kext的寿命一样。类上的IOKit init/start/stop/free函数将发生在kext start函数和stop函数之间(您可能没有显式的kext start&stop函数),全局构造函数在kext start函数之前运行,全局析构函数在kext stop函数之后运行。全局/静态变量的内存分配/释放由动态内核链接器在加载和卸载kext代码的同时完成。

    我能想到三件事:

    1. 这个 IOService start() free() 函数不匹配- 自由() 被称为即使 开始() 从来没人打过电话。例如,如果你有一个 probe() 函数,然后调用并返回 nullptr ,然后 开始() 从来没打过电话,但是 自由() 肯定会,它试图释放一个从未分配过的锁组。同样,如果 init() 函数返回false- 开始() 不会跑,但是 自由() 威尔。相当于 自由() 初始化() 成员函数的系列,因此仅无条件销毁(无null ptr签入) 自由() 一切可能的无条件创造 init… 功能。

    2. 开始() 可以在不同实例上调用任意次数,因此如果始终运行 my_lock_grp = lck_grp_alloc_init() 在里面 开始() 创建了两个实例, my_lock_grp 只记住最后一个,所以如果您的类的两个实例都被释放,那么您将尝试释放一个锁组两次,而另一个则完全不被释放。这显然是个坏消息。对于初始化/销毁真正的全局状态,我建议使用kext start和stop函数或全局构造函数/析构函数。

    3. 否则,我怀疑您可能会遇到这样的情况:正在运行的内核的其他部分在kext已经卸载的点上仍然有一个悬挂的引用,例如,如果您创建了一个新的内核线程,而该线程仍在运行,或者如果您还没有注销所有已注册的回调,或者如果回调已注销,但不能保证已完成所有调用。(考斯的听众因后一种情况而臭名昭著)

    如果这些听起来都不是问题所在,我建议发布受影响的代码和恐慌日志,如果我们有一些硬数据,也许我们可以更清楚地了解问题。