Diagnosis of the mysterious valgrind "invalid write"

[This is long and full of details. My specific questions are introduced in bold Question below.]

Summary

We run some of our test suites under valgrind and encounter an error that doesn't make much sense to me. I am looking for advice on finding out more in detail what might be wrong.

  • Valgrind complains about "invalid size 8 record."
  • The error is consistent with run to run, but comes and comes with inappropriate code changes, different versions of the / stdlib compiler, etc.
  • The address that is being written is on the stack, and as far as I can see, this is a perfectly reasonable address for writing our code.
  • Its alignment corresponds to the size of the record.
  • The place where this happens is deep inside the standard library.

Everything that smells like a real problem elsewhere: something becomes corrupt and leads to confusion later. But this is the first problem with valgrind messages, so if there is a stomp of memory elsewhere, then valgrind cannot catch it. I suspect that either I am missing out on something obvious, or there is a subtle problem that those who have more valgrind experience than me can point me.

Some information

Here are some details and some specific questions.

This is on a Linux box running Ubuntu 14.04 on x64 hardware.

Here is a complaint in one fairly typical case:

==14259== Invalid write of size 8
==14259==    at 0x662BBC9: __printf_fp (printf_fp.c:663)
==14259==    by 0x6629792: vfprintf (vfprintf.c:1660)
==14259==    by 0x664D578: vsnprintf (vsnprintf.c:119)
==14259==    by 0x52DCE0F: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==14259==    by 0x52E3263: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_float<double>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, char, double) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==14259==    by 0x52E354F: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, double) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==14259==    by 0x52EEAF4: std::ostream& std::ostream::_M_insert<double>(double) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==14259==    by 0x694725: CRVinfo::appendValue(std::string const&, double) (CRVinfo.cpp:197)
==14259==    by 0x6902DB: CRVdouble::info(CRVinfo&) const (CRVdouble.cpp:103)
==14259==    by 0x6913B4: CRVcollection::info(CRVinfo&) const (CRVcollection.cpp:60)
==14259==    by 0x6913B4: CRVcollection::info(CRVinfo&) const (CRVcollection.cpp:60)
==14259==    by 0x68F87F: CRVvalue::generate() (CRVvalue.cpp:71)
==14259==  Address 0xffeffde68 is on thread 1 stack
==14259==  in frame #0, created by __printf_fp (printf_fp.c:161)

, "CRV", ; libstd++ glibc. Ubuntu 14.04 2.19 glibc - , , , eglibc 2.19, glibc 2.19; printf_fp.c .

valgrind --vgdb gdb ( , ), , , valgrind , callq __mpn_lshift.

, , :

void CRVinfo::appendValue(const std::string &name, double value){

  addIndent();
  addElementBegin(name);

  std::ostringstream  oss;
  oss << value;
  m_valueTree.append(oss.str());

  addElementEnd(name);
}

oss << value; . m_valueTree std::string; , addIndent addElementBegin; stringstream, , . (, : , , , .)

, , 8 0xffeffde68 callq. , callq , rsp, ( , rsp 0xffeffde68)... valgrind , .

( , . (1) , , , (2) , (3) segfault , , (4) , , rsp 0xfff000598, 10 . .)

. , valgrind ? , valgrind , ?

: , valgrind (, , )? , ?

: glibc libstd++? ( -, , .)

, valgrind - __mpn_lshift - 8. gdb retq __mpn_lshift, .

. Valgrind , , , --max-stacksize - .

gcc , , valgrind 8 __printf_fp, , , ( , , , , , , , . 95% , mov .)

+6

Source: https://habr.com/ru/post/1015800/


All Articles