简体   繁体   中英

STL vector.clear() cause memory double free or corruption is pthreads program

Here is code snippet:

pthread_mutex_lock(&hostsmap_mtx);
for (int i = 0; i < service_hosts[service].size(); ++i)
    poolmanager->delPool(service, service_hosts[service][i].first);

service_hosts[service].clear();
for (int i = 0; i < servers->count; ++i) {
    string temp(servers->data[i]);
    int pos = temp.find(':');
    string server = temp.substr(0, pos);
    string port = temp.substr(pos + 1, temp.length() - pos - 1);
    service_hosts[service].push_back(make_pair(server, atoi(port.c_str())));

    config.server = server;
    config.port = atoi(port.c_str());

    poolmanager->addPool(service, config);
}

pthread_mutex_unlock(&hostsmap_mtx);

The type of service_hosts is map<string, vector<pair<string, int> > >

Crash reason:
* Error in './HttpProxy': double free or corruption (fasttop): 0x00007f6fe000a6b0 *

And GDB bt:

5  ~basic_string (this=0x7f6fe0000960, __in_chrg=<optimized out>)
    at /usr/include/c++/4.8.3/bits/basic_string.h:539  
6  ~pair (this=0x7f6fe0000960, __in_chrg=<optimized out>)
    at /usr/include/c++/4.8.3/bits/stl_pair.h:96  
7  _Destroy<std::pair<std::basic_string<char>, int> > (__pointer=0x7f6fe0000960)
    at /usr/include/c++/4.8.3/bits/stl_construct.h:93  
8  __destroy<std::pair<std::basic_string<char>, int>*> (__last=<optimized out>,
    __first=0x7f6fe0000960) at /usr/include/c++/4.8.3/bits/stl_construct.h:103  
9  _Destroy<std::pair<std::basic_string<char>, int>*> (__last=<optimized out>,
    __first=<optimized out>) at /usr/include/c++/4.8.3/bits/stl_construct.h:126  
10 _Destroy<std::pair<std::basic_string<char>, int>*, std::pair<std::basic_string<char>, int> > (
    __last=0x7f6fe0000970, __first=0x7f6fe0000960)
    at /usr/include/c++/4.8.3/bits/stl_construct.h:151  
11 _M_erase_at_end (this=<optimized out>, __pos=0x7f6fe0000960)
    at /usr/include/c++/4.8.3/bits/stl_vector.h:1352  
12 clear (this=0x7f6fe000a0f8) at /usr/include/c++/4.8.3/bits/stl_vector.h:1126  

Any advice would be grateful.

Double frees are very easy to diagnose using valgrind (or any other similar tool you have access to). It will tell you who freed the memory you are accessing which will lead you to the root of the problem. If you have problems reading the valgrind output post it here and we can help you out.

This problem may not be easy to find out the root cause.But finally I find out the reason.Cause stl string is not thread safe and stl string assignment is reference-count and COW. Eg:

string str = "stl::string";
string temp = str; //this is ref-count,COW
string temp2 = str.c_str(); //this is memory copy, cause string don't know how to handle const char *, just copy it

My fix is to pass const char * to stl vecotrs, and use const char * as function parameter in multithreading condition and if there is a contention. Eg:

map<string, vector<pair<string, int> > > Hostmap;
string service = "service";
string host = "host";
//Note: not service and host, but service.c_str() and host.c_str()
Hostmap[service.c_str()].push_back(make_pair(host.c_str(), 9966));

Hope this question will provide some hint to the problem you encountered.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM