|
From: Zachary T. <div...@gm...> - 2009-07-14 18:20:33
|
On Tue, Jul 14, 2009 at 1:07 PM, Colin Miller<col...@pi...> wrote:
> Zachary Turner wrote:
>>
>> On Tue, Jul 14, 2009 at 12:27 PM, Colin Miller<col...@pi...>
>> wrote:
>>
>> ==7439== Use of uninitialised value of size 4
>> ==7439== at 0x82D32D6: _int_malloc (in /usr/sbin/snip/bin/snip)
>> ==7439== by 0x82D4E3A: malloc (in /usr/sbin/snip/bin/snip)
>> ==7439== by 0x82992E6: operator new(unsigned) (in
>> /usr/snip/snip/bin/snip)
>> ==7439== by 0x827945A: std::string::_Rep::_S_create(unsigned,
>> unsigned, std::allocator<char> const&) (in /usr/sbin/snip/bin/snip)
>> ==7439== by 0x8279D5C:
>> std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned) (in
>> /usr/snip/snip/snip/snip)
>> ==7439== by 0x827A659: std::string::reserve(unsigned) (in
>> /usr/sbin/snip/bin/snip)
>> ==7439== by 0x827A77C: std::string::append(unsigned, char) (in
>> /usr/sbin/snip/bin/snip)
>> ==7439== by 0x827B80F: std::string::resize(unsigned) (in
>> /usr/sbin/snip/bin/snip)
>> ==7439== by 0x80D8153: Foo::Foo(x&, y const&) (Foo.cpp:147)
>> ==7439== by 0x80D4C96: Foo::foi(x&, y const&) (Foo.cpp:234)
>> ==7439== by 0x80D7006: Foo::foj(RsaKeyInfo&) (Foo.cpp:60)
>> ==7439== by 0x80CF313: Bar::Baz() (Bar.cpp:141)
>>
>>
>> The first few all have their roots in libc, and the last one, while it
>> does at least have my code on the callstack, is really nothing
>> special. For example, Foo::Foo (Foo.cpp:147) listed above is
>> basically just the following:
>>
>> class Foo
>> {
>> Foo(x&, const y)
>> {
>> std::stringstream input_buf;
>> //initialize input_buf using whatever method
>>
>> unsigned short length;
>> input_buf.read((char*)&length, sizeof(length));
>> length = ntohs(length);
>> str_.resize(length);
>> }
>> private:
>> std::string str_;
>> };
>>
>>
>
> It's been a while since I've done C++,
> but IIRC, the stream input_buf hasn't had a string associated with it.
> Therefore the read() will read 0 bytes,
> and the variable 'length'
> with be uninitialised
>
> Now assuming that this is just an artefact of stripping the code for display
> here,
> it might be worthwhile calling
> |VALGRIND_CHECK_MEM_IS_DEFINED(length, 4)
> just before the resize(length).
> Prototype is in valgrind/memcheck.h
>
> This will verify that 'length' has been properly initialised.
>
> HTH,
> Colin S. Miller
Thanks! I'll definitely give that a shot, I didn't know about that.
I don't guess this could have anything to do with converting smaller
types to larger types could it? For example, above I've defined
length as a 2-byte value, but then passing it (by value) to a function
which takes a 4-byte value.
Also, for what it's worth, the value _is_ actually uninitialized
except that I pass it to that input_buf.read() method by pointer which
does raw modification of the memory. Is valgrind able to detect this?
In other words, how much dynamic analysis is it actually doing? Is
it actually detecting writes to individual bytes of memory and then
tagging each byte as 'dirty', and verifying for every read that
occurs, that every byte being read from is dirty?
Suppose, for example, that I do the following:
//Process 1
//1. Map a 256-byte region in shared memory.
//2. Wait on a shared condition variable.
//3. Read 256-bytes from the shared memory
//Process 2
//1. Map the same 256-byte region in shared memory.
//2. Write 256-bytes into the shared memory
//3. Signal the shared condition variable
Will valgrind correctly note in this case that the data is
initialized? I bring up this specific scenario because this way
valgrind presumably has no correlation between the two process's
source codes / debug information and would be unable to perform any
static analysis whatsoever. Whereas the example I'm actually
encountering above with the length variable is the same in the sense
that it's relying on non-type-safe, external memory modification, but
it could still in theory be detected with some static analysis.
Also, any suggestions about the libc errors? Those don't have any of
my code on the stack at all. (I'm also not using the most recent
version of Valgrind, I'm using 3.1.x, is there a huge difference?)
|