|
From: john r. <joh...@ro...> - 2007-05-02 14:38:14
|
Hello,
I'm a newbie with Valgrind, but I've already found it very useful!
Valgrinds finds an error in my program, which I can reproduce with this
small
example file called "prova.c". It's a simple program which stores in a
binary file
the current positions of another file, and seems to work properly.
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE* pfile,*pposition;
int i=5;
pfile=fopen("file.dat","w");
pposition=fopen("position.dat","wb");
fprintf(pfile,"%d\n",i);
fpos_t pos;
fgetpos(pfile,&pos);
fwrite(&pos,sizeof(fpos_t),1,pposition);
fclose(pfile);
fclose(pposition);
return 0;
}
The error message I get with "valgrind --leak-check=yes ./a.out" is:
--7620-- DWARF2 CFI reader: unhandled CFI instruction 0:50
--7620-- DWARF2 CFI reader: unhandled CFI instruction 0:50
==7620== Syscall param write(buf) points to uninitialised byte(s)
==7620== at 0x40F14DE: __write_nocancel (in /lib/libc-2.3.6.so)
==7620== by 0x4094A0A: _IO_do_write@@GLIBC_2.1 (in /lib/libc-2.3.6.so)
==7620== by 0x4094154: _IO_file_close_it@@GLIBC_2.1 (in
/lib/libc-2.3.6.so)
==7620== by 0x408A61A: fclose@@GLIBC_2.1 (in /lib/libc-2.3.6.so)
==7620== by 0x804855A: main (prova.c:20)
==7620== Address 0x4022004 is not stack'd, malloc'd or (recently) free'd
==7620==
==7620== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from 1)
==7620== malloc/free: in use at exit: 0 bytes in 0 blocks.
==7620== malloc/free: 2 allocs, 2 frees, 704 bytes allocated.
==7620== For counts of detected errors, rerun with: -v
==7620== All heap blocks were freed -- no leaks are possible.
Can you spot what's wrong with my program?
Thanks for the help,
John Russo
|
|
From: Tom H. <to...@co...> - 2007-05-02 15:05:24
|
In message <463...@ro...>
john russo <joh...@ro...> wrote:
> Valgrinds finds an error in my program, which I can reproduce with
> this small example file called "prova.c". It's a simple program
> which stores in a binary file the current positions of another file,
> and seems to work properly.
>
>
> #include <stdio.h>
> #include <stdlib.h>
>
> int main()
> {
> FILE* pfile,*pposition;
> int i=5;
>
> pfile=fopen("file.dat","w");
> pposition=fopen("position.dat","wb");
>
> fprintf(pfile,"%d\n",i);
> fpos_t pos;
>
> fgetpos(pfile,&pos);
>
> fwrite(&pos,sizeof(fpos_t),1,pposition);
>
> fclose(pfile);
> fclose(pposition);
>
> return 0;
> }
>
> The error message I get with "valgrind --leak-check=yes ./a.out" is:
>
> --7620-- DWARF2 CFI reader: unhandled CFI instruction 0:50
> --7620-- DWARF2 CFI reader: unhandled CFI instruction 0:50
> ==7620== Syscall param write(buf) points to uninitialised byte(s)
> ==7620== at 0x40F14DE: __write_nocancel (in /lib/libc-2.3.6.so)
> ==7620== by 0x4094A0A: _IO_do_write@@GLIBC_2.1 (in /lib/libc-2.3.6.so)
> ==7620== by 0x4094154: _IO_file_close_it@@GLIBC_2.1 (in
> /lib/libc-2.3.6.so)
> ==7620== by 0x408A61A: fclose@@GLIBC_2.1 (in /lib/libc-2.3.6.so)
> ==7620== by 0x804855A: main (prova.c:20)
> ==7620== Address 0x4022004 is not stack'd, malloc'd or (recently) free'd
It is often useful to turn off buffering on the stdio stream when
confronted with a problem like this, as it will then show you exactly
which write is causing the problem.
In this case you only have one, so it doesn't matter.
> Can you spot what's wrong with my program?
I suspect you will find that fpos_t is actually a structure that
happens to include padding bytes that are not being initialised by
fgetpos.
The glibc definition of fpos_t looks like this on my machine:
typedef struct
{
__off_t __pos;
__mbstate_t __state;
} _G_fpos_t;
So it includes both the offset, and the multibyte character conversion
state so that character decoding can resume correctly when you seek
back to the position.
Tom
--
Tom Hughes (to...@co...)
http://www.compton.nu/
|
>> fpos_t pos; And the fix to initialize the 'holes' and/or unused bytes is: memset(&pos, 0, sizeof(pos)); -- |
|
From: john r. <joh...@ro...> - 2007-05-02 16:24:57
|
Great, you fixed the problem. I guess I'll have to refresh my standard library knowledge :-) Thank you, John John Reiser wrote: >>> fpos_t pos; > > And the fix to initialize the 'holes' and/or unused bytes is: > > memset(&pos, 0, sizeof(pos)); > |
|
From: john r. <joh...@ro...> - 2007-05-02 16:23:18
|
Tom Hughes wrote:
> It is often useful to turn off buffering on the stdio stream when
> confronted with a problem like this, as it will then show you exactly
> which write is causing the problem.
Thank you for the tip! :-)
> I suspect you will find that fpos_t is actually a structure that
> happens to include padding bytes that are not being initialised by
> fgetpos.
>
> The glibc definition of fpos_t looks like this on my machine:
>
> typedef struct
> {
> __off_t __pos;
> __mbstate_t __state;
> } _G_fpos_t;
>
> So it includes both the offset, and the multibyte character conversion
> state so that character decoding can resume correctly when you seek
> back to the position.
>
> Tom
I looked the __mbstate_t struct and it contains a union. I guess that's
were the unitialized padding bytes come from.
Anyhow, if this is it, there's nothing I can do, and I'll just have
to suppress the Valgrind message.
Thank you again for the great help you gave me,
John Russo
|