Annoying problem with Valgrind: write binary data

A

Alberto

Hi there!

I'm currently handling with a Valgrind error in a binary mode write of
date. The error is the following:

==6877== Syscall param writev(vector[...]) points to uninitialised
byte(s)
==6877== at 0x4236C61: writev (writev.c:51)
==6877== by 0x40F2909: std::__basic_file<char>::xsputn_2(char const*,
int, char const*, int) (in /usr/lib/libstdc++.so.6.0.13)
==6877== by 0x409E059: std::basic_filebuf said:
::xsputn(char const*, int) (in /usr/lib/libstdc++.so.6.0.13)
==6877== by 0x40C9CB0: std::eek:stream::write(char const*, int) (in /usr/
lib/libstdc++.so.6.0.13)
==6877== by 0x804A68F: convert_struct_to_binary(tNodo*&,
std::basic_ofstream<char, std::char_traits<char> >&) (libplanet.cc:
674)
==6877== by 0x804C5D4: GuardarBinario(tNodo*&) (libplanet.cc:1214)
==6877== by 0x80500B0: main (planet.cc:66)
==6877== Address 0x4353a1e is 110 bytes inside a block of size 8,192
alloc´d
==6877== at 0x4025024: operator new[](unsigned int)
(vg_replace_malloc.c:258)
==6877== by 0x409D592: std::basic_filebuf said:
::_M_allocate_internal_buffer() (in /usr/lib/libstdc++.so.6.0.13)
==6877== by 0x40A15B1: std::basic_filebuf said:
::eek:pen(char const*, std::_Ios_Openmode) (in /usr/lib/libstdc++.so.
6.0.13)
==6877== by 0x40A1855: std::basic_ofstream<char,
std::char_traits<char> >::eek:pen(char const*, std::_Ios_Openmode) (in /
usr/lib/libstdc++.so.6.0.13)
==6877== by 0x804C51D: GuardarBinario(tNodo*&) (libplanet.cc:1202)
==6877== by 0x80500B0: main (planet.cc:66)
==6877==


==6877== Syscall param write(buf) points to uninitialised byte(s)
==6877== at 0x422F113: __write_nocancel (in /lib/tls/i686/cmov/
libc-2.10.1.so)
==6877== by 0x409DDCD: std::basic_filebuf said:
::_M_convert_to_external(char*, int) (in /usr/lib/libstdc++.so.
6.0.13)
==6877== by 0x409DF0E: std::basic_filebuf said:
::eek:verflow(int) (in /usr/lib/libstdc++.so.6.0.13)
==6877== by 0x40A0E07: std::basic_filebuf said:
::_M_terminate_output() (in /usr/lib/libstdc++.so.6.0.13)
==6877== by 0x40A1417: std::basic_filebuf said:
::close() (in /usr/lib/libstdc++.so.6.0.13)
==6877== by 0x40A4C67: std::basic_ofstream<char,
std::char_traits<char> >::~basic_ofstream() (in /usr/lib/libstdc++.so.
6.0.13)
==6877== by 0x804C652: GuardarBinario(tNodo*&) (libplanet.cc:1222)
==6877== by 0x80500B0: main (planet.cc:66)
==6877== Address 0x4353a1e is 110 bytes inside a block of size 8,192
alloc´d
==6877== at 0x4025024: operator new[](unsigned int)
(vg_replace_malloc.c:258)
==6877== by 0x409D592: std::basic_filebuf said:
::_M_allocate_internal_buffer() (in /usr/lib/libstdc++.so.6.0.13)
==6877== by 0x40A15B1: std::basic_filebuf said:
::eek:pen(char const*, std::_Ios_Openmode) (in /usr/lib/libstdc++.so.
6.0.13)
==6877== by 0x40A1855: std::basic_ofstream<char,
std::char_traits<char> >::eek:pen(char const*, std::_Ios_Openmode) (in /
usr/lib/libstdc++.so.6.0.13)
==6877== by 0x804C51D: GuardarBinario(tNodo*&) (libplanet.cc:1202)
==6877== by 0x80500B0: main (planet.cc:66)

It happens when I try to write binary data into the file. I've been
searching all over the internet for this error, but I haven't found
nothing useful. I think it is because in the struct that is to be
written:

fileb.write((const char *)&(pos_binary), sizeof(pos_binary));

There are some junk data initialized. That's the more arguable option.
But I think everything in the program is right. At the end there is no
memory leaks or something like that.

The basic function for creating nodes on the list is this:

bool CrearNodoVacio(pNodo &n)
{
bool status = false;

n = new Nodo;

if (n != NULL)
{
n->pSig = NULL;
status = true;
}

return status;

}

