curl_easy_在Linux上执行分段错误
curl_easy_perform segmentation fault on Linux
我正在开发一个c++应用程序,该应用程序使用curl来处理HTTP GET请求。它在Windows上运行得很好,但在Linux(CentOS 7(上,当使用curl_easy_cleanup时,我会遇到分段错误。
下面是我的代码
CURL* curl = NULL;
curl = curl_easy_init();
if (curl == NULL)
{
this->getBitsLibrary()->writeToLog("Failed to init curl");
this->getBitsLibrary()->setAlarm("CrashInfo", Alarms::AlarmLevel::Critical, "Failed to init curl for IP lookup");
return;
}
stringstream urlstream;
string iplookupURL;
//curlResponse = "";
urlstream << StaticSettings::IP_Lookup::ipLookupURL << "/" << clientIP << "?access_key="<<StaticSettings::IP_Lookup::api_key;
iplookupURL = urlstream.str();
logstream << "Using URL " << iplookupURL << " for IP lookup";
this->getBitsLibrary()->writeToLog(logstream.str(), "CrashInfo", "performIPLookup");
logstream.clear();
logstream.str(string());
//string response = "";
this->curlResponse = new string();
curl_easy_setopt(curl, CURLOPT_URL, iplookupURL.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)this);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &curlStaticCallback);
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK)
{
logstream << "Failed to perform IP lookup using curl";
this->getBitsLibrary()->writeToLog(logstream.str(), "CrashInfo", "performIPLookup");
this->getBitsLibrary()->setAlarm("CrashInfo", Alarms::AlarmLevel::Warning, "Failed to perform IP Lookup. Curl error");
curl_easy_cleanup(curl);
return;
}
int httpResponseCode = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpResponseCode);
if (httpResponseCode == 200)
{
if (!this->curlResponse->empty())
{
this->getBitsLibrary()->writeToLog("Processing response for IP lookup");
rapidjson::Document jsonObject;
jsonObject.Parse(this->curlResponse->c_str());
const rapidjson::Value& countryValue = jsonObject["country_name"];
if (!countryValue.IsNull())
{
string country = string(jsonObject["country_name"].GetString());
this->setCountry(!country.empty() ? country : "N/A");
}
else
{
this->setCountry("N/A");
}
const rapidjson::Value& cityValue = jsonObject["city"];
if (!cityValue.IsNull())
{
string city = string(jsonObject["city"].GetString());
this->setCity(!city.empty() ? city : "N/A");
}
else
{
this->setCity("N/A");
}
this->getBitsLibrary()->writeToLog("IPLookup performed successfully", "CrashInfo", "performIPLookup");
}
delete this->curlResponse;
this->curlResponse = NULL;
curl_easy_cleanup(curl);
由于curl是一个C库,我创建了一个静态函数(在C++类之外(,如下所示:
size_t curlStaticCallback(void *contents, size_t size, size_t nmemb, void * userp)
{
CrashInfo *crashInfo = (CrashInfo*)userp;
crashInfo->curlResponseWriteCallback(contents, size, nmemb, userp);
return size * nmemb;
}
上面的静态函数由curl中的WRITEFUNCTION调用。我得到类对象,然后调用C++函数,如下所示:
size_t CrashInfo::curlResponseWriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
curlResponse->append((char*)contents, size * nmemb);
return size * nmemb;
}
如上所述,这在Windows上运行得很好,但在Linux上,当我得到预期的响应URL时,它运行得很不错,但当调用curl_easy_cleanup
时,我会得到一个包含以下堆栈的分段错误:
#0 0x00007fe7f45ff2ad in ?? () from /lib64/libstdc++.so.6
#1 0x00007fe7f4661c03 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() () from /lib64/libstdc++.so.6
#2 0x000000000043f773 in WebManager::CrashInfo::performIPLookup (this=0x7fe7d00020d0, clientIP="192.168.1.96") at CrashInfo.cpp:732
#3 0x000000000043aeb0 in WebManager::CrashInfo::processCrashInfo (this=0x7fe7d00020d0, httpRequest=0x7fe7d00008f0) at CrashInfo.cpp:308
#4 0x00000000004396ee in WebManager::CrashInfo::CrashInfo (this=0x7fe7d00020d0, httpRequest=0x7fe7d00008f0) at CrashInfo.cpp:50
#5 0x000000000046ce23 in WebManager::WebProcessor::processWebSocketData (this=0x7fe7ed841a60, clientpointer=0x7fe7e40008c0, ipAddress=0x7fe7ed8426b8 "192.168.1.96") at WebProcessor.cpp:71
#6 0x0000000000473bd6 in std::_Mem_fn<void (WebManager::WebProcessor::*)(void*, char*)>::operator()<int*, char*, void>(WebManager::WebProcessor*, int*&&, char*&&) const (this=0x7fe7e4000948, __object=0x7fe7ed841a60)
at /usr/include/c++/4.8.2/functional:601
#7 0x00000000004739fd in std::_Bind_simple<std::_Mem_fn<void (WebManager::WebProcessor::*)(void*, char*)> (WebManager::WebProcessor*, int*, char*)>::_M_invoke<0ul, 1ul, 2ul>(std::_Index_tuple<0ul, 1ul, 2ul>) (this=0x7fe7e4000930)
at /usr/include/c++/4.8.2/functional:1732
#8 0x00000000004737fd in std::_Bind_simple<std::_Mem_fn<void (WebManager::WebProcessor::*)(void*, char*)> (WebManager::WebProcessor*, int*, char*)>::operator()() (this=0x7fe7e4000930) at /usr/include/c++/4.8.2/functional:1720
#9 0x000000000047372e in std::thread::_Impl<std::_Bind_simple<std::_Mem_fn<void (WebManager::WebProcessor::*)(void*, char*)> (WebManager::WebProcessor*, int*, char*)> >::_M_run() (this=0x7fe7e4000918)
at /usr/include/c++/4.8.2/thread:115
#10 0x00007fe7f4659070 in ?? () from /lib64/libstdc++.so.6
#11 0x00007fe7f3aaae25 in start_thread () from /lib64/libpthread.so.0
#12 0x00007fe7f3dbdbad in clone () from /lib64/libc.so.6
我已经在GDB中查看了Curl的内存位置,看看是否有什么意外的权限/损坏了它,但看起来没有任何问题。
我已经发现了问题,这是一个相当奇怪的问题。正如Michael Doubez在评论中所说,它并没有直接卷曲。我认为它是curl,因为堆栈轨迹中的第二行指向curl_easy_cleanup,然后最上面一行是字符串析构函数,所以认为它是卷曲的。
我在curl_easy_cleanup之后放了一条日志行,它成功地记录了日志,然后崩溃了。curl_easy_cleanup是该方法中的最后一个调用,当函数完成时,崩溃发生了。
最后,我注释掉了整个函数,然后慢慢地重新添加它的块,以确定它是在什么时候导致崩溃的。
它最终成为线路curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpResponseCode);
。当函数想要一个指向long的指针时,我正在传递一个指向int的指针。
我纠正了上面的错误,现在一切都如预期的那样工作,不完全确定为什么这没有1,引发了一个编译器警告,那就是我传入了错误的类型,2,为什么堆栈跟踪显示一个字符串被破坏。
- GCC:随机构建导致执行期间分段错误
- 在 c++ 中执行 BFS 时出现分段错误
- 甚至在开始执行之前出现分段错误
- curl_easy_在Linux上执行分段错误
- 为什么我在执行main之前就出现分段错误(核心转储)
- 尝试运行可执行文件时出现分段错误
- 为什么我的编译器在执行此代码时出现分段错误?
- 不执行的代码会导致分段错误吗?
- 执行 N >= 10^7 的代码时出现分段错误(核心转储)错误
- 执行结束时QT QTest分段故障
- Unix可执行文件上的Mac分段错误,文件编译正常
- 是否可以执行范围添加更新,将线性函数添加到最大分段树中
- C++ Sqlite3 中,执行 2 个 sql 语句 - 第 2 条语句得到分段核心转储错误
- 执行 CUDA 程序时分段错误
- 在 c++ 中执行递归时出现分段错误
- 执行C++程序时出现分段错误(核心转储)错误
- 分段错误执行方法
- Q应用程序执行分段错误
- C++:执行"push_back"后分段故障 11
- 执行结束时出现分段错误(核心转储)