[英]gdb shows weird stack trace
I have a C++ daemon which segfaults after few days of work. 我有一个C ++守护程序,经过几天的工作后它会出现段错误。 I compiled it with debug options (I'm sure I did it well, because I tested it with premeditated crashes and gdb showed correct stack trace), but in "real" crash on production I see only following trace:
我使用调试选项对其进行了编译(我确信我做得很好,因为我已经过预先测试的崩溃进行了测试,并且gdb显示了正确的堆栈跟踪),但是在生产中出现的“真正”崩溃中,我仅看到以下跟踪:
(gdb) where
#0 0x00007ffff674d5a7 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#1 0xffffffffffffffff in ?? ()
#2 0x0000000000000000 in ?? ()
What does it mean? 这是什么意思?
The following source code has potential issue, because it is the only new code since daemon become unstable: 以下源代码有潜在的问题,因为这是守护程序变得不稳定以来唯一的新代码:
namespace Foo {
Bar* Bar::instance = NULL;
Bar* Bar::getInstance() {
if (!instance)
instance = new Bar();
return instance;
}
Bar::Bar() {
curl = curl_easy_init();
if(CURLE_OK != curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &data_write)
|| CURLE_OK != curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L)
|| CURLE_OK != curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L)
|| CURLE_OK != curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, Bar::timeout)) {
throw std::runtime_error(std::string("Can't initialize curl."));
}
}
Bar::~Bar() {
curl_easy_cleanup(curl);
}
std::string Bar::getByIp(const std::string &id) {
Bar *self = getInstance();
std::string url = "example.com";
url.append(id);
std::ostringstream oss;
if (CURLE_OK == self->curl_read(url, oss)) {
std::string output(oss.str());
if (output.empty())
return NULL_OBJECT;
TiXmlDocument xml;
xml.Parse(output.c_str());
if (
xml.Error()
|| !xml.FirstChild("a")
|| !xml.FirstChild("a")->FirstChild("b")
|| !xml.FirstChild("a")->FirstChild("b")->FirstChildElement("lat")
|| !xml.FirstChild("a")->FirstChild("b")->FirstChildElement("lng")
)
return NULL_OBJECT;
std::string lat = xml.FirstChild("a")->FirstChild("b")->FirstChildElement("lat")->GetText();
std::string lng = xml.FirstChild("a")->FirstChild("b")->FirstChildElement("lng")->GetText();
return Region::getByCoordinates(lng, lat);
}
return NULL_OBJECT;
}
size_t Bar::data_write(void* buf, size_t size, size_t nmemb, void* userp)
{
if(userp)
{
std::ostream& os = *static_cast<std::ostream*>(userp);
std::streamsize len = size * nmemb;
if(os.write(static_cast<char*>(buf), len))
return len;
}
return 0;
}
CURLcode Bar::curl_read(const std::string& url, std::ostringstream& os)
{
CURLcode code(CURLE_FAILED_INIT);
if(curl)
{
if(
CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_FILE, &os))
&& CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_URL, url.c_str()))
) {
code = curl_easy_perform(curl);
}
}
return code;
}
}
Shouldn't the second if in your getByIp(...) method look like this? 应该不是第二,如果你getByIp(...)方法这个样子的?
if (xml.Error()
|| !xml.FirstChild("a")
|| !xml.FirstChild("a")->FirstChild("b")
|| !xml.FirstChild("a")->FirstChild("b")->FirstChildElement("lat")
|| !xml.FirstChild("a")->FirstChild("b")->FirstChildElement("lng")) // <- added missing parenthesis
{ // <- added
std::string lat = xml.FirstChild("a")->FirstChild("b")->FirstChildElement("lat")->GetText();
std::string lng = xml.FirstChild("a")->FirstChild("b")->FirstChildElement("lng")->GetText();
return Region::getByCoordinates(lng, lat);
} // <- added
If you are indeed missing the curly braces, you might be dereferencing invalid pointers when you retrieve the lng string, because its retrieval is then not a part of the conditional statement. 如果确实缺少花括号,则在检索lng字符串时,您可能会取消引用无效的指针,因为那样,对它的检索就不再是条件语句的一部分。
It looks like a memory corruption affecting the stack: writing outside of the allocated memory. 它看起来像是影响堆栈的内存损坏:在分配的内存之外进行写操作。
You can write a little program to exercise your Bar class the same way your daemon does, possibly in a loop. 您可以编写一个小程序来以与守护程序相同的方式练习Bar类,可能是在循环中。 You can also run this program with MALLOC_CHECK_ , electric fence , Valgrind or any other memory checking tool.
您也可以使用MALLOC_CHECK_ , 电围栏 ,Valgrind或任何其他内存检查工具运行该程序。
It could be curl, TiXmlDocument, or the code calling your class. 它可以是curl,TiXmlDocument或调用您的类的代码。
I expect you have a few issues with pointers. 我希望您在使用指针时遇到一些问题。 As StackTrace #0 shows a function within libc.so.6 that does not have a name.
正如StackTrace#0所示,libc.so.6中的函数没有名称。 And #1 has a NULL -1 pointer.
#1具有NULL -1指针。 We need a lot more to help you fix your bug.
我们需要更多帮助您修复错误的信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.