Understanding an issue reported by valgrind - c++

I consistently get this trace shown by valgrind. This is an aarch64 system. I want to know if there is anything I can do within my limits to fix this problem, as explained below -
Invalid read of size 8 is at lh_delete by ERR_remove_thread_state (in libcrypto) by soap_free (in gsoap) ? There is no relation as far as I know between these two.
Invalid read by a function in libcrypto, attempts to read 8 bytes that has been freed again by libcrypto. Block itself was also allocated by libcrypto. I have been reading about issues with the version of libcrypto I have. https://curl.se/mail/lib-2016-08/0137.html. I don't think I will be able to upgrade the libcrypto package as that will affect lots of places within the codebase.
What can I do as an alternative ?
==15163== Invalid read of size 8
==15163== at 0x4B5931C: lh_delete (in /usr/lib/libcrypto.so.1.0.0)
==15163== by 0x4B5CF5F: ??? (in /usr/lib/libcrypto.so.1.0.0)
==15163== by 0x4B5DE53: ERR_remove_thread_state (in /usr/lib/libcrypto.so.1.0.0)
==15163== by 0x5915BC7: soap_free (in /opt/MyC/lib/libjci_gsoap.so)
==15163== by 0x672DFF: ??? (in /opt/MyC/bin/MyProg)
==15163== by 0x616D3B: ??? (in /opt/MyC/bin/MyProg)
==15163== by 0x61AAD7: ??? (in /opt/MyC/bin/MyProg)
==15163== by 0x61B69B: ??? (in /opt/MyC/bin/MyProg)
==15163== by 0x61159B: ??? (in /opt/MyC/bin/MyProg)
==15163== by 0x60CB93: ??? (in /opt/MyC/bin/MyProg)
==15163== by 0x60E08B: ??? (in /opt/MyC/bin/MyProg)
==15163== by 0x60D6FF: ??? (in /opt/MyC/bin/MyProg)
==15163== Address 0x6e69b28 is 8 bytes inside a block of size 24 free'd
==15163== at 0x4849A00: free (vg_replace_malloc.c:538)
==15163== by 0x4AE3F0B: CRYPTO_free (in /usr/lib/libcrypto.so.1.0.0)
==15163== by 0x4B59337: lh_delete (in /usr/lib/libcrypto.so.1.0.0)
==15163== by 0x4B5CF5F: ??? (in /usr/lib/libcrypto.so.1.0.0)
==15163== by 0x4B5DE53: ERR_remove_thread_state (in /usr/lib/libcrypto.so.1.0.0)
==15163== by 0x50999B: ??? (in /opt/MyC/bin/MyProg)
==15163== by 0x50A473: ??? (in /opt/MyC/bin/MyProg)
==15163== by 0x50B437: ??? (in /opt/MyC/bin/MyProg)
==15163== by 0x5044CF: ??? (in /opt/MyC/bin/MyProg)
==15163== by 0x506433: ??? (in /opt/MyC/bin/MyProg)
==15163== by 0x50834F: ??? (in /opt/MyC/bin/MyProg)
==15163== by 0x5069B3: ??? (in /opt/MyC/bin/MyProg)
==15163== Block was alloc'd at
==15163== at 0x4848798: malloc (vg_replace_malloc.c:307)
==15163== by 0x4AE3BEB: CRYPTO_malloc (in /usr/lib/libcrypto.so.1.0.0)
==15163== by 0x4B5928F: lh_insert (in /usr/lib/libcrypto.so.1.0.0)
==15163== by 0x4B5CD23: ??? (in /usr/lib/libcrypto.so.1.0.0)
==15163== by 0x4B5E017: ERR_get_state (in /usr/lib/libcrypto.so.1.0.0)
==15163== by 0x4B5E46B: ERR_put_error (in /usr/lib/libcrypto.so.1.0.0)
==15163== by 0x4B61B13: EVP_DecryptFinal_ex (in /usr/lib/libcrypto.so.1.0.0)
==15163== by 0x49CBCD3: users::User::decrypt(int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (in /opt/MyC/lib/libuserdatabase.so)
==15163== by 0x49D19DB: users::User::authenticatePassword(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (in /opt/MyC/lib/libuserdatabase.so)
==15163== by 0x532D01F: Security::authenticate(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /opt/MyC/lib/libonvif_utils.so)
==15163== by 0x504437: ??? (in /opt/MyC/bin/MyProg)
==15163== by 0x506433: ??? (in /opt/MyC/bin/MyProg)

Related

Invalid write of size 1, Address 0x... is not stack'd, malloc'd or (recently) free'd (Valgrind)

I've tried to change the code to do what I want in different ways but doesn't seem to fix that Valgrind error.
Cadena::Cadena(unsigned tam, char c):s_(new char[tam+1]), tam_(tam)
{
//c is ' ' by default
memset(s_, c, tam+1);
s_[tam]='\0';
}
...
Cadena& Cadena::substr(unsigned i, unsigned tam) const
{
if(i>=tam_||i+tam>tam_) throw out_of_range("Posicion indicada fuera de rango");
Cadena* subCad=new Cadena(tam);
strncpy(subCad->s_, &s_[i], tam);
return *subCad;
}
==9669== Invalid write of size 1
==9669== at 0x1390CC: Cadena::Cadena(unsigned int, char) (in /mnt/hgfs/mvpoosf/P1/test-P1-auto)
==9669== by 0x13972B: Cadena::substr(unsigned int, unsigned int) const (in /mnt/hgfs/mvpoosf/P1/test-P1-auto)
==9669== by 0x12D436: test_cadena(_fctkern_t*) (in /mnt/hgfs/mvpoosf/P1/test-P1-auto)
==9669== by 0x137D42: main (in /mnt/hgfs/mvpoosf/P1/test-P1-auto)
==9669== Address 0x105bc176f is not stack'd, malloc'd or (recently) free'd
==9669==
==9669==
==9669== Process terminating with default action of signal 11 (SIGSEGV)
==9669== Access not within mapped region at address 0x105BC176F
==9669== at 0x1390CC: Cadena::Cadena(unsigned int, char) (in /mnt/hgfs/mvpoosf/P1/test-P1-auto)
==9669== by 0x13972B: Cadena::substr(unsigned int, unsigned int) const (in /mnt/hgfs/mvpoosf/P1/test-P1-auto)
==9669== by 0x12D436: test_cadena(_fctkern_t*) (in /mnt/hgfs/mvpoosf/P1/test-P1-auto)
==9669== by 0x137D42: main (in /mnt/hgfs/mvpoosf/P1/test-P1-auto)
==9669== If you believe this happened as a result of a stack
==9669== overflow in your program's main thread (unlikely but
==9669== possible), you can try to increase the size of the
==9669== main thread stack using the --main-stacksize= flag.
==9669== The main thread stack size used in this run was 8388608.
Another way:
Cadena& Cadena::substr(unsigned i, unsigned tam) const
{
if(i>=tam_||i+tam>tam_) throw out_of_range("Posicion indicada fuera de rango");
char res[tam+1];
strncpy(res, s_+i, tam);
res[tam]='\0';
Cadena* subCad=new Cadena(tam);
return *subCad;
}
==17029== Invalid write of size 1
==17029== at 0x4C3304C: strncpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==17029== by 0x13979E: Cadena::substr(unsigned int, unsigned int) const (in /mnt/hgfs/mvpoosf/P1/test-P1-auto)
==17029== Address 0x1fff001000 is not stack'd, malloc'd or (recently) free'd
==17029==
==17029==
==17029== Process terminating with default action of signal 11 (SIGSEGV)
==17029== Access not within mapped region at address 0x1FFF001000
==17029== at 0x4C3304C: strncpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==17029== by 0x13979E: Cadena::substr(unsigned int, unsigned int) const (in /mnt/hgfs/mvpoosf/P1/test-P1-auto)
==17029== If you believe this happened as a result of a stack
==17029== overflow in your program's main thread (unlikely but
==17029== possible), you can try to increase the size of the
==17029== main thread stack using the --main-stacksize= flag.
==17029== The main thread stack size used in this run was 8388608.
I'm passing this test (test-P1-auto):
FCT_TEST_BGN(Cadena - Subcadena: tamanno mayor que longitud restante) {
const Cadena a("0123456789");
fct_chk_ex(out_of_range&, a.substr(9, 2));
}
FCT_TEST_END();
It returns a substring of two elements following the number 8. It's not possible as it throws out_of_range, so the test is OK. But when I use Valgrind, it's giving me those errors and I've been stuck here for hours.
Private part of my class Cadena:
private:
char* s_;
unsigned int tam_;
Sorry for the mistake guys, but as #Some programmer dude commented I didn't put the flag -g on my makefile that allows valgrind to tell me wich lines make the errors. Actually that wasn't the right test, it was the next one:
FCT_TEST_BGN(Cadena - Subcadena: tamanno negativo) {
const Cadena a("0123456789");
fct_chk_ex(out_of_range&, a.substr(9, -1));
}
FCT_TEST_END();
As I can see here Signed to unsigned conversion in C - is it always safe?, there's no way to get a negative value as unsigned and expect the sign "just to be removed". I solved it by changing it to int and checking inside the function if it's negative.
Thanks everyone for your help.

