gpt4 book ai didi

c++ - 有时只会出现 jni segv_accer 或 segv_mapper 错误

转载 作者:行者123 更新时间:2023-11-27 23:37:14 25 4
gpt4 key购买 nike

我有以下 C++ 代码,它由网络服务器通过 JNI 调用。

 static shared_ptr<multimap<string,SomeObject> > cacheMap;

void Cache::refresh(multimap<string, SomeObject> delta){

shared_ptr<multimap<string, SomeObject> > old_cache=atomic_exchange(&cacheMap,make_shared<multimap<string,SomeObject> >(delta));

shared_ptr<multimap<string, SomeObject> > old_readMap=atomic_load(&old_cache);
if(old_readMap){
for(std::multimap<string, SomeObject>::iterator it = old_readMap->begin(); it != old_readMap->end(); it++){
it->second.getSomeObject()->~SomeObject();
}
old_readMap->clear();
}
}


list<int> Cache::get(string key1,const char* key2){

SomeObject value;
list<int> IDs;
try{
shared_ptr<multimap<string,SomeObject> > readMap=atomic_load(&cacheMap);
pair<mapIterator,mapIterator> result=readMap->equal_range(key1);
for(auto iterator=result.first; iterator!=result.second; iterator++){
value=iterator->second;
if(!(value.getSomeObject()->test(key2,strlen(key2)))){
IDs.push_front(value.getInternalID());
}
}

}
catch(...){
std::exception_ptr p = std::current_exception();
std::clog <<(p ? p.__cxa_exception_type()->name() : "null") << " from Cache.cpp " << std::endl;
}
return IDs;
}

cacheMap 将由 cronjob 每 5 分钟刷新一次,请求线程通过 get() 不断访问缓存。这是一个多线程环境。一切正常,3 或 4 天后,我收到此 SEGV_ACCER/SEGV_MAPPER 错误,转储如下所示(转储中的几行)

# Problematic frame:
# C [libstdc++.so.6+0xd7172] std::string::assign(std::string const&)+0x12

...

Stack: [0x00007fed854c2000,0x00007fed855c3000], sp=0x00007fed855c08b0, free space=1018k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [libstdc++.so.6+0xd7172] std::string::assign(std::string const&)+0x12
C [libCustomCache.so+0x1c0b0] Cache::get(std::string, char const*)+0x122

我已经使用shared_ptr 和原子操作来保证线程安全,但仍然出现这个错误。关于如何调试这个的任何想法?

最佳答案

Cache::refreshCache::get 竞相同时销毁和读取同一个 SomeObject 对象。这是一种竞争条件。

std::shared_ptr 的原子指针或原子用法在这里仅使指针的值成为原子的和无竞争的,而不是指针所指的对象。

一种可靠的方法是使用 C++17 std::shared_mutex或 C++14 boost::shared_mutex允许读者并发访问缓存,而只允许作者独占访问。

您还应该消除手动销毁 SomeObject 的需要。

例子:

using namespace std;

namespace {

shared_mutex m;
multimap<string, SomeObject> cacheMap; // SomeObject doesn't need to be manually destroyed.

} // namespace

void Cache::refresh(multimap<string, SomeObject> delta){
std::unique_lock lock(m); // Writer exclusive lock.
cacheMap = std::move(delta);
}

list<int> Cache::get(string const& key1, const char* key2) {
list<int> IDs;
std::shared_lock lock(m); // Readers shared lock.
for(auto result = readMap->equal_range(key1); result.first != result.second; ++result.first) {
auto&& value = *result.first;
if(!(value.getSomeObject()->test(key2, strlen(key2))))
IDs.push_front(value.getInternalID());
}
return IDs;
}

关于c++ - 有时只会出现 jni segv_accer 或 segv_mapper 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58400915/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com