As you see, very simple.


Thank you very much in advance!
 
V

Vladimir Jovic

Alberto wrote:
The basic function for creating nodes on the list is this:

bool CrearNodoVacio(pNodo &n)
{
bool status = false;

n = new Nodo;

if (n != NULL)
{
n->pSig = NULL;
status = true;
}

return status;

}

As you see, very simple.


Thank you very much in advance!

Please tell what crappy compiler are you using, which allows you to do
this :

bool CrearNodoVacio(pNodo &n)
{
n = new Nodo;
....


btw take a look here:
http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.8
 
K

Krice

But I think everything in the program is right.

Even the allocator function itself is bad design and wrong.
You should avoid passing a pointer to be allocated in a
function. Just use new to get a new object! Don't check for
NULL with new, it's useless. You can refactor that function
away and write Nodo *n=new Nodo;
 
J

Jorgen Grahn

Hi there!

I'm currently handling with a Valgrind error in a binary mode write of
date. The error is the following:

==6877== Syscall param writev(vector[...]) points to uninitialised
byte(s)
==6877== at 0x4236C61: writev (writev.c:51)
==6877== by 0x40F2909: std::__basic_file<char>::xsputn_2(char const*,
int, char const*, int) (in /usr/lib/libstdc++.so.6.0.13)

Very hard to read all this wrapped.

....
It happens when I try to write binary data into the file. I've been
searching all over the internet for this error, but I haven't found
nothing useful. I think it is because in the struct that is to be
written:

fileb.write((const char *)&(pos_binary), sizeof(pos_binary));

There are some junk data initialized. That's the more arguable option.
But I think everything in the program is right. At the end there is no
memory leaks or something like that.

I don't understand what you're saying here, and I think you made a
typo or two. But if you write uninitialized data to file, valgrind
*will* warn. That's what it does; that's its job. It doesn't
necessarily mean the program is not alright (except writing random
junk data might expose sensitive information like passwords in some
applications.)

You have the option to (a) ignore this warning, (b) tell valgrind to
ignore it or (c) stop doing the thing it warns about.

If you're dumping data structures straight from memory to disk, I
suppose struct padding will often count as uninitialized data. Generally
people avoid doing that anyway, because the file format becomes very
dependant on the exact executable that wrote it.

/Jorgen
 
A

Alberto

If you're dumping data structures straight from memory to disk, I
suppose struct padding will often count as uninitialized data. Generally
people avoid doing that anyway, because the file format becomes very
dependant on the exact executable that wrote it.

Yes, that's the problem exactly. But, how I can get rid of these
uninitialized bytes?

On the other hand, I know this code looks like crap, but I have to
make it *this* way because the teacher says so. Yes, I know my college
sucks, but I can't do nothing. In fact, I asked him this problem and
he told me something totally unrelated with the real problem.

Ah! and this is my first time in a news group :) I will try to make it
better the next time. http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.8
is now in my reading-list queue :)

Thanks!
 
J

Jorgen Grahn

Yes, that's the problem exactly. But, how I can get rid of these
uninitialized bytes?

Given what your teacher wants (below), I suggest you ignore those
warnings now that you understand them. You will, I think, get at most
one per struct, so you can still use the tool to tell you about worse
problems.
On the other hand, I know this code looks like crap, but I have to
make it *this* way because the teacher says so. Yes, I know my college
sucks, but I can't do nothing. In fact, I asked him this problem and
he told me something totally unrelated with the real problem.

C++ teachers seem to be worse than others, so I hope the rest of the
college is better. If nothing else, you have learned scepticism ;-)

/Jorgen
 
A

Alberto

Yeah. Actually I got 10/10 in that pratice, so I have learned some
useful stuff and I have passed that subject. Now it's time to really
improve my C++ level by self-teaching :)

Thanks everyone again!
 
A

Alberto

Yeah. Actually I got 10/10 in that pratice, so I have learned some
useful stuff and I have passed that subject. Now it's time to really
improve my C++ level by self-teaching :)

Thanks everyone again!

Ok, I managed to fix this bug finally! After reading a lot of about
struct, memory, alignement, etc. I found a simple fix doing this:

typedef struct
{
char nombre[40], descripcion[70];
char _pad[2]; // explicit padding
type_coord c;

} type_pos_binary;

that's because I had 16 bits unitialised in this struct padding:

----------------------
| 320 bits |
----------------------
| 544 bits |
----------------------
| 16 bits | empty! |
----------------------
| 64 bits |
----------------------

then initializing the 2 chars with '\0'; that solved the problem of
uninitialized values!

Hope this help future people with the same problem.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,534
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top