KEXT:vnode_open()导致内核恐慌

时间:2015-09-15 05:23:49

标签: macos kernel iokit kernel-extension

很抱歉,如果之前有人询问过,但我真的不能谷歌了。

我正在尝试使用vnode_open()读取 OSX KEXT 中的文件,如下所示:

        struct vnode *vp = NULL;
        kern_return_t kret;
        vfs_context_t ctx = vfs_context_current();

        kret = vnode_open(path, FREAD, 0, 0, &vp, ctx);
        if (kret != KERN_SUCCESS) {
            // Error log
        } else {
            proc_t proc = vfs_context_proc(ctx);
            kauth_cred_t vp_cred = vfs_context_ucred(ctx);

            char *buf = NULL;
            int resid;
            int len = sizeof(struct astruct);
            buf = (char *)IOMalloc(len);

            kret = vn_rdwr(UIO_READ, fvp, (caddr_t)buf,
                           len, 0, UIO_SYSSPACE, 0, vp_cred, &resid, proc);

            vnode_close(fvp, FREAD, ctx);

            if (kret != KERN_SUCCESS) {
                // Error log
            }

            // Do something with the result.
        }
        vfs_context_rele(ctx);

加载kext后,系统会发生混乱并重新启动。只要有vnode_open(),就会发生恐慌。

我做错了吗?

1 个答案:

答案 0 :(得分:2)

立即突出的一点是:

您不应该使用vfs_context_current() - 使用vfs_context_create(NULL)。更糟糕的是,您随后在返回的上下文中调用了vfs_context_rele(ctx);。只有vfs_context_create保留,vfs_context_current()没有,因此您过度释放VFS上下文。这肯定会导致内核恐慌。

一般来说,在开发kexts时,你真的可以做的不仅仅是在内核恐慌后让系统重启:

  1. 恐慌日志被写入NVRAM,并在下次启动时保存到文件中。您可以通过Console.app在"系统诊断报告"下进行检查。从" kernel"开始。
  2. 恐慌日志包含堆栈跟踪,默认情况下为非符号化。您可以在崩溃后对它们进行符号化,但设置keepsyms=1引导参数并让崩溃处理程序为您进行符号化更方便。
  3. 您可以设置debug启动参数以使崩溃启动内核调试器或核心转储,将堆栈跟踪写入串行/火线控制台等。
  4. 这些内容部分记录在Apple的网站上,但在网上进行一些搜索可能会为您提供更详细的信息。无论如何,它们对于调试这样的问题非常有用。