I catched an exception and want to log it on the console. This works as exepcted, but Valgrind shows me a set of invalid reads.
Here the code of the catch-block:
1 2 3
} catch(HGL::IOException &e) {
logError(e);
}
The signature of the logDebug is: BasicLogger &operator<<(const std::exception &e);
Now valgrind shows me 4 errors like that:
==20943== Invalid read of size 1
==20943== at 0x402C658: strlen (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==20943== by 0x41554DD: std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& std::operator<< <wchar_t, std::char_traits<wchar_t> >(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >&, char const*) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
==20943== by 0x40824FA: HGL::Interpreter::Interpreter::execute(int, char const**) (interpreter.cpp:163)
==20943== by 0x80486D3: main (main.cpp:15)
==20943== Address 0x45593a4 is 12 bytes inside a block of size 109 free'd
==20943== at 0x402ACFC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==20943== by 0x415E99A: std::string::_Rep::_M_destroy(std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
==20943== by 0x43B7966: Commons::BasicLogger::operator<<(std::exception const&) (basiclogger.cpp:106)
==20943== by 0x40824FA: HGL::Interpreter::Interpreter::execute(int, char const**) (interpreter.cpp:163)
==20943== by 0x80486D3: main (main.cpp:15)
What is going wrong? Generally I dislike invalid read in my code, even if they are harmless like in that case.
If I don't pass a reference, but a copy of the exception, I don't get this invalid reads, but also loose all information,because of the implicit upcasting.
Does somebody know why I get the illegal read, resp. why std::wstring is deleting it on the way to the <<-operator?
I have given the valgrind log. The 3 sucessive errors are the same, the invalid read just seems to happen 4 times in one call.
logError is a macro which resolves to exactly ==20943== by 0x43B7966: Commons::BasicLogger::operator<<(std::exception const&) (basiclogger.cpp:106) and there it happens at entering the method.
Additionally valgrind tells us Address 0x45593a4 is 12 bytes inside a block of size 109 free'd.
I use the GNU Compiler, in two versions, depending on the target system. This log comes from a binary compiled with version gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3.
BTW: I don't belive in a bad implementation of std::exception in GNU C++, the error must be somewhere else.
That's the question. And actually your small question @kbw brought me to the idea to check my IOException class. Somehow I guess it can be within this exception.
Solution is simple and easy: don't mix delete with free, i.e. if something - even if deep inside the code - has been malloc'd not new'd, so use free not delete!