【问题标题】:llvm-gcc std::allocator bug?llvm-gcc std::allocator 错误?
【发布时间】:2010-11-13 14:52:54
【问题描述】:

代码:

#include <vector>
#include <stack>
using namespace std;

class blub {};
class intvec : public std::vector<int, std::allocator<int> >, public blub {};

int main()
{
  std::stack<int, intvec> s;
}

同时使用 g++ (4.4.3) 和 llvm-g++ (4.2.1) 编译,但后一个 seg 的输出错误:

$ g++ main.cc && ./a.out
$ llvm-g++ main.cc && ./a.out
Segmentation fault

这似乎是释放未分配的东西的问题。这是 llvm-gcc 的错误吗?

更新:根据 llvm 邮件列表上的讨论,看起来这是一个错误,无论是在 llvm-gcc 还是它的 STL 实现中,都已在新版本中修复。但是,我没有费心从他们的存储库中安装和构建 llvm-gcc 来找出答案。

【问题讨论】:

  • 您可以通过将问题发布到 LLVM 邮件列表来更快地获得解决方案。
  • 从没有虚拟析构函数的类继承是不好的。您应该尝试组合并报告结果。
  • @DeadMG:这难道不是只有我们做Blub *b = new intvec; delete b;吗?
  • @DeadMG:这不是 OOP 代码,也不是 IS-A 继承。这是通用编程代码。在 GP 范例中,继承用于与 OOP 完全不同的目的。从具有非虚拟析构函数的类继承绝对没有错。它做了很多。它是 GP 中一个成熟且广泛使用的成语。事实上,在这里引入虚拟析构函数通常会完全破坏意图。
  • 它根本没有“坏习惯”。只是有些人出于某种原因喜欢抛弃“你需要一个虚拟析构函数”这个固定规则,而不了解首先发生了什么。

标签: c++ stl segmentation-fault allocator llvm-gcc


【解决方案1】:

好的。所以我在 Ubuntu 10.10 x64 上运行了它,我看到了分段错误。这里有一些细节。总的来说,我的总结似乎是这是编译器中的一个错误。 (请注意,我不是最初的提问者,我只是能够重现他的结果)。

我也将此转发到 llvm 邮件列表http://lists.cs.uiuc.edu/pipermail/llvmdev/2010-November/036231.html


wlynch@green:/tmp$ llvm-g++ --version
llvm-g++ (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
wlynch@green:/tmp$ llvm-g++ -O0 -g main.cc && ./a.out 
Segmentation fault
wlynch@green:/tmp$ llvm-g++ -O3 -g main.cc && ./a.out 
Segmentation fault

(gdb) bt
#0  0x00007ffff780aa75 in *__GI_raise (sig=<value optimized out>)                                                                at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1  0x00007ffff780e5c0 in *__GI_abort ()                                                                                         at abort.c:92
#2  0x00007ffff78444fb in __libc_message (do_abort=<value optimized out>, fmt=<value optimized out>)                             at ../sysdeps/unix/sysv/linux/libc_fatal.c:189
#3  0x00007ffff784e5b6 in malloc_printerr (action=3, str=0x7ffff791ead3 "free(): invalid pointer", ptr=<value optimized out>)    at malloc.c:6266
#4  0x00007ffff7854e83 in *__GI___libc_free (mem=<value optimized out>)                                                          at malloc.c:3738
#5  0x0000000000401476 in __gnu_cxx::new_allocator<int>::deallocate (this=0x7fffffffe5a8, __p=0x62c000, unnamed_arg=4)           at include/c++/4.2.1/ext/new_allocator.h:97
#6  0x00000000004014b1 in std::_Vector_base<int, std::allocator<int> >::_M_deallocate (this=0x7fffffffe5a8, __p=0x62c000, __n=4) at include/c++/4.2.1/bits/stl_vector.h:146
#7  0x00000000004014fe in std::_Vector_base<int, std::allocator<int> >::~_Vector_base (this=0x7fffffffe5a8)                      at include/c++/4.2.1/bits/stl_vector.h:132
#8  0x00000000004017cf in std::vector<int, std::allocator<int> >::~vector (this=0x7fffffffe5a8)                                  at include/c++/4.2.1/bits/stl_vector.h:287
#9  0x0000000000401886 in intvec::~intvec (this=0x7fffffffe5a8)                                                                  at main.cc:6
#10 0x00000000004018a4 in std::stack<int, intvec>::~stack (this=0x7fffffffe5a8)                                                  at include/c++/4.2.1/bits/stl_stack.h:99
#11 0x0000000000400c01 in main ()                                                                                                at main.cc:10

我们还得到了一个无效指针的释放。从追溯来看这是有道理的。


wlynch@green:/tmp$ valgrind ./a.out 
==4644== Memcheck, a memory error detector
==4644== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==4644== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==4644== Command: ./a.out
==4644== 
==4644== Invalid free() / delete / delete[]
==4644==    at 0x4C270BD: free (vg_replace_malloc.c:366)
==4644==    by 0x401475: __gnu_cxx::new_allocator<int>::deallocate(int*, unsigned long) (new_allocator.h:97)
==4644==    by 0x4014B0: std::_Vector_base<int, std::allocator<int> >::_M_deallocate(int*, unsigned long) (stl_vector.h:146)
==4644==    by 0x4014FD: std::_Vector_base<int, std::allocator<int> >::~_Vector_base() (stl_vector.h:132)
==4644==    by 0x4017CE: std::vector<int, std::allocator<int> >::~vector() (stl_vector.h:287)
==4644==    by 0x401885: intvec::~intvec() (main.cc:6)
==4644==    by 0x4018A3: std::stack<int, intvec>::~stack() (stl_stack.h:99)
==4644==    by 0x400C00: main (main.cc:10)
==4644==  Address 0x5433000 is not stack'd, malloc'd or (recently) free'd
==4644== 
==4644== 
==4644== HEAP SUMMARY:
==4644==     in use at exit: 1 bytes in 1 blocks
==4644==   total heap usage: 1 allocs, 1 frees, 1 bytes allocated
==4644== 
==4644== LEAK SUMMARY:
==4644==    definitely lost: 1 bytes in 1 blocks
==4644==    indirectly lost: 0 bytes in 0 blocks
==4644==      possibly lost: 0 bytes in 0 blocks
==4644==    still reachable: 0 bytes in 0 blocks
==4644==         suppressed: 0 bytes in 0 blocks
==4644== Rerun with --leak-check=full to see details of leaked memory
==4644== 
==4644== For counts of detected and suppressed errors, rerun with: -v
==4644== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)

我稍微减少了测试用例。我实际上倾向于这是一个 STL 实现错误,而不是编译器错误。

#include <vector>

class blub {};
class intvec : public std::vector<int>, public blub {};

int main() {
    intvec d;
    intvec e(d);
}

【讨论】:

    【解决方案2】:

    要弄清楚实际发生了什么,请尝试使用-g 标志进行编译以启用调试信息,然后运行valgrind ./a.out 以获取发生段错误的堆栈跟踪。

    【讨论】:

      【解决方案3】:

      对我来说没有段错误,你使用的是什么平台?

      macmini:stackoverflow samm$ llvm-g++ --version
      llvm-g++ (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build)
      Copyright (C) 2007 Free Software Foundation, Inc.
      This is free software; see the source for copying conditions.  There is NO
      warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
      
      macmini:stackoverflow samm$ cat stack.cc
      #include <vector>
      #include <stack>
      using namespace std;
      
      class blub {};
      class intvec : public std::vector<int, std::allocator<int> >, public blub {};
      
      int main()
      {
        std::stack<int, intvec> s;
      }
      macmini:stackoverflow samm$ llvm-g++ -g stack.cc 
      macmini:stackoverflow samm$ ./a.out
      macmini:stackoverflow samm$ echo $?
      0
      macmini:stackoverflow samm$ 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-14
        • 1970-01-01
        • 1970-01-01
        • 2017-06-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多