Valgrind supplying question marks - c++

I'm trying to track down some mysterious crashes that seem to be memory-related thus far. So, I've started using Valgrind to get it done. I've never used it before, but the first run gave me some good information. Today I had a chance to run it again (the circumstance in which we see a crash isn't reproducible) and the output was decidedly less useful.
==11831==
==11831== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==11831== Bad permissions for mapped region at address 0x75EAB8
==11831== at 0x75EAB8: ??? (in /usr/local/bin/test-app.V1.88)
==11831== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==11831== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==11831== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==11831== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==11831== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==11831== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==11831== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==11831==
==11831== HEAP SUMMARY:
==11831== in use at exit: 3,611,867 bytes in 12,934 blocks
==11831== total heap usage: 15,871 allocs, 2,937 frees, 26,483,142 bytes allocated
==11831==
==11831== LEAK SUMMARY:
==11831== definitely lost: 0 bytes in 0 blocks
==11831== indirectly lost: 0 bytes in 0 blocks
==11831== possibly lost: 206,203 bytes in 7,146 blocks
==11831== still reachable: 3,405,664 bytes in 5,788 blocks
==11831== suppressed: 0 bytes in 0 blocks
==11831== Rerun with --leak-check=full to see details of leaked memory
==11831==
==11831== For counts of detected and suppressed errors, rerun with: -v
==11831== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
So, I ran it again with --leak-check=full and it did give me more:
==13764==
==13764== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==13764== Bad permissions for mapped region at address 0x75EAB8
==13764== at 0x75EAB8: ??? (in /usr/local/bin/test-app.V1.88)
==13764== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==13764== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==13764== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==13764== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==13764== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==13764== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==13764== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==13764==
==13764== HEAP SUMMARY:
==13764== in use at exit: 3,611,867 bytes in 12,934 blocks
==13764== total heap usage: 15,871 allocs, 2,937 frees, 26,483,154 bytes allocated
==13764==
==13764== 26 bytes in 1 blocks are possibly lost in loss record 5 of 343
==13764== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==13764== by 0x4ED0A88: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4ED0C79: std::string::_M_mutate(unsigned long, unsigned long, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4ED0E1B: std::string::_M_replace_safe(unsigned long, unsigned long, char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4D48B3: abc::load_config_file(std::string) (abc_read_config_file.cpp:46)
==13764== by 0x4C0A3A: AppStartup(int, char**, char const*) (AppBase.cpp:58)
==13764== by 0x49BFC1: main (App.cpp:54)
==13764==
==13764== 28 bytes in 1 blocks are possibly lost in loss record 6 of 343
==13764== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==13764== by 0x4ED0A88: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4ED2494: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4ED25E2: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4FCB74: __static_initialization_and_destruction_0(int, int) (xyzLib.cc:46)
==13764== by 0x4FCD12: _GLOBAL__sub_I_xyzLib.cc (xyzLib.cc:2179)
==13764== by 0x52280C: __libc_csu_init (in /usr/local/bin/test-app.V1.88)
==13764== by 0x58826FF: (below main) (libc-start.c:185)
==13764==
==13764== 28 bytes in 1 blocks are possibly lost in loss record 7 of 343
==13764== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==13764== by 0x4ED0A88: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4ED22B4: char* std::string::_S_construct<char*>(char*, char*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4ED2414: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&, unsigned long, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4ED2441: std::string::substr(unsigned long, unsigned long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x500E27: XyzParameter::getField(std::string&, char const*, std::string const&, unsigned long&, bool) (xyzMessageCodec.hh:1186)
==13764== by 0x500FBB: XyzParameter::getFields(std::vector<std::string, std::allocator<std::string> >&, int, std::string const&, bool) (xyzMessageCodec.hh:1219)
==13764== by 0x5021F3: XyzParameter::getPositionsList(std::string const&) (xyzMessageCodec.hh:1414)
==13764== by 0x4FAF0B: Xyz::XyzLib::MessageHandler::handleOpenPositionsResponse(void*) (xyzLib.cc:1854)
==13764== by 0x4F8F08: Xyz::XyzLib::MessageHandler::handleXyzMsg(void*) (xyzLib.cc:1444)
==13764== by 0x4F7CCC: Xyz::XyzLib::MessageHandler::onMsg(Xyz::Xyz::XyzMessage*) (xyzLib.cc:1211)
==13764== by 0x51101D: Xyz::Xyz::XyzSession::processNextMsg() (xyzSession.cc:270)
==13764==
==13764== 29 bytes in 1 blocks are possibly lost in loss record 8 of 343
==13764== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==13764== by 0x4ED0A88: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4ED2494: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4ED25E2: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4A62CE: __static_initialization_and_destruction_0(int, int) (Distributor.h:190)
==13764== by 0x4A659F: _GLOBAL__sub_I_abc.cpp (abc.cpp:522)
==13764== by 0x52280C: __libc_csu_init (in /usr/local/bin/test-app.V1.88)
==13764== by 0x58826FF: (below main) (libc-start.c:185)
==13764==
==13764== 29 bytes in 1 blocks are possibly lost in loss record 9 of 343
==13764== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==13764== by 0x4ED0A88: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4ED2494: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4ED25E2: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4A6311: __static_initialization_and_destruction_0(int, int) (Distributor.h:190)
==13764== by 0x4A659F: _GLOBAL__sub_I_abc.cpp (abc.cpp:522)
==13764== by 0x52280C: __libc_csu_init (in /usr/local/bin/test-app.V1.88)
==13764== by 0x58826FF: (below main) (libc-start.c:185)
And on it goes for another 14,000 lines and a few PID's.
My question is: what exactly is this reporting? The last time I ran valgrind on an app crashing like this, I was pointed squarely at the destructor of a class, specifically of a std::string data member of that class. This time, however, valgrind only has question marks for me and a whole lot more dealing with the new operator from std::string. I'm genuinely unaware how one might proceed with this information to arrive at some sort of conclusion and fix a bug or four.
EDIT Here are the specific lines valgrind is suspicious of:
app_params.tracked_symbol="a";
const std::string XyzLib::LANGUAGE_ID = "C++";
The next two are a return statement and the closing brace of a class. It continues like that for quite a few instances of valgrind's concern (closing braces of the several classes).

Related

Memory leak when linking against opencv

I'm linking a library against opencv libraries. I noticed that when I run the unit test executable (using GTest) for that library, that valgrind reports a memory leak/conditional jump or move depends on uninitialised value, even when the test doesn't do anything at all (just empty test method).
I traced that issue back to a single line in my CMakeLists.txt - when I remove the linkage against opencv, the memory leak goes away. This is the releavant snippet:
find_package(OpenCV REQUIRED)
set(libImageSources src/SourceImageFile.cpp)
add_library(image SHARED ${libImageSources})
# removing this line fixes the leak:
target_link_libraries(image ${OpenCV_LIBS})
Otherwise when runnig an empty unit test, I get an error like this:
==18681== Memcheck, a memory error detector
==18681== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==18681== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==18681== Command: ./image_test /Users/max/Documents/playground/cpp/image-server/tests
==18681==
==18681== Conditional jump or move depends on uninitialised value(s)
==18681== at 0x7FFF5FC24A27: bcmp (in /usr/lib/dyld)
==18681== by 0x7FFF5FC11904: ImageLoaderMachO::validateFirstPages(linkedit_data_command const*, int, unsigned char const*, unsigned long, long long, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC16B7A: ImageLoaderMachOCompressed::instantiateFromFile(char const*, int, unsigned char const*, unsigned long, unsigned long long, unsigned long long, stat const&, unsigned int, unsigned int, linkedit_data_command const*, encryption_info_command const*, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC10A6E: ImageLoaderMachO::instantiateFromFile(char const*, int, unsigned char const*, unsigned long long, unsigned long long, stat const&, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC038C2: dyld::loadPhase6(int, stat const&, char const*, dyld::LoadContext const&) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC08468: dyld::loadPhase5(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC08188: dyld::loadPhase4(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC07EED: dyld::loadPhase3(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC07642: dyld::loadPhase1(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC0347A: dyld::loadPhase0(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC0315E: dyld::load(char const*, dyld::LoadContext const&) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC08705: dyld::libraryLocator(char const*, bool, char const*, ImageLoader::RPathChain const*) (in /usr/lib/dyld)
==18681==
==18681== Use of uninitialised value of size 8
==18681== at 0x7FFF5FC24A3F: bcmp (in /usr/lib/dyld)
==18681== by 0x7FFF5FC11904: ImageLoaderMachO::validateFirstPages(linkedit_data_command const*, int, unsigned char const*, unsigned long, long long, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC16B7A: ImageLoaderMachOCompressed::instantiateFromFile(char const*, int, unsigned char const*, unsigned long, unsigned long long, unsigned long long, stat const&, unsigned int, unsigned int, linkedit_data_command const*, encryption_info_command const*, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC10A6E: ImageLoaderMachO::instantiateFromFile(char const*, int, unsigned char const*, unsigned long long, unsigned long long, stat const&, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC038C2: dyld::loadPhase6(int, stat const&, char const*, dyld::LoadContext const&) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC08468: dyld::loadPhase5(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC08188: dyld::loadPhase4(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC07EED: dyld::loadPhase3(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC07642: dyld::loadPhase1(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC0347A: dyld::loadPhase0(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC0315E: dyld::load(char const*, dyld::LoadContext const&) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC08705: dyld::libraryLocator(char const*, bool, char const*, ImageLoader::RPathChain const*) (in /usr/lib/dyld)
==18681==
==18681== Use of uninitialised value of size 8
==18681== at 0x7FFF5FC24A44: bcmp (in /usr/lib/dyld)
==18681== by 0x7FFF5FC11904: ImageLoaderMachO::validateFirstPages(linkedit_data_command const*, int, unsigned char const*, unsigned long, long long, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC16B7A: ImageLoaderMachOCompressed::instantiateFromFile(char const*, int, unsigned char const*, unsigned long, unsigned long long, unsigned long long, stat const&, unsigned int, unsigned int, linkedit_data_command const*, encryption_info_command const*, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC10A6E: ImageLoaderMachO::instantiateFromFile(char const*, int, unsigned char const*, unsigned long long, unsigned long long, stat const&, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC038C2: dyld::loadPhase6(int, stat const&, char const*, dyld::LoadContext const&) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC08468: dyld::loadPhase5(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC08188: dyld::loadPhase4(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC07EED: dyld::loadPhase3(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC07642: dyld::loadPhase1(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC0347A: dyld::loadPhase0(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC0315E: dyld::load(char const*, dyld::LoadContext const&) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC08705: dyld::libraryLocator(char const*, bool, char const*, ImageLoader::RPathChain const*) (in /usr/lib/dyld)
==18681==
==18681== Conditional jump or move depends on uninitialised value(s)
==18681== at 0x7FFF5FC11907: ImageLoaderMachO::validateFirstPages(linkedit_data_command const*, int, unsigned char const*, unsigned long, long long, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC16B7A: ImageLoaderMachOCompressed::instantiateFromFile(char const*, int, unsigned char const*, unsigned long, unsigned long long, unsigned long long, stat const&, unsigned int, unsigned int, linkedit_data_command const*, encryption_info_command const*, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC10A6E: ImageLoaderMachO::instantiateFromFile(char const*, int, unsigned char const*, unsigned long long, unsigned long long, stat const&, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC038C2: dyld::loadPhase6(int, stat const&, char const*, dyld::LoadContext const&) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC08468: dyld::loadPhase5(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC08188: dyld::loadPhase4(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC07EED: dyld::loadPhase3(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC07642: dyld::loadPhase1(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC0347A: dyld::loadPhase0(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC0315E: dyld::load(char const*, dyld::LoadContext const&) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC08705: dyld::libraryLocator(char const*, bool, char const*, ImageLoader::RPathChain const*) (in /usr/lib/dyld)
==18681== by 0x7FFF5FC0E85D: ImageLoader::recursiveLoadLibraries(ImageLoader::LinkContext const&, bool, ImageLoader::RPathChain const&) (in /usr/lib/dyld)
==18681==
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from ImageProcessingConfigurationService
[ RUN ] ImageProcessingConfigurationService.evaluateConfigurationFile
[ OK ] ImageProcessingConfigurationService.evaluateConfigurationFile (13 ms)
[----------] 1 test from ImageProcessingConfigurationService (28 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (114 ms total)
[ PASSED ] 1 test.
==18681==
==18681== HEAP SUMMARY:
==18681== in use at exit: 1,346,030 bytes in 1,453 blocks
==18681== total heap usage: 2,926 allocs, 1,473 frees, 3,045,052 bytes allocated
==18681==
==18681== LEAK SUMMARY:
==18681== definitely lost: 10,580 bytes in 137 blocks
==18681== indirectly lost: 10,032 bytes in 152 blocks
==18681== possibly lost: 9,568 bytes in 183 blocks
==18681== still reachable: 43,598 bytes in 520 blocks
==18681== suppressed: 1,272,252 bytes in 461 blocks
==18681== Rerun with --leak-check=full to see details of leaked memory
==18681==
==18681== For counts of detected and suppressed errors, rerun with: -v
==18681== Use --track-origins=yes to see where uninitialised values come from
==18681== ERROR SUMMARY: 36 errors from 4 contexts (suppressed: 0 from 0)
Compiler is clang++ Apple LLVM version 7.3.0 (clang-703.0.31), OS X El Capitan (10.11.1).
Anyone else has had an issue like that? It seems stuff works nontheless, but the error creates noise that I'd rather ignore, I'm not sure if I can fix the root cause.
The issue seems like a false positive reported by valgrind which I can ignore as it's not caused by code.
I tried (at the time of writing) the latest valgrind suppressions file for macOS which didn't work for me, the issue was still reported.
I let valgrind dump the suppressions needed to ignore this error, using a command like:
valgrind --leak-check=full --show-reachable=yes --error-limit=no --gen-suppressions=all --log-file=l.log ./image_test
And then used a tool to parse the log output (the awk script didn't work for me as it contained a syntax error, I used the perl version) into a suppressions file:
cat l.log | ./parse_valgrind_suppressions.pl > s.supp
Now running the test with the generated suppresions file ignores the memory leak:
valgrind --suppressions=./s.supp ./image_test

valgrind detects errors when c++ exception is not caught

I notice that the valgrind reports possible memory leak for the following minimal example:
#include <stdexcept>
int main() {
try {
throw std::logic_error("test");
}
catch (std::exception& e) {
std::string msg("test2 ");
msg.append(e.what());
throw std::logic_error(msg);
}
return 0;
}
After compiling it with g++ test.cpp -g, the valgrind detects some errors with valgrind --tool=memcheck --leak-check=full ./a.out. Is this normal?
I concern this issue because the valgrind reports some errors of my R extensions which is similar to this example.
The valgrind version is: 3.10.0.SVN. The gcc version is 4.8.2 (Ubuntu 4.8.2-19ubuntu1). The reported message is shown below:
==8640== Memcheck, a memory error detector
==8640== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==8640== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==8640== Command: ./a.out
==8640==
terminate called after throwing an instance of 'std::logic_error'
what(): test2 test
==8640==
==8640== HEAP SUMMARY:
==8640== in use at exit: 354 bytes in 4 blocks
==8640== total heap usage: 6 allocs, 2 frees, 417 bytes allocated
==8640==
==8640== 29 bytes in 1 blocks are possibly lost in loss record 1 of 4
==8640== at 0x4C2B0E0: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8640== by 0x4EF13B8: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==8640== by 0x4EF2AE0: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==8640== by 0x4EF2EF7: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==8640== by 0x400BA7: main (test.cpp:4)
==8640==
==8640== 37 bytes in 1 blocks are possibly lost in loss record 2 of 4
==8640== at 0x4C2B0E0: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8640== by 0x4EF13B8: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==8640== by 0x4EF1F7A: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==8640== by 0x4EF2013: std::string::reserve(unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==8640== by 0x4EF225E: std::string::append(char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==8640== by 0x400CC6: main (test.cpp:8)
==8640==
==8640== 144 bytes in 1 blocks are possibly lost in loss record 3 of 4
==8640== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8640== by 0x4E944E2: __cxa_allocate_exception (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==8640== by 0x400B83: main (test.cpp:4)
==8640==
==8640== 144 bytes in 1 blocks are possibly lost in loss record 4 of 4
==8640== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8640== by 0x4E944E2: __cxa_allocate_exception (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==8640== by 0x400CD0: main (in /home/wush/Test/a.out)
==8640==
==8640== LEAK SUMMARY:
==8640== definitely lost: 0 bytes in 0 blocks
==8640== indirectly lost: 0 bytes in 0 blocks
==8640== possibly lost: 354 bytes in 4 blocks
==8640== still reachable: 0 bytes in 0 blocks
==8640== suppressed: 0 bytes in 0 blocks
==8640==
==8640== For counts of detected and suppressed errors, rerun with: -v
==8640== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 1 from 1)
Aborted (core dumped)

Memory Corruption on Allocation

I've been having a problem with allocating memory for one of my data structures. It always crashes out, but it's not always at the same place. My suspicion is that I'm trying to allocate it over the top of something that's already there, but I'm really not sure how to tell what's actually going on or how to fix it - I've tried to install valgrind, but that doesn't yet support Mac OS 10.10.
This is the code that calls the function.
stet::file f1;
f1.set_path("test/longfile1.txt"); // a file with almost 2 million lines
f1.read();
std::string all_text = f1.get_contents();
std::vector<chunk *> chunks = populate_chunks(all_text);
These are my data structures - the idea is that the text from file is split into fixed sized chunks, which are populated up to 75% capacity, but I can't seem to create all the chunks.
struct line {
std::string text;
};
struct chunk {
line *lines[MAX_CHUNK_SIZE];
};
And this is the cause of my nightmares - it crashes out on the line below all the comments.
std::vector<chunk *> populate_chunks(std::string &text) {
std::vector<std::string> all_lines;
boost::split(all_lines, text, boost::is_any_of("\n"));
size_t num_lines = all_lines.size();
std::vector<chunk *> chunks = std::vector<chunk *>( (num_lines / START_CHUNK_SIZE) * 2 );
size_t next_line_num;
for(size_t line_num = 0; line_num < num_lines; line_num = next_line_num) {
next_line_num = line_num + START_CHUNK_SIZE;
std::cout << line_num << std::endl;
chunk *c = new chunk;
chunks.push_back(c);
// This always falls over, but not always at the same point in the file.
// Never seems to be the first time. Observed range: 3072 - 59904
// Error always looks something like this:
// text(71184,0x7fff77699300) malloc: *** error for object 0x7ff389006208: incorrect checksum for freed object - object was probably modified after being freed.
// *** set a breakpoint in malloc_error_break to debug
for(size_t i = 0; i < next_line_num; ++i) {
line *l = new line;
l->text = all_lines[line_num+i];
c->lines[i] = l;
}
}
return chunks;
}
If anyone has any ideas, they'd be much appreciated - it should be noted that I'm pretty new to C++, so it's quite likely that I've missed something really stupid.
Update:
I've fiddled around with the code to change things based on the comments I've been getting:
Made chunks the function's return value, rather than a pointer
Stopped giving the all_lines vector a size on creation, allowed boost to sort that out
I also got a fedora VM up and running in order to put it through valgrind and I'm really very confused by the output.
Noted the values of MAX_CHUNK_SIZE and START_CHUNK_SIZE below.
Macro values:
#define MAX_CHUNK_SIZE 1024
#define START_CHUNK_SIZE MAX_CHUNK_SIZE * 0.75
Valgrind output after the above changes:
==24468== Memcheck, a memory error detector
==24468== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==24468== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==24468== Command: bin/text
==24468==
==24468== Invalid write of size 8
==24468== at 0x402907: populate_chunks(std::string&) (text_storage.cc:125)
==24468== by 0x402ADF: main (text_storage.cc:173)
==24468== Address 0x216b5640 is 0 bytes after a block of size 8,192 alloc'd
==24468== at 0x4C27965: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==24468== by 0x402888: populate_chunks(std::string&) (text_storage.cc:113)
==24468== by 0x402ADF: main (text_storage.cc:173)
==24468==
==24468==
==24468== Process terminating with default action of signal 11 (SIGSEGV)
==24468== Access not within mapped region at address 0x37D77000
==24468== at 0x402907: populate_chunks(std::string&) (text_storage.cc:125)
==24468== by 0x402ADF: main (text_storage.cc:173)
==24468== If you believe this happened as a result of a stack
==24468== overflow in your program's main thread (unlikely but
==24468== possible), you can try to increase the size of the
==24468== main thread stack using the --main-stacksize= flag.
==24468== The main thread stack size used in this run was 8388608.
==24468==
==24468== HEAP SUMMARY:
==24468== in use at exit: 371,641,698 bytes in 6,241,143 blocks
==24468== total heap usage: 6,241,190 allocs, 47 frees, 656,880,685 bytes allocated
==24468==
==24468== 16 bytes in 2 blocks are possibly lost in loss record 1 of 11
==24468== at 0x4C27965: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==24468== by 0x4028BC: populate_chunks(std::string&) (text_storage.cc:123)
==24468== by 0x402ADF: main (text_storage.cc:173)
==24468==
==24468== 43 bytes in 1 blocks are possibly lost in loss record 2 of 11
==24468== at 0x4C27965: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==24468== by 0x5340048: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.19)
==24468== by 0x5341900: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib64/libstdc++.so.6.0.19)
==24468== by 0x5341D37: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.19)
==24468== by 0x4029F7: main (text_storage.cc:138)
==24468==
==24468== 35,727,800 (33,173,592 direct, 2,554,208 indirect) bytes in 4,146,699 blocks are definitely lost in loss record 8 of 11
==24468== at 0x4C27965: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==24468== by 0x4028BC: populate_chunks(std::string&) (text_storage.cc:123)
==24468== by 0x402ADF: main (text_storage.cc:173)
==24468==
==24468== 93,350,023 bytes in 1 blocks are possibly lost in loss record 9 of 11
==24468== at 0x4C27965: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==24468== by 0x5340048: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.19)
==24468== by 0x5340235: std::string::_M_mutate(unsigned long, unsigned long, unsigned long) (in /usr/lib64/libstdc++.so.6.0.19)
==24468== by 0x53403C5: std::string::_M_leak_hard() (in /usr/lib64/libstdc++.so.6.0.19)
==24468== by 0x5340412: std::string::begin() (in /usr/lib64/libstdc++.so.6.0.19)
==24468== by 0x407728: boost::range_iterator<std::string>::type boost::range_detail::range_begin<std::string>(std::string&) (begin.hpp:49)
==24468== by 0x40705D: boost::range_iterator<std::string>::type boost::range_adl_barrier::begin<std::string>(std::string&) (begin.hpp:108)
==24468== by 0x4066FC: __gnu_cxx::__normal_iterator<char*, std::string> boost::iterator_range_detail::iterator_range_impl<__gnu_cxx::__normal_iterator<char*, std::string> >::adl_begin<std::string>(std::string&) (iterator_range_core.hpp:58)
==24468== by 0x40601A: boost::iterator_range<__gnu_cxx::__normal_iterator<char*, std::string> >::iterator_range<std::string>(std::string&, boost::iterator_range_detail::range_tag) (iterator_range_core.hpp:207)
==24468== by 0x40561F: boost::iterator_range<boost::range_iterator<std::string>::type> boost::make_iterator_range<std::string>(std::string&) (iterator_range_core.hpp:559)
==24468== by 0x404BC3: boost::iterator_range<boost::range_iterator<std::string>::type> boost::range_detail::make_range<std::string>(std::string&, long) (as_literal.hpp:93)
==24468== by 0x4040E5: boost::iterator_range<boost::range_iterator<std::string>::type> boost::as_literal<std::string>(std::string&) (as_literal.hpp:102)
==24468==
==24468== 93,351,904 bytes in 1 blocks are possibly lost in loss record 10 of 11
==24468== at 0x4C27965: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==24468== by 0x5340048: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.19)
==24468== by 0x5341710: char* std::string::_S_construct<char*>(char*, char*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib64/libstdc++.so.6.0.19)
==24468== by 0x531F9A7: std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::str() const (in /usr/lib64/libstdc++.so.6.0.19)
==24468== by 0x402523: stet::file::read() (file.cc:50)
==24468== by 0x402A2E: main (text_storage.cc:139)
==24468==
==24468== 129,441,960 bytes in 1,520,226 blocks are possibly lost in loss record 11 of 11
==24468== at 0x4C27965: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==24468== by 0x5340048: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.19)
==24468== by 0x40845E: char* std::string::_S_construct<__gnu_cxx::__normal_iterator<char*, std::string> >(__gnu_cxx::__normal_iterator<char*, std::string>, __gnu_cxx::__normal_iterator<char*, std::string>, std::allocator<char> const&, std::forward_iterator_tag) (basic_string.tcc:138)
==24468== by 0x4082E8: char* std::string::_S_construct_aux<__gnu_cxx::__normal_iterator<char*, std::string> >(__gnu_cxx::__normal_iterator<char*, std::string>, __gnu_cxx::__normal_iterator<char*, std::string>, std::allocator<char> const&, std::__false_type) (basic_string.h:1725)
==24468== by 0x408177: char* std::string::_S_construct<__gnu_cxx::__normal_iterator<char*, std::string> >(__gnu_cxx::__normal_iterator<char*, std::string>, __gnu_cxx::__normal_iterator<char*, std::string>, std::allocator<char> const&) (basic_string.h:1746)
==24468== by 0x407FDA: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<__gnu_cxx::__normal_iterator<char*, std::string> >(__gnu_cxx::__normal_iterator<char*, std::string>, __gnu_cxx::__normal_iterator<char*, std::string>, std::allocator<char> const&) (basic_string.tcc:229)
==24468== by 0x407D6A: std::string boost::copy_range<std::string, boost::iterator_range<__gnu_cxx::__normal_iterator<char*, std::string> > >(boost::iterator_range<__gnu_cxx::__normal_iterator<char*, std::string> > const&) (iterator_range_core.hpp:643)
==24468== by 0x407AEA: boost::algorithm::detail::copy_iterator_rangeF<std::string, __gnu_cxx::__normal_iterator<char*, std::string> >::operator()(boost::iterator_range<__gnu_cxx::__normal_iterator<char*, std::string> > const&) const (util.hpp:97)
==24468== by 0x407395: boost::transform_iterator<boost::algorithm::detail::copy_iterator_rangeF<std::string, __gnu_cxx::__normal_iterator<char*, std::string> >, boost::algorithm::split_iterator<__gnu_cxx::__normal_iterator<char*, std::string> >, boost::use_default, boost::use_default>::dereference() const (transform_iterator.hpp:121)
==24468== by 0x406B72: boost::transform_iterator<boost::algorithm::detail::copy_iterator_rangeF<std::string, __gnu_cxx::__normal_iterator<char*, std::string> >, boost::algorithm::split_iterator<__gnu_cxx::__normal_iterator<char*, std::string> >, boost::use_default, boost::use_default>::reference boost::iterator_core_access::dereference<boost::transform_iterator<boost::algorithm::detail::copy_iterator_rangeF<std::string, __gnu_cxx::__normal_iterator<char*, std::string> >, boost::algorithm::split_iterator<__gnu_cxx::__normal_iterator<char*, std::string> >, boost::use_default, boost::use_default> >(boost::transform_iterator<boost::algorithm::detail::copy_iterator_rangeF<std::string, __gnu_cxx::__normal_iterator<char*, std::string> >, boost::algorithm::split_iterator<__gnu_cxx::__normal_iterator<char*, std::string> >, boost::use_default, boost::use_default> const&) (iterator_facade.hpp:514)
==24468== by 0x40633D: boost::iterator_facade<boost::transform_iterator<boost::algorithm::detail::copy_iterator_rangeF<std::string, __gnu_cxx::__normal_iterator<char*, std::string> >, boost::algorithm::split_iterator<__gnu_cxx::__normal_iterator<char*, std::string> >, boost::use_default, boost::use_default>, std::string, boost::forward_traversal_tag, std::string, long>::operator*() const (iterator_facade.hpp:639)
==24468== by 0x405895: void std::vector<std::string, std::allocator<std::string> >::_M_range_initialize<boost::transform_iterator<boost::algorithm::detail::copy_iterator_rangeF<std::string, __gnu_cxx::__normal_iterator<char*, std::string> >, boost::algorithm::split_iterator<__gnu_cxx::__normal_iterator<char*, std::string> >, boost::use_default, boost::use_default> >(boost::transform_iterator<boost::algorithm::detail::copy_iterator_rangeF<std::string, __gnu_cxx::__normal_iterator<char*, std::string> >, boost::algorithm::split_iterator<__gnu_cxx::__normal_iterator<char*, std::string> >, boost::use_default, boost::use_default>, boost::transform_iterator<boost::algorithm::detail::copy_iterator_rangeF<std::string, __gnu_cxx::__normal_iterator<char*, std::string> >, boost::algorithm::split_iterator<__gnu_cxx::__normal_iterator<char*, std::string> >, boost::use_default, boost::use_default>, std::input_iterator_tag) (stl_vector.h:1188)
==24468==
==24468== LEAK SUMMARY:
==24468== definitely lost: 33,173,592 bytes in 4,146,699 blocks
==24468== indirectly lost: 2,554,208 bytes in 319,276 blocks
==24468== possibly lost: 316,143,946 bytes in 1,520,231 blocks
==24468== still reachable: 19,769,952 bytes in 254,937 blocks
==24468== suppressed: 0 bytes in 0 blocks
==24468== Reachable blocks (those to which a pointer was found) are not shown.
==24468== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==24468==
==24468== For counts of detected and suppressed errors, rerun with: -v
==24468== ERROR SUMMARY: 4146708 errors from 7 contexts (suppressed: 2 from 2)
The size of the lines array in a chunk is MAX_CHUNK_SIZE, but you are accessing it far beyond that on any iteration except the first.
Your loop is for(size_t i = 0; i < next_line_num; ++i), guess what next_line_num is on your second (and beyond) iteration?
You would probably have totally avoided this problem if you had thought of another problem, which you overlooked. You only partially fill the chunks (by 75%), which makes sense. But on the last iteration you are likely to have even less lines than those needed to fill 75% of a chunk. Therefore there should be, somewhere, a test to handle this boundary. A comparison, somewhere in that loop, with num_lines. Thinking about where to put it could (but not necessarily would) have alerted you that the iteration index is not doing what you expect.
Try for(size_t i = 0; i < START_CHUNK_SIZE && line_num+i < num_lines; ++i).
For reference, this is what the final code looks like:
std::vector<chunk *> populate_chunks(std::string &text) {
std::vector<std::string> all_lines;
boost::split(all_lines, text, boost::is_any_of("\n"));
size_t num_lines = all_lines.size();
std::vector<chunk *> chunks = std::vector<chunk *>( (num_lines / START_CHUNK_SIZE) * 2 );
for(size_t next_line_num, line_num = 0; line_num < num_lines; line_num = next_line_num) {
next_line_num = line_num + START_CHUNK_SIZE;
chunk *c = new chunk;
chunks.push_back(c);
for(size_t i = 0; i < std::min(static_cast<unsigned int>(START_CHUNK_SIZE), static_cast<unsigned int>(num_lines - line_num) ); ++i) {
line *l = new line;
l->text = all_lines[line_num+i];
c->lines[i] = l;
}
}
return chunks;
}

Potential pointer issue and Address is not stack'd, malloc'd or (recently) free'd

I am getting a segmentation fault on one of my programs and not sure why. I've ran a valgrind:
==7631== Memcheck, a memory error detector
==7631== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==7631== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==7631== Command: ./a.out wordsRMS.txt
==7631== Parent PID: 30431
==7631==
==7631== Use of uninitialised value of size 8
==7631== at 0x403C5C: std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> >::begin() const (in /root/test/a.out)
==7631== by 0x403D04: std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> >::size() const (in /root/test/a.out)
==7631== by 0x40328A: testNewWord(std::string const&, std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> >*) (in /root/test/a.out)
==7631== by 0x4038FE: main (in /root/test/a.out)
==7631==
==7631== Use of uninitialised value of size 8
==7631== at 0x403C86: std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> >::end() const (in /root/test/a.out)
==7631== by 0x403D11: std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> >::size() const (in /root/test/a.out)
==7631== by 0x40328A: testNewWord(std::string const&, std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> >*) (in /root/test/a.out)
==7631== by 0x4038FE: main (in /root/test/a.out)
==7631==
==7631== Use of uninitialised value of size 8
==7631== at 0x403C5C: std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> >::begin() const (in /root/test/a.out)
==7631== by 0x403D04: std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> >::size() const (in /root/test/a.out)
==7631== by 0x405E78: std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> >::_M_range_check(unsigned long) const (in /root/test/a.out)
==7631== by 0x405EAC: std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> >::at(unsigned long) (in /root/test/a.out)
==7631== by 0x402DD2: testNewWord(std::string const&, std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> >*) (in /root/test/a.out)
==7631== by 0x4038FE: main (in /root/test/a.out)
==7631==
==7631== Use of uninitialised value of size 8
==7631== at 0x403C86: std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> >::end() const (in /root/test/a.out)
==7631== by 0x403D11: std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> >::size() const (in /root/test/a.out)
==7631== by 0x405E78: std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> >::_M_range_check(unsigned long) const (in /root/test/a.out)
==7631== by 0x405EAC: std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> >::at(unsigned long) (in /root/test/a.out)
==7631== by 0x402DD2: testNewWord(std::string const&, std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> >*) (in /root/test/a.out)
==7631== by 0x4038FE: main (in /root/test/a.out)
==7631==
==7631== Use of uninitialised value of size 8
==7631== at 0x403D48: __gnu_cxx::__normal_iterator<PeekDeque<StringWrap>**, std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> > >::__normal_iterator(PeekDeque<StringWrap>** const&) (in /root/test/a.out)
==7631== by 0x403D6C: std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> >::begin() (in /root/test/a.out)
==7631== by 0x403DD2: std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> >::operator[](unsigned long) (in /root/test/a.out)
==7631== by 0x405EB9: std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> >::at(unsigned long) (in /root/test/a.out)
==7631== by 0x402DD2: testNewWord(std::string const&, std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> >*) (in /root/test/a.out)
==7631== by 0x4038FE: main (in /root/test/a.out)
==7631==
==7631== Invalid read of size 8
==7631== at 0x402DD3: testNewWord(std::string const&, std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> >*) (in /root/test/a.out)
==7631== by 0x4038FE: main (in /root/test/a.out)
==7631== Address 0x6c894ce02464894c is not stack'd, malloc'd or (recently) free'd
==7631==
==7631==
==7631== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==7631== General Protection Fault
==7631== at 0x402DD3: testNewWord(std::string const&, std::vector<PeekDeque<StringWrap>*, std::allocator<PeekDeque<StringWrap>*> >*) (in /root/test/a.out)
==7631== by 0x4038FE: main (in /root/test/a.out)
==7631==
==7631== HEAP SUMMARY:
==7631== in use at exit: 9,344 bytes in 5 blocks
==7631== total heap usage: 5 allocs, 0 frees, 9,344 bytes allocated
==7631==
==7631== 27 bytes in 1 blocks are possibly lost in loss record 1 of 5
==7631== at 0x4A0695E: operator new(unsigned long) (vg_replace_malloc.c:220)
==7631== by 0x33A9A9B860: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.8)
==7631== by 0x33A9A9C23A: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) (in /usr/lib64/libstdc++.so.6.0.8)
==7631== by 0x33A9A9CB44: std::string::reserve(unsigned long) (in /usr/lib64/libstdc++.so.6.0.8)
==7631== by 0x33A9A9CD5E: std::string::append(char const*, unsigned long) (in /usr/lib64/libstdc++.so.6.0.8)
==7631== by 0x33A9A76203: std::basic_istream<char, std::char_traits<char> >& std::operator>><char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&) (in /usr/lib64/libstdc++.so.6.0.8)
==7631== by 0x40390B: main (in /root/test/a.out)
==7631==
==7631== 37 bytes in 1 blocks are possibly lost in loss record 2 of 5
==7631== at 0x4A0695E: operator new(unsigned long) (vg_replace_malloc.c:220)
==7631== by 0x33A9A9B860: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.8)
==7631== by 0x33A9A9C364: ??? (in /usr/lib64/libstdc++.so.6.0.8)
==7631== by 0x33A9A9C511: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.8)
==7631== by 0x403873: main (in /root/test/a.out)
==7631==
==7631== LEAK SUMMARY:
==7631== definitely lost: 0 bytes in 0 blocks
==7631== indirectly lost: 0 bytes in 0 blocks
==7631== possibly lost: 64 bytes in 2 blocks
==7631== still reachable: 9,280 bytes in 3 blocks
==7631== suppressed: 0 bytes in 0 blocks
==7631== Reachable blocks (those to which a pointer was found) are not shown.
==7631== To see them, rerun with: --leak-check=full --show-reachable=yes
==7631==
==7631== For counts of detected and suppressed errors, rerun with: -v
==7631== Use --track-origins=yes to see where uninitialised values come from
==7631== ERROR SUMMARY: 8 errors from 8 contexts (suppressed: 4 from 4)
The line that seems to be of importance:
Address 0x6c894ce02464894c is not stack'd, malloc'd or (recently) free'd
However, I'm not quite sure what to make of this. Here is my code:
/** Add word to new or existing chain.
*/
void testNewWord(const string& word, vector<PeekDeque<StringWrap>* >* chains) {
bool foundChain = false;
// check to see if we can add word into EXISTING chain
for(std::vector<int>::size_type i = 0; i != chains->size(); i++) {
// check front of chain
if(ed1(StringWrap(word).str(), chains->at(i)->returnFront().str())) {
//cout << "The word has an edit distance 1 with the front item." << endl;
chains->at(i)->pushFront(StringWrap(word));
foundChain = true;
break;
}
// check rear of chain
if(ed1(StringWrap(word).str(), chains->at(i)->returnRear().str())) {
//cout << "The word has an edit distance 1 with the rear item." << endl;
chains->at(i)->pushRear(StringWrap(word));
foundChain = true;
break;
}
}
// otherwise create a NEW chain
if(!foundChain) {
PeekDeque<StringWrap>* newpd = new PeekDeque<StringWrap>(500);
newpd->pushFront(StringWrap(word));
chains->push_back(newpd);
}
}
int main(int argc, char* argv[]){
if(argc != 2){
cerr << "Please specify a SINGLE .txt file to generate word chains from." << '\n' << "Usage: ./PeekClientRMS /path/to/file.txt" << '\n';
return 1;
}
vector<PeekDeque<StringWrap>* >* chains;
string word;
string infileName = argv[1];
ifstream* INFILEp = new ifstream(infileName.c_str(), ios_base::in);
while ((*INFILEp) >> word) {
testNewWord(word, chains);
}
INFILEp->close();
/*for(std::vector<int>::size_type i = 0; i != chains->size(); i++) {
}*/
}
Interestingly enough, when I uncomment the for loop at the bottom of main(), my program runs?
/*for(std::vector<int>::size_type i = 0; i != chains->size(); i++) {
}*/
What could be going on here?
In the main function you declare a pointer to a vector, but you never make that pointer actually point anywhere. Uninitialized local variables have an indeterminate value (and it will seem to be random), and using those variables leads to undefined behavior.
In this case there's no need to use a pointer for the vector. Just declare it as a normal non-pointer variable, and pass it to the function as a reference.
Like
vector<PeekDeque<StringWrap>* > chains;
Then modify the function to take a reference:
void testNewWord(const string& word, vector<PeekDeque<StringWrap>* >& chains)
In fact, in C++ you should try to avoid pointers as much as possible, they are often not needed. I would actually urge you to not store pointers in the vector.
Your mistake is fundamental!
A pointer is no object, the chains is just holding an address to some memory, which is not the address of an object, not allocated and not initialized.
In C++ you should avoid needless allocations and prefer passing objects by value or reference:
vector< PeekDeque < StringWrap > >
void testNewWord(const string& word, vector< PeekDeque< StringWrap> >& chains);
If you allocate via new you should pair up with delete, too (or delegate to a smart pointer).
The ifstream* INFILEp = new ... is a memory leak and defeats proper destruction without a delete INFILEp - better (again): omit the pointer and just use ifstream INFILE(infileName.c_str());
The PeekDeque<StringWrap>* newpd = new PeekDeque is likely a memory leak, too.

Mac/C++/10.8: "Conditional jump or move depends on uninitialised value(s)" in dyld?

I am using valkrie/valgrind on Mac OS 10.8 to find memory leaks in a small testcase command line tool.
While I have been able to locate many problems successfully before, valgrind right now presents the following error to me of which I can't seem to make sense:
==69195== Conditional jump or move depends on uninitialised value(s)
==69195== at 0x3F68CF: ??? (in /usr/lib/system/libxpc.dylib)
==69195== by 0x11AC2F: ??? (in /usr/lib/libSystem.B.dylib)
==69195== by 0x8FE13CD9: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==69195== by 0x8FE13FDD: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==69195== by 0x8FE10267: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==69195== by 0x8FE101CB: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==69195== by 0x8FE100B9: ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==69195== by 0x8FE01DD8: dyld::initializeMainExecutable() (in /usr/lib/dyld)
==69195== by 0x8FE05ADA: dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**, unsigned long*) (in /usr/lib/dyld)
==69195== by 0x8FE01375: dyldbootstrap::start(macho_header const*, int, char const**, long, macho_header const*, unsigned long*) (in /usr/lib/dyld)
==69195== by 0x8FE01076: _dyld_start (in /usr/lib/dyld)
Usually valgrind's error traces touch my own code before they descend into library/system calls,
but in this case the error seems to occur in "dyld::initializeMainExecutable()", which is in a system linker library outside of my control.
Where could I look to fix this - is there another way to make sense of it?
Cheers+thanks y