Почему указатель меняется без причины?
Я работаю над заданием 2 класса ops.
Следующая функция загружает массив обработчиков файлов для создаваемого процесса (например, пользовательские процессы для тестовых программ, представленные здесь).
int _fh_bootstrap(struct fharray *fhs){
/* Initialize the file handle array of this process */
fharray_init(fhs);
/* String variables initialized for passage to vfs_open */
char* console_inp = kstrdup(CONSOLE); // CONSOLE = "con:"
char* console_out = kstrdup(console_inp);
char* console_err = kstrdup(console_inp);
/* Return variable */
int ret = 0;
/* Initialize the console files STDIN, STDOUT and STDERR */
struct vnode *stdin;
ret = vfs_open(console_inp,O_RDONLY,0,&stdin);
if(ret != 0){
return ret;
}
kfree(console_inp);
struct fh *stdinfh = kmalloc(sizeof(struct fh));
ret = _fh_create(O_RDONLY,stdin,stdinfh);
if(ret != 0){
return ret;
}
stdinfh->fd = STDIN_FILENO;
fharray_add(fhs,stdinfh,NULL);
struct vnode *stdout;
ret = vfs_open(console_out,O_WRONLY,0,&stdout);
if(ret != 0){
return ret;
}
kfree(console_out);
struct fh *stdoutfh = kmalloc(sizeof(struct fh));
ret = _fh_create(O_WRONLY,stdout,stdoutfh);
if(ret != 0){
return ret;
}
stdoutfh->fd = STDOUT_FILENO;
fharray_add(fhs,stdoutfh,NULL);
struct vnode *stderr;
ret = vfs_open(console_err,O_WRONLY,0,&stderr);
if(ret != 0){
return ret;
}
kfree(console_err);
struct fh *stderrfh = kmalloc(sizeof(struct fh));
ret = _fh_create(O_WRONLY,stderr,stderrfh);
if(ret != 0){
return ret;
}
stderrfh->fd = STDERR_FILENO;
fharray_add(fhs,stderrfh,NULL);
fharray_setsize(fhs,MAX_FD);
return 0;
/* Initialization of stdin, out and err filehandlers complete */
}
Если я использую os161-gdb для выполнения этой функции, я замечаю следующее:
//*stdinfh after the call to _fh_create
{fd = 0, flag = 0, fh_seek = 0, fh_vnode = 0x80044ddc}
//**stdinfh->fh_vnode
{vn_refcount = 2, vn_countlock = {splk_lock = 0, splk_holder = 0x0}, vn_fs = 0x0,
vn_data = 0x8004ab60, vn_ops = 0x8003e690 <dev_vnode_ops>}
Это странная часть. После выполнения второго вызова kmalloc (для инициализации stdoutfh) указатель stdinfh->fh_vnode меняет значение!
//**stdinfh->fh_vnode
(struct vnode *) 0x1
И даже незнакомец, перейдя к следующей строке
fharray_add(fhs,stdoutfh,NULL);
Значение *stdoutfh->fh_vnode и *stdinfh->fh_vnode ЕСТЬ ТО ЖЕ
1 возможное объяснение: не хватает ли ОС кучи памяти. Я нахожу это маловероятным, и даже после этого я не могу точно объяснить, что здесь происходит.
Некоторый дополнительный код
- _fh_create
определение структуры
static int _fh_create(int flag, struct vnode *file, struct fh *handle){ KASSERT(file != NULL); /* W , R , RW */ if ( ((flag & O_RDONLY) && (flag & O_WRONLY)) || ((flag & O_RDWR) && ((flag & O_RDONLY) || (flag & O_WRONLY))) ) { handle = NULL; return 1; } handle->flag = flag; handle->fh_seek = 0; handle->fh_vnode = &file; return 0; }
struct fh { uint32_t fd; // file descriptor int flag; // File handler mode off_t fh_seek; // seek position in file struct vnode **fh_vnode; // File object of the file }
Определение struct vnode можно найти здесь.
Пожалуйста, дайте мне знать, если вам нужна дополнительная информация и спасибо за помощь!
1 ответ
Код handle->fh_vnode
устанавливает указатель на автоматическую переменную ("в стеке"), параметры функции являются автоматическими переменными. После возврата функции это будет висячий указатель.
Чтобы это исправить, вам нужно немного переделать свой код, например, возможно, struct fh
должен просто хранить file
а не указатель на file
,