很抱歉,如果之前有人询问过,但我真的不能谷歌了。
我正在尝试使用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()
,就会发生恐慌。
我做错了吗?
答案 0 :(得分:2)
立即突出的一点是:
您不应该使用vfs_context_current()
- 使用vfs_context_create(NULL)
。更糟糕的是,您随后在返回的上下文中调用了vfs_context_rele(ctx);
。只有vfs_context_create
保留,vfs_context_current()
没有,因此您过度释放VFS上下文。这肯定会导致内核恐慌。
一般来说,在开发kexts时,你真的可以做的不仅仅是在内核恐慌后让系统重启:
keepsyms=1
引导参数并让崩溃处理程序为您进行符号化更方便。debug
启动参数以使崩溃启动内核调试器或核心转储,将堆栈跟踪写入串行/火线控制台等。这些内容部分记录在Apple的网站上,但在网上进行一些搜索可能会为您提供更详细的信息。无论如何,它们对于调试这样的问题非常有用。