Valgrind 发现了以下错误,我在阅读文档、代码和此处的其他问题后无法弄清楚原因。
Valgrind:第一次警告
~$ valgrind --vgdb=yes --vgdb-error=0 --read-var-info=yes --leak-check=yes --track-origins=yes debitadmin*
debitadmin ==20720== Conditional jump or move depends on uninitialised value(s)
==20720== at 0x4013BC6: initialise (dbg.c:199)
==20720== by 0x4013F5C: ??? (in /opt/ivb/lib/libdbg.so)
==20720== by 0x4013917: ??? (in /opt/ivb/lib/libdbg.so)
==20720== by 0x5F5FFE: _dl_init (in /lib/ld-2.12.so)
==20720== by 0x5E788E: ??? (in /lib/ld-2.12.so)
==20720== Uninitialised value was created by a stack allocation
==20720== at 0x4013A8F: initialise (dbg.c:150)
GDB 和 Valgrind:符号
(gdb) info symbol 0x4013A8F
initialise + 5 in section .text of /opt/ivb/lib/libdbg.so
(gdb) info symbol 0x4013BC6
initialise + 316 in section .text of /opt/ivb/lib/libdbg.so
代码:dbg.c
148 void
149 initialise(void)
150 {
151 register int i = 0;
152 char buffer[FILENAME_MAX] = "";
153 char *program = NULL;
154 struct sigaction act = {0};
...
...
195 while ( ! feof(proc_file) && ! ferror(proc_file))
196 {
197 char ch;
198 fread(&ch,1,1,proc_file);
199 if ( ch != 0 )
200 fprintf(stderr,"%c",ch);
201 else
202 fprintf(stderr," ");
203 }
GDB:回溯
(gdb) bt
#0 0x04013bc6 in initialise () at dbg.c:199
#1 0x04013f5d in __do_global_ctors_aux () from /opt/ivb/lib/libdbg.so
#2 0x04013918 in _init () from /opt/ivb/lib/libdbg.so
#3 0x005f5fff in _dl_init_internal () from /lib/ld-linux.so.2
#4 0x005e788f in _dl_start_user () from /lib/ld-linux.so.2
GDB:本地人
(gdb) info locals
ch = 0 '\000'
c = 10
额外信息
- 此代码是从 Solaris 移植到 Unix 的库的一部分
我的理解:
Valgrind 提示说
char ch;
没有初始化,即使在
之后fread(&ch,1,1,proc_file);
在检查上面一行之后的 GDB ch
值后,我有:
ch = 0 '\000'
proc_file 不对应,如您所见:
(gdb) print *proc_file
$17 = {
_flags = -72538984,
_IO_read_ptr = 0x4352000 "debitadmin",
_IO_read_end = 0x4352000 "debitadmin",
_IO_read_base = 0x4352000 "debitadmin",
_IO_write_base = 0x4352000 "debitadmin",
_IO_write_ptr = 0x4352000 "debitadmin",
_IO_write_end = 0x4352000 "debitadmin",
_IO_buf_base = 0x4352000 "debitadmin",
_IO_buf_end = 0x4353000 <Address 0x4353000 out of bounds>,
_IO_save_base = 0x0,
_IO_backup_base = 0x0,
_IO_save_end = 0x0,
_markers = 0x0,
_chain = 0x79c580,
_fileno = 3,
_flags2 = 0,
_old_offset = 0,
_cur_column = 0,
_vtable_offset = 0 '\000',
_shortbuf = "",
_lock = 0x43dc0c0,
_offset = -1,
__pad1 = 0x0,
__pad2 = 0x43dc0cc,
__pad3 = 0x0,
__pad4 = 0x0,
__pad5 = 0,
_mode = -1,
_unused2 = '\000' <repeats 39 times>
}
没有 MCVE,因为我仍然不确定问题出在哪里,我指望专家帮助我解决这个问题。
所以,我的问题是,为什么 fread()
赋值后 ch
还是空的?这是 Solaris 和 Linux 之间的可移植性问题吗?这是问题所在还是我遗漏了什么?
更新:文件已打开并检查是否为空。
#elif LINUX
{
char name[FILENAME_MAX];
FILE *proc_file;
sprintf(name,"/proc/%d/cmdline",(int)getpid());
proc_file=fopen (name,"r");
if ( proc_file != NULL )
{
int c;
/* read in the programs name */
for(c=0; ((fread(&buffer[c],1,1,proc_file)== 1) && (buffer[c]!=0)); c++);
/* print out the program */
(void)fprintf(stderr,"%s ", buffer);
/* and the program arguments , not efficient but it works....*/
fprintf(stderr," ");
while ( ! feof(proc_file) && ! ferror(proc_file))
{
char ch;
test *t;
t = fread(&ch,1,1,proc_file);
if ( ch != 0 )
fprintf(stderr,"%c",ch);
else
fprintf(stderr," ");
}
(void) fprintf(stderr,"\n\n");
}
}
#endif
最佳答案
Q 1. why is
ch
empty even after fread() assignment?
(很可能)因为 fread()
失败了。请参阅下面的详细答案。
Q 2.Is this a portability issue between Solaris and Linux?
不,可能您的代码本身存在问题,valgrind 已正确报告该问题。
我不太确定下面的方法将解决你的问题,但你应该考虑以下几点来改进你的代码,例如,
第1点:检查
fread()
的返回值以确保成功。如果fread()
失败,稍后使用ch
将调用 read-before-write 方案。由于ch
是自动 局部变量且未显式初始化,它将调用undefined behaviour。 .第 2 点:阅读:Why is
while ( !feof (file) )
(almost) always wrong?
关于c - fread()、solaris 到 unix 的可移植性和未初始化值的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30843844/