Я работаю над уступкой 2 от ops-class.Почему указатель меняется без причины?
Следующая функция загружает массив обработчика файлов для процесса, который создается (например, пользовательские процессы для предоставленных программ тестирования here).
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 (для init 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 }
Определение структуры vnode можно найти here.
Пожалуйста, дайте мне знать, если вам нужна дополнительная информация и спасибо за помощь!
'handle-> fh_vnode = &file;' будет висящим указателем при возврате функции. Параметры функции - это автоматические переменные (стек) –
Ваша цитата из gdb для измененного значения узла задает неправильный тип - *, а не **. Это опечатка или вы недавно изменили типы? –
@ M.M Итак, я не уверен, что полностью понимаю вашу точку зрения. Вы хотите сказать, что новая переменная (ы) создается внутри фрейма стека _fh_create, и эта переменная удаляется после возвращения функции? Значения * stdoutfh-> fh_vnode и * stdinfh-> fh_vnode заканчиваются тем же, потому что они указывают на то же смещение временных кадров стека (_fh_create)? – Deepak