why does valgrind detect uninitialised values only so late

I want to understand the valgrind log messages and use the following code
#include <iostream>
int main()
{
int numbers[] = {1,2,3,4,5,6,7,8,9,10};
int length = sizeof(numbers) / sizeof(numbers[0]);
std::cout << "length: " << length << std::endl;
for (int i = 0; i < length + 10; ++i)
{
int number = numbers[i];
if (number > 5)
{
std::cout << number << " is greater than 5" << std::endl;
} else {
std::cout << number << " is less or equal 5" << std::endl;
}
}
}
to produce uninitialised values. If I run the program in valgrind I don't receive a corresponding message. If I run the for-loop to length + 10 valgrind detects uninitialised values.
Why does valgrind detect the unitialised values only so late?
==2484== Conditional jump or move depends on uninitialised value(s)
==2484== at 0x108A3C: main (arrays.cpp:11)
==2484== Uninitialised value was created by a stack allocation
==2484== at 0x51E6ABB: (below main) (libc-start.c:137)
==2484==
==2484== Conditional jump or move depends on uninitialised value(s)
==2484== at 0x4F43C0A: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484== by 0x4F501A4: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484== by 0x108A85: main (arrays.cpp:15)
==2484== Uninitialised value was created by a stack allocation
==2484== at 0x51E6ABB: (below main) (libc-start.c:137)
==2484==
==2484== Use of uninitialised value of size 8
==2484== at 0x4F4370E: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484== by 0x4F43C33: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484== by 0x4F501A4: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484== by 0x108A85: main (arrays.cpp:15)
==2484== Uninitialised value was created by a stack allocation
==2484== at 0x51E6ABB: (below main) (libc-start.c:137)
==2484==
==2484== Conditional jump or move depends on uninitialised value(s)
==2484== at 0x4F4371B: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484== by 0x4F43C33: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484== by 0x4F501A4: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484== by 0x108A85: main (arrays.cpp:15)
==2484== Uninitialised value was created by a stack allocation
==2484== at 0x51E6ABB: (below main) (libc-start.c:137)
==2484==
==2484== Conditional jump or move depends on uninitialised value(s)
==2484== at 0x4F43C66: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484== by 0x4F501A4: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484== by 0x108A85: main (arrays.cpp:15)
==2484== Uninitialised value was created by a stack allocation
==2484== at 0x51E6ABB: (below main) (libc-start.c:137)
EDIT: I changed the code. THis is the whole code i used.
compile: g++ -c -g3 arrays.cpp arrays.cpp
valgrind: valgrind --tool=memcheck --track-origins=yes --num-callers=100 --log-file=uv_log.txt ./arrays
EDIT 2:
length: 10
1 is less or equal 5
2 is less or equal 5
3 is less or equal 5
4 is less or equal 5
5 is less or equal 5
6 is greater than 5
7 is greater than 5
8 is greater than 5
9 is greater than 5
10 is greater than 5
-882498304 is less or equal 5
-188984184 is less or equal 5
1084208 is greater than 5
0 is less or equal 5
85879703 is greater than 5
0 is less or equal 5
0 is less or equal 5
You don't actually check for uninitialized access. You check for index out of bounds access. In your case, the out of bounds access is on the stack, so you access some memory, which is on the stack. And you're lucky, because the whole accessed area is on the stack, so you don't get an invalid read. Your program reads some data of the stack, which happens to be initialized for the length+1 case (because there is some other thing written to it, for example, it can be function parameter, other local variable or the function's return address), so valgrind is not able to report any error.
But for the length+10 case, it is large enough to actually read from some uninitialized memory. And I bet, if you increase 10 to a much larger number, you'll get invalid read (which causes segmentation fault).

malloc() memory corruption by writing an int array only for a specific amount

I have a memory corruption in my code given as
*** Error in `./match': malloc(): memory corruption: 0x0000000001036470 ***
Aborted (core dumped)
Strangely this happens not before having an input of about 30-40 elements.
Since I couldn't figure out what's going on I did some research and read that valgrind is a good choice. I'm very new into this so I ran valgrind via two options (not sure the one makes sense) which points at subsequent code lines:
void match(vector<APD> apdvec_database, const char* OUTPUTFILE, bool EXTRACT_APD_VALUE)
{
(...)
const int N = apdvec_database.size();
vector<vector<double> > cost (N, vector<double>(N,0));
(...)
// Calculate amount of edges
double number=0;
double n=N;
double k=2;
number=binom(n, k);
// convert edges
int node_num;
long int edge_num;
int* edges;
double* weights;
node_num=N;
edge_num=(int)number;
[line 561:] edges = new int[2*edge_num];
weights = new double[edge_num];
cout << "\t\t " << node_num << " APDs and " << edge_num << " edges calculated" << endl;
int e=0;
for(size_t i = 0; i<apdvec_database.size(); i++)
{
for(size_t j = 0; j<apdvec_database.size(); j++)
{
if(i!=j)
{
// Assign edges among themselves
[line 575:] edges[2*e] = (int)i;
edges[2*e+1] = (int)j;
// Use only triangular matrix with diagonals
if(j>i){ weights[e] = (double)cost[i][j];}
else{ if((int)+(int)j<node_num) weights[e] = (double)cost[i][j]; }
e++;
}
}
}
Due to the output I marked two specific lines via [line] at the beginning: The output is:
valgrind options: --tool=memcheck --leak-check=yes
==24195== at 0x40D5CE: match(std::vector<APD, std::allocator<APD> >, char const*, bool) (match.cpp:575)
==24195== by 0x410866: main (match.cpp:680)
==24195== Address 0x8be5a38 is 0 bytes after a block of size 11,448 alloc'd
==24195== at 0x4C2B800: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24195== by 0x40D4A6: match(std::vector<APD, std::allocator<APD> >, char const*, bool) (match.cpp:561)
==24195== by 0x410866: main (match.cpp:680)
==24195==
==24195== Invalid write of size 4
==24195== at 0x40D5D2: match(std::vector<APD, std::allocator<APD> >, char const*, bool) (match.cpp:576)
==24195== by 0x410866: main (match.cpp:680)
==24195== Address 0x8be5a3c is 4 bytes after a block of size 11,448 alloc'd
==24195== at 0x4C2B800: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24195== by 0x40D4A6: match(std::vector<APD, std::allocator<APD> >, char const*, bool) (match.cpp:561)
==24195== by 0x410866: main (match.cpp:680)
==24195==
==24195== Invalid write of size 8
==24195== at 0x40D607: match(std::vector<APD, std::allocator<APD> >, char const*, bool) (match.cpp:580)
==24195== by 0x410866: main (match.cpp:680)
==24195== Address 0x158e86c8 is 0 bytes after a block of size 11,448 alloc'd
==24195== at 0x4C2B800: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24195== by 0x40D4D3: match(std::vector<APD, std::allocator<APD> >, char const*, bool) (match.cpp:562)
==24195== by 0x410866: main (match.cpp:680)
==24195==
==24195== Invalid write of size 8
==24195== at 0x40D5EA: match(std::vector<APD, std::allocator<APD> >, char const*, bool) (match.cpp:579)
==24195== by 0x410866: main (match.cpp:680)
==24195== Address 0x158e87a0 is 128 bytes inside a block of size 184 free'd
==24195== at 0x4C2C2BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24195== by 0x508A5B8: THashList::Delete(char const*) (THashList.cxx:199)
==24195== by 0x5515ACF: TDirectoryFile::Close(char const*) (TDirectoryFile.cxx:562)
==24195== by 0x550A549: TFile::Close(char const*) (TFile.cxx:935)
==24195== by 0x410623: database_irradiated(char const*, bool, std::vector<APD, std::allocator<APD> >&, double&) (match.cpp:317)
==24195== by 0x410820: main (match.cpp:655)
==24195==
valgrind options: -fno-inline
==23041== Invalid write of size 4
==23041== at 0x416D17: match(std::vector<APD, std::allocator<APD> >, char const*, bool) (in /home/ben/analysis/APDs/match/Combine/match)
==23041== by 0x417AA9: main (in /home/ben/analysis/APDs/match/Combine/match)
==23041== Address 0x8be5a38 is 0 bytes after a block of size 11,448 alloc'd
==23041== at 0x4C2B800: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23041== by 0x416C6E: match(std::vector<APD, std::allocator<APD> >, char const*, bool) (in /home/ben/analysis/APDs/match/Combine/match)
==23041== by 0x417AA9: main (in /home/ben/analysis/APDs/match/Combine/match)
==23041==
==23041== Invalid write of size 4
==23041== at 0x416D1B: match(std::vector<APD, std::allocator<APD> >, char const*, bool) (in /home/ben/analysis/APDs/match/Combine/match)
==23041== by 0x417AA9: main (in /home/ben/analysis/APDs/match/Combine/match)
==23041== Address 0x8be5a3c is 4 bytes after a block of size 11,448 alloc'd
==23041== at 0x4C2B800: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23041== by 0x416C6E: match(std::vector<APD, std::allocator<APD> >, char const*, bool) (in /home/ben/analysis/APDs/match/Combine/match)
==23041== by 0x417AA9: main (in /home/ben/analysis/APDs/match/Combine/match)
==23041==
==23041== Invalid write of size 8
==23041== at 0x416D72: match(std::vector<APD, std::allocator<APD> >, char const*, bool) (in /home/ben/analysis/APDs/match/Combine/match)
==23041== by 0x417AA9: main (in /home/ben/analysis/APDs/match/Combine/match)
==23041== Address 0x158e86c8 is 0 bytes after a block of size 11,448 alloc'd
==23041== at 0x4C2B800: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23041== by 0x416C9B: match(std::vector<APD, std::allocator<APD> >, char const*, bool) (in /home/ben/analysis/APDs/match/Combine/match)
==23041== by 0x417AA9: main (in /home/ben/analysis/APDs/match/Combine/match)
==23041==
==23041== Invalid write of size 8
==23041== at 0x416D45: match(std::vector<APD, std::allocator<APD> >, char const*, bool) (in /home/ben/analysis/APDs/match/Combine/match)
==23041== by 0x417AA9: main (in /home/ben/analysis/APDs/match/Combine/match)
==23041== Address 0x158e87a0 is 128 bytes inside a block of size 184 free'd
==23041== at 0x4C2C2BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23041== by 0x508A5B8: THashList::Delete(char const*) (THashList.cxx:199)
==23041== by 0x5515ACF: TDirectoryFile::Close(char const*) (TDirectoryFile.cxx:562)
==23041== by 0x550A549: TFile::Close(char const*) (TFile.cxx:935)
==23041== by 0x417901: database_irradiated(char const*, bool, std::vector<APD, std::allocator<APD> >&, double&) (in /home/ben/analysis/APDs/match/Combine/match)
==23041== by 0x417A6D: main (in /home/ben/analysis/APDs/match/Combine/match)
==23041==
Interestingly via valgrind the program does not get stuck resp. does not throw a malloc() and instead it even ends successfully with reasonable output.
I obviously forget to comment further here: Nevertheless, I had to declare each variable clearly. Probably there was a conflict because I included Cern ROOT framework. But this was then solved anyhow by declaring each variable with care.

Can valgrind report a memory address of a lost block (for debugging recursive function calls)?

This question is the most similar to mine, but it's rather old, so I wonder if anything has changed since then.
The valgrind output for me is:
==29443== 109 (16 direct, 93 indirect) bytes in 2 blocks are definitely lost in loss record 270 of 309
==29443== at 0x4C2B0E0: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==29443== by 0x4F4E8DB: grl::Configuration::Configuration(grl::Configuration const&) (configuration.h:192)
==29443== by 0x4F49973: grl::YAMLConfigurator::load(YAML::Node const&, grl::Configuration*, std::string const&) (configurable.cpp:74)
==29443== by 0x4F499FC: grl::YAMLConfigurator::load(YAML::Node const&, grl::Configuration*, std::string const&) (configurable.cpp:75)
==29443== by 0x4F499FC: grl::YAMLConfigurator::load(YAML::Node const&, grl::Configuration*, std::string const&) (configurable.cpp:75)
==29443== by 0x4F499FC: grl::YAMLConfigurator::load(YAML::Node const&, grl::Configuration*, std::string const&) (configurable.cpp:75)
==29443== by 0x40C78E: grl::YAMLConfigurator::load(std::string, grl::Configuration*, std::string const&) (configurable.h:321)
==29443== by 0x40B897: main (deployer.cpp:180)
Program is configured at the start with recursive calls of reading from yaml file and storing all required parameters in a map as a pair (name, allocated address). I can print these pairs. Therefore, if valgrind could tell me an address of lost values then I could get a name of a parameter and check why it is not freed.
If the functionality is not possible, what else can I use?
You can run your program under valgrind+gdb, using vgdb.
See http://www.valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver
Then you can use various valgrind memcheck monitor commands to do
leak search and have the addresses/sizes of leaked blocks.
See http://www.valgrind.org/docs/manual/mc-manual.html#mc-manual.monitor-commands

Why is my shared_ptr leaking memory?

I am trying to use C++11's std::tr1::shared_ptr to manage SDL_Surface pointers. Note, I am not using Boost. I have defined a deleter for the shared_ptr to use SDL_FreeSurface.
Declared like:
class Engine {
private:
std::tr1::shared_ptr<SDL_Surface> _scr;
std::tr1::shared_ptr<SDL_Surface> _bg;
Defined (in Engine's ctor) like:
_scr = std::tr1::shared_ptr<SDL_Surface>( SDL_SetVideoMode(Data::SCR_WIDTH,
Data::SCR_HEIGHT,
32, SDL_SWSURFACE),
SurfaceDeleter<SDL_Surface>());
_bg = std::tr1::shared_ptr<SDL_Surface>(IMG_Load(Data::IM_BACKGROUND),
SurfaceDeleter<SDL_Surface>());
The custom deleter:
template<typename T>
class SurfaceDeleter{
public:
void operator() (T*& d) const {
if(d){
SDL_FreeSurface(d);
}
}
};
The only object holding the shared_ptr is the Engine. The shared_ptr was used like so:
SDL_BlitSurface(_bg.get(), nullptr, _scr.get(), nullptr);
SDL_Flip(_scr.get());
Valgrind results:
==3648== 8 bytes in 2 blocks are definitely lost in loss record 16 of 292
==3648== at 0x402A018: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3648== by 0x431FBE0: strdup (in /lib/libc-2.14.1.so)
==3648== 1 bytes in 1 blocks are definitely lost in loss record 1 of 292
==3648== at 0x402A018: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3648== by 0x494A590: _XlcDefaultMapModifiers (in /usr/lib/libX11.so.6.3.0)
==3648== by 0x494A99A: XSetLocaleModifiers (in /usr/lib/libX11.so.6.3.0)
==3648== by 0x4097CDB: ??? (in /usr/lib/libSDL-1.2.so.0.11.3)
==3648== by 0x4083868: SDL_VideoInit (in /usr/lib/libSDL-1.2.so.0.11.3)
==3648== by 0x40594D9: SDL_InitSubSystem (in /usr/lib/libSDL-1.2.so.0.11.3)
==3648== by 0x42C3212: (below main) (in /lib/libc-2.14.1.so)
==3648== 980 (68 direct, 912 indirect) bytes in 1 blocks are definitely lost in loss record 258 of 292
==3648== at 0x402A102: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3648== by 0x49402A6: ??? (in /usr/lib/libX11.so.6.3.0)
==3648== by 0x49407A2: ??? (in /usr/lib/libX11.so.6.3.0)
==3648== by 0x494212F: ??? (in /usr/lib/libX11.so.6.3.0)
==3648== by 0x49429BA: _XlcCreateLC (in /usr/lib/libX11.so.6.3.0)
==3648== by 0x4965957: _XlcUtf8Loader (in /usr/lib/libX11.so.6.3.0)
==3648== by 0x494A793: _XOpenLC (in /usr/lib/libX11.so.6.3.0)
==3648== by 0x494A8F1: _XlcCurrentLC (in /usr/lib/libX11.so.6.3.0)
==3648== by 0x4097CDB: ??? (in /usr/lib/libSDL-1.2.so.0.11.3)
==3648== by 0x4083868: SDL_VideoInit (in /usr/lib/libSDL-1.2.so.0.11.3)
==3648== by 0x40594D9: SDL_InitSubSystem (in /usr/lib/libSDL-1.2.so.0.11.3)
==3648== by 0x42C3212: (below main) (in /lib/libc-2.14.1.so)
Run valgrind with --track-origins=yes so it shows you where the leaked memory was allocated.
You might also want to use --leak-check=full and --leak-resolution=high (although the latter should be the default)