deepfryed / beanstalk-client

C/C++ beanstalk client
59 stars 44 forks source link

Memory issues with reconnect #25

Open wimrijnders opened 10 years ago

wimrijnders commented 10 years ago

I ran valgrind on my application and several issues popped up involving Beanstalk::Client::reconnect(). I will put the report in a separate post in this issue.

I'm not entirely sure how to fix this, but I did notice the following when looking at the code.

When looking at the code, I notice that strings are passed by value. eg:

Client::Client(string host, int port, float secs) {
...
void Client::connect(string _host, int _port, float secs) {

In addition, in reconnect(), connect is called with the member values of host, port and float secs already stored in the instance, which values are then again used to set the exact members passed.

void Client::connect(string _host, int _port, float secs) {
...
    host         = _host;
    port         = _port;
    timeout_secs = secs;
...
}
...
 void Client::reconnect() {
    disconnect();
    connect(host, port, timeout_secs);
}

This looks like a roundabout way of reconnecting and might be improved by using const string referemces. Since these methods are exactly where the memory issues occur as reported by valgrind, cleaning up might go some way to solve them.

wimrijnders commented 10 years ago

Here is the valgrind report. stacktraces have been shortened to the relevant part.

==640== Reachable blocks (those to which a pointer was found) are not shown.
==640== To see them, rerun with: --leak-check=full --show-reachable=yes
==640== 
==640== For counts of detected and suppressed errors, rerun with: -v
==640== ERROR SUMMARY: 13 errors from 11 contexts (suppressed: 0 from 0)
==25455== Memcheck, a memory error detector
==25455== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==25455== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==25455== Command: /home/wri/projects/memtest master master /home/wri/projects/memtest/test/init/bin/system.ini
==25455== Invalid read of size 4
==25455==    at 0x5B605EB: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x589D6F5: Beanstalk::Client::reconnect() (beanstalk.cc:114)
==25455== 
==25455==  Address 0xdf00570 is 16 bytes inside a block of size 34 free'd
==25455==    at 0x4C2B1BF: operator delete(void*) (vg_replace_malloc.c:480)
==25455==    by 0x5B5F51E: std::basic_string<char, std::char_traits<char>, std::allocator<char>>::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x589D2E4: Beanstalk::Client::~Client() (beanstalk.cc:64)
==25455== 
==25455== Invalid read of size 8
==25455==    at 0x5B5FF8F: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x5B6061B: std::basic_string<char, std::char_traits<char>, std::allocator<char>>::basic_string(std::string const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x589D6F5: Beanstalk::Client::reconnect() (beanstalk.cc:114)
==25455==  Address 0xdf00560 is 0 bytes inside a block of size 34 free'd
==25455==    at 0x4C2B1BF: operator delete(void*) (vg_replace_malloc.c:480)
==25455==    by 0x5B5F51E: std::basic_string<char, std::char_traits<char>, std::allocator<char>>::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x589D2E4: Beanstalk::Client::~Client() (beanstalk.cc:64)
==25455== 
==25455== Invalid read of size 8
==25455==    at 0x5B5FF92: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x5B6061B: std::basic_string<char, std::char_traits<char>, std::allocator<char>>::basic_string(std::string const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x589D6F5: Beanstalk::Client::reconnect() (beanstalk.cc:114)
==25455==  Address 0xdf00568 is 8 bytes inside a block of size 34 free'd
==25455==    at 0x4C2B1BF: operator delete(void*) (vg_replace_malloc.c:480)
==25455==    by 0x5B5F51E: std::basic_string<char, std::char_traits<char>, std::allocator<char>>::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x589D2E4: Beanstalk::Client::~Client() (beanstalk.cc:64)
==25455== 
==25455== Invalid read of size 8
==25455==    at 0x5B5FF9B: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x5B6061B: std::basic_string<char, std::char_traits<char>, std::allocator<char>>::basic_string(std::string const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x589D6F5: Beanstalk::Client::reconnect() (beanstalk.cc:114)
==25455==  Address 0xdf00560 is 0 bytes inside a block of size 34 free'd
==25455==    at 0x4C2B1BF: operator delete(void*) (vg_replace_malloc.c:480)
==25455==    by 0x5B5F51E: std::basic_string<char, std::char_traits<char>, std::allocator<char>>::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455== 
==25455== Invalid read of size 1
==25455==    at 0x4C2E241: memcpy@@GLIBC_2.14 (mc_replace_strmem.c:877)
==25455==    by 0x5B5FFBF: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x5B6061B: std::basic_string<char, std::char_traits<char>, std::allocator<char>>::basic_string(std::string const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x589D6F5: Beanstalk::Client::reconnect() (beanstalk.cc:114)
==25455==  Address 0xdf00580 is 32 bytes inside a block of size 34 free'd
==25455==    at 0x4C2B1BF: operator delete(void*) (vg_replace_malloc.c:480)
==25455==    by 0x5B5F51E: std::basic_string<char, std::char_traits<char>, std::allocator<char>>::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x589D2E4: Beanstalk::Client::~Client() (beanstalk.cc:64)
==25455== 
==25455== Invalid read of size 8
==25455==    at 0x4C2E268: memcpy@@GLIBC_2.14 (mc_replace_strmem.c:877)
==25455==    by 0x5B5FFBF: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x5B6061B: std::basic_string<char, std::char_traits<char>, std::allocator<char>>::basic_string(std::string const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x589D6F5: Beanstalk::Client::reconnect() (beanstalk.cc:114)
==25455==  Address 0xdf00578 is 24 bytes inside a block of size 34 free'd
==25455==    at 0x4C2B1BF: operator delete(void*) (vg_replace_malloc.c:480)
==25455==    by 0x5B5F51E: std::basic_string<char, std::char_traits<char>, std::allocator<char>>::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x589D2E4: Beanstalk::Client::~Client() (beanstalk.cc:64)
==25455== 
==25455== Invalid read of size 8
==25455==    at 0x5B5FFC0: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x5B6061B: std::basic_string<char, std::char_traits<char>, std::allocator<char>>::basic_string(std::string const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x589D6F5: Beanstalk::Client::reconnect() (beanstalk.cc:114)
==25455==  Address 0xdf00560 is 0 bytes inside a block of size 34 free'd
==25455==    at 0x4C2B1BF: operator delete(void*) (vg_replace_malloc.c:480)
==25455==    by 0x5B5F51E: std::basic_string<char, std::char_traits<char>, std::allocator<char>>::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x589D2E4: Beanstalk::Client::~Client() (beanstalk.cc:64)
==25455== 
==25455== Invalid read of size 4
==25455==    at 0x5B5F4C7: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x5B606B8: std::string::assign(std::string const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x589D4DB: Beanstalk::Client::connect(std::string, int, float) (beanstalk.cc:87)
==25455==    by 0x589D70F: Beanstalk::Client::reconnect() (beanstalk.cc:114)
==25455==  Address 0xdf00570 is 16 bytes inside a block of size 34 free'd
==25455==    at 0x4C2B1BF: operator delete(void*) (vg_replace_malloc.c:480)
==25455==    by 0x5B5F51E: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x589D2E4: Beanstalk::Client::~Client() (beanstalk.cc:64)
==25455== 
==25455== Invalid free() / delete / delete[] / realloc()
==25455==    at 0x4C2B1BF: operator delete(void*) (vg_replace_malloc.c:480)
==25455==    by 0x5B606B8: std::string::assign(std::string const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x589D4DB: Beanstalk::Client::connect(std::string, int, float) (beanstalk.cc:87)
==25455==    by 0x589D70F: Beanstalk::Client::reconnect() (beanstalk.cc:114)
==25455==  Address 0xdf00560 is 0 bytes inside a block of size 34 free'd
==25455==    at 0x4C2B1BF: operator delete(void*) (vg_replace_malloc.c:480)
==25455==    by 0x5B5F51E: std::basic_string<char, std::char_traits<char>, std::allocator<char>>::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x589D2E4: Beanstalk::Client::~Client() (beanstalk.cc:64)
==25455== 
==25455== 
==25455== HEAP SUMMARY:
==25455==     in use at exit: 10,394 bytes in 6 blocks
==25455==   total heap usage: 21,949,552 allocs, 21,949,547 frees, 139,313,317,856 bytes allocated
==25455== 
==25455== 34 bytes in 1 blocks are definitely lost in loss record 1 of 6
==25455==    by 0x426181: main (main.cpp:53)
==25455== 
==25455== 
==25455== HEAP SUMMARY:
==25455==     in use at exit: 10,394 bytes in 6 blocks
==25455==   total heap usage: 21,949,552 allocs, 21,949,547 frees, 139,313,317,856 bytes allocated
==25455== 
==25455== 34 bytes in 1 blocks are definitely lost in loss record 1 of 6
==25455==    at 0x4C2C154: operator new(unsigned long) (vg_replace_malloc.c:298)
==25455==    by 0x5B5F3C8: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x5B5FF9A: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x5B6061B: std::basic_string<char, std::char_traits<char>, std::allocator<char>>::basic_string(std::string const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==25455==    by 0x589D6F5: Beanstalk::Client::reconnect() (beanstalk.cc:114)
==25455== 
==25455== LEAK SUMMARY:
==25455==    definitely lost: 34 bytes in 1 blocks
==25455==    indirectly lost: 0 bytes in 0 blocks
==25455==      possibly lost: 0 bytes in 0 blocks
==25455==    still reachable: 10,360 bytes in 5 blocks
==25455==         suppressed: 0 bytes in 0 blocks
==25455== Reachable blocks (those to which a pointer was found) are not shown.
==25455== To see them, rerun with: --leak-check=full --show-reachable=yes
==25455== 
==25455== For counts of detected and suppressed errors, rerun with: -v
==25455== ERROR SUMMARY: 12 errors from 10 contexts (suppressed: 0 from 0)