2017-01-10 5 views
0

Я работаю над уступкой 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 возможное объяснение: у ОС недостаточно памяти кучи. Я нахожу это маловероятным и даже после этого, я не могу точно объяснить, что здесь происходит.

Некоторые дополнительные код

  1. _fh_create
  2. определение структура СПЧ

    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.

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация и спасибо за помощь!

+4

'handle-> fh_vnode = &file;' будет висящим указателем при возврате функции. Параметры функции - это автоматические переменные (стек) –

+0

Ваша цитата из gdb для измененного значения узла задает неправильный тип - *, а не **. Это опечатка или вы недавно изменили типы? –

+0

@ M.M Итак, я не уверен, что полностью понимаю вашу точку зрения. Вы хотите сказать, что новая переменная (ы) создается внутри фрейма стека _fh_create, и эта переменная удаляется после возвращения функции? Значения * stdoutfh-> fh_vnode и * stdinfh-> fh_vnode заканчиваются тем же, потому что они указывают на то же смещение временных кадров стека (_fh_create)? – Deepak

ответ

1

Код handle->fh_vnode устанавливает указатель на автоматическую переменную («на стек»), параметры функции являются автоматическими переменными. После возвращения функции это будет свисающим указателем.

Чтобы исправить это, вам нужно немного перепроектировать код, например. возможно, struct fh должен просто хранить file, а не указатель на file.

 Смежные вопросы

  • Нет связанных вопросов^_^