11

我一直在尝试调试崩溃的应用程序中的崩溃(即断言 * glibc 检测到 * free():无效指针:0x000000000070f0c0 ***),而我正在尝试对字符串进行简单的分配。请注意,我正在使用 gcc 4.2.4 的 linux 系统上编译,优化级别设置为 -O2。使用 -O0 应用程序不再崩溃。

例如

std::string abc;

abc = "testString";

但是如果我按如下方式更改代码它不再崩溃

std::string abc("testString");

所以我又挠了挠头!但有趣的模式是崩溃在应用程序中稍后移动,再次出现在另一个字符串中。我发现应用程序在字符串分配上不断崩溃,这很奇怪。典型的崩溃回溯如下所示:

#0  0x00007f2c2663bfb5 in raise () from /lib64/libc.so.6
(gdb) bt
#0  0x00007f2c2663bfb5 in raise () from /lib64/libc.so.6
#1  0x00007f2c2663dbc3 in abort () from /lib64/libc.so.6
#2  0x00000000004d8cb7 in people_streamingserver_sighandler (signum=6) at src/peoplestreamingserver.cpp:487
#3  <signal handler called>
#4  0x00007f2c2663bfb5 in raise () from /lib64/libc.so.6
#5  0x00007f2c2663dbc3 in abort () from /lib64/libc.so.6
#6  0x00007f2c26680ce0 in ?? () from /lib64/libc.so.6
#7  0x00007f2c270ca7a0 in std::string::assign (this=0x7f2c21bc8d20, __str=<value optimized out>)
    at /home/bbazso/ThirdParty/sources/gcc-4.2.4/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:238
#8  0x00007f2c21bd874a in PEOPLESProtocol::GetStreamName (this=<value optimized out>,
    pRawPath=0x2342fd8 "rtmp://127.0.0.1/mp4:pop.mp4", lStreamName=@0x7f2c21bc8d20)
    at /opt/trx-HEAD/gcc/4.2.4/lib/gcc/x86_64-pc-linux-gnu/4.2.4/../../../../include/c++/4.2.4/bits/basic_string.h:491
#9  0x00007f2c21bd9daa in PEOPLESProtocol::SignalProtocolCreated (pProtocol=0x233a4e0, customParameters=@0x7f2c21bc8de0)
    at peoplestreamer/src/peoplesprotocol.cpp:240

这是非常奇怪的行为,所以我开始在我的应用程序中进一步查看是否存在某种可能导致这种奇怪行为的内存损坏(堆或堆栈)错误。我什至检查了 ptr 损坏并空手而归。除了对代码进行视觉检查之外,我还尝试了以下工具:

  • Valgrind 同时使用 memcheck 和 exp-ptrcheck
  • 电围栏
  • 安全库
  • 我在 gcc 中使用 -fstack-protector-all 编译
  • 我尝试将 MALLOC_CHECK_ 设置为 2
  • 我通过 lint 检查和 cppcheck 运行我的代码(检查错误)
  • 我使用 gdb 逐步完成了代码

所以我尝试了很多东西,但仍然空手而归。所以我想知道它是否可能是链接器问题或某种可能导致此问题的库问题。std::string 是否存在任何已知问题,使得 make 容易在 -O2 中崩溃,或者它可能与优化级别无关?但是到目前为止,我在我的问题中看到的唯一模式是它似乎总是在字符串上崩溃,所以我想知道是否有人知道我导致这种行为的任何问题。

非常感谢!

4

4 回答 4

10

这是使用我可以从您的回溯中提取的所有信息的初步猜测。

您很可能混合和匹配 gcc 版本、链接器和 libstdc++,导致主机上出现异常行为:

  1. libc 是系统的:/lib64/libc.so.6
  2. libstdc++ 位于“第三方”目录中——这是怀疑,因为它告诉我它可能会在其他地方用不同的目标编译——/home/bbazso/ThirdParty/sources/gcc-4.2.4/x86_64-pc-linux-gnu/libstdc++-v3/
  3. 另一个 libstdc++ 在/opt/opt/trx-HEAD/gcc/4.2.4/lib/gcc/x86_64-pc-linux-gnu/4.2.4/../../../../include/c++/4.2.4/bits/basic_string.h:491

此外,GCC 可能会混合系统的 ld 而不是本身,这可能会导致更奇怪的内存映射使用。

于 2010-02-20T21:24:53.953 回答
7

你能用一个基本的两行程序重复崩溃吗?

#include <string>

int main()
{
    std::string abc;
    abc = "testString";
}

如果崩溃,请发布您的确切编译/链接选项?

如果没有,请开始缩减您的代码。一次删除几行,直到错误消失。一旦您进行了一些其他更改,您可以添加以导致崩溃并删除以使其消失,这应该可以帮助您找到问题。

于 2010-02-20T21:18:05.030 回答
2

发生在我身上是因为将 malloc 用于具有 std::strings 作为数据成员的类。棘手。

于 2015-10-19T09:17:45.527 回答
0

正如你所说,这是一种奇怪的行为。

老实说,我认为您正在浪费时间研究 std::strings 的可能错误。只要您使用得当,字符串是绝对安全的。

无论如何,根据您提供的信息:首先,您是否使用线程?可能是线程问题。其次,您使用 valgrind 检查您的程序。你根本没有警告吗?

注意:最关键的 valgrind 警告是无效读取和无效写入。

PS:正如评论中所说,您可能应该使用 g++ 编译 C++ 代码;)

于 2010-02-20T21:29:21.677 回答