为什么指针无缘无故变化?
Why is the pointer changing for no reason?
我正在处理 ops-class 的作业 2。
以下函数为正在创建的进程引导文件处理程序数组(例如,提供的测试程序的用户进程 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(初始化 stdoutfh)后,stdinfh->fh_vnode 指针改变值!
//**stdinfh->fh_vnode
(struct vnode *) 0x1
更奇怪的是,在进行到下一行之后
fharray_add(fhs,stdoutfh,NULL);
*stdoutfh->fh_vnode和*stdinfh->fh_vnode的值是一样的
1 种可能的解释:OS 是否没有足够的堆内存。我发现这不太可能,即使假设了这一点,我也无法准确解释这里发生的事情。
一些额外的代码
- _fh_create
结构 fh 定义
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的定义here。
如果您需要更多信息,请告诉我,感谢您的帮助!
代码handle->fh_vnode
设置了一个指向自动变量("on the stack")的指针,函数参数是自动变量。在函数 returns 之后,这将是一个悬挂指针。
要解决此问题,您需要 re-design 您的代码,例如也许 struct fh
应该只存储 file
而不是指向 file
.
的指针
我正在处理 ops-class 的作业 2。
以下函数为正在创建的进程引导文件处理程序数组(例如,提供的测试程序的用户进程 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(初始化 stdoutfh)后,stdinfh->fh_vnode 指针改变值!
//**stdinfh->fh_vnode
(struct vnode *) 0x1
更奇怪的是,在进行到下一行之后
fharray_add(fhs,stdoutfh,NULL);
*stdoutfh->fh_vnode和*stdinfh->fh_vnode的值是一样的
1 种可能的解释:OS 是否没有足够的堆内存。我发现这不太可能,即使假设了这一点,我也无法准确解释这里发生的事情。
一些额外的代码
- _fh_create
结构 fh 定义
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的定义here。
如果您需要更多信息,请告诉我,感谢您的帮助!
代码handle->fh_vnode
设置了一个指向自动变量("on the stack")的指针,函数参数是自动变量。在函数 returns 之后,这将是一个悬挂指针。
要解决此问题,您需要 re-design 您的代码,例如也许 struct fh
应该只存储 file
而不是指向 file
.