KEXT: vnode_open () приводит к панике ядра

Извините, если об этом спрашивали раньше, но я не могу гуглить.

Я пытался прочитать файлы в KEXT OSX, используя vnode_open(), как показано ниже:

        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(), он паникует.

Я что делаю неправильно?


person Cai    schedule 15.09.2015    source источник


Ответы (1)


Одно сразу бросается в глаза:

Вы не должны использовать vfs_context_current() - используйте vfs_context_create(NULL). Что еще хуже, вы впоследствии вызываете vfs_context_rele(ctx); в возвращенном контексте. Сохраняется только vfs_context_create, vfs_context_current() - нет, поэтому вы чрезмерно освобождаете контекст VFS. Это определенно могло вызвать панику ядра.

В общем, при разработке kexts вы действительно можете делать гораздо больше, чем просто позволять системе перезагружаться после паники ядра:

  1. Журналы паники записываются в NVRAM и при следующей загрузке сохраняются в файл. Вы можете проверить их через Console.app в разделе «Отчеты о диагностике системы», начиная с «ядра».
  2. Журналы паники содержат трассировку стека, которая по умолчанию не имеет символов. Вы можете обозначить их символами после сбоя, но гораздо удобнее установить keepsyms=1 аргумент загрузки и заставить обработчик сбоя символизировать за вас.
  3. Вы можете настроить загрузочный аргумент debug, чтобы сбои запускали отладчик ядра или дампы ядра, записывали трассировку стека в последовательную / firewire-консоль и т. Д.

Эти вещи частично задокументированы на сайте Apple, но небольшой поиск в Интернете может дать вам более подробную информацию. В любом случае они невероятно полезны для устранения подобных проблем.

person pmdj    schedule 16.09.2015
comment
ха-ха, я понял, что вскоре после того, как разместил вопрос, но это действительно полезно для остальной дополнительной информации, которую вы предоставили. Спасибо чувак! - person Cai; 17.09.2015