Bug In Module::getConstantPointerRef ?

I was about to post a bug concerning this, but I thought I'd check with
you folks first. The symptom is a SIGSEGV in my program in the standard
library template for red black trees (bits/stl_tree.h). The crash occurs
as the result of an LLVM Module method, getConstantPointerRef which
looks like:

// Accessor for the underlying GlobalValRefMap...
ConstantPointerRef *Module::getConstantPointerRef(GlobalValue *V){
  // Create ref map lazily on demand...
  if (GVRefMap == 0) GVRefMap = new GlobalValueRefMap();
  GlobalValueRefMap::iterator I = GVRefMap->Map.find(V);
  if (I != GVRefMap->Map.end()) return I->second;
  ConstantPointerRef *Ref = new ConstantPointerRef(V);
  GVRefMap->Map[V] = Ref;
  return Ref;

I have verified that my GlobalValue* parameter is valid. The crash
happens during the call to GVRefMap->Map.find(V). The code looks okay to
me on visual inspection but it does produce a crash.

When I debug it, I get this stack trace:

(gdb) where
#0 0x080b480b in std::_Rb_tree<llvm::GlobalValue*, std::pair<llvm::GlobalValue* const, llvm::ConstantPointerRef*>, std::_Select1st<std::pair<llvm::GlobalValue* const, llvm::ConstantPointerRef*> >, std::less<llvm::GlobalValue*>, std::allocator<std::pair<llvm::GlobalValue* const, llvm::ConstantPointerRef*> > >
     ::find(llvm::GlobalValue* const&) (this=0x4022d36c, __k=@0xbfffcc44) at stl_tree.h:1268
#1 0x080b35bc in std::map<llvm::GlobalValue*, llvm::ConstantPointerRef*, std::less<llvm::GlobalValue*>, std::allocator<std::pair<llvm::GlobalValue* const, llvm::ConstantPointerRef*> > >
    ::find(llvm::GlobalValue* const&) (this=0x4022d36c, __x=@0xbfffcc44) at stl_map.h:468
#2 0x08067d6d in llvm::Module::getConstantPointerRef(llvm::GlobalValue*) (this=0x81d4348, V=0x81d34f8) at /proj/work/llvm/llvm/lib/VMCore/Module.cpp:320
#3 0x08060497 in llvm::ConstantPointerRef::get(llvm::GlobalValue*) (GV=0x81d34f8) at /proj/work/llvm/llvm/lib/VMCore/Constants.cpp:908

Looking deeper, I noticed that the _M_header field of the red black tree
is null:

(gdb) p *GVRefMap
$22 = {Map = {
    _M_t = {<_Rb_tree_base<std::pair<llvm::GlobalValue* const, llvm::ConstantPointerRef*>,std::allocator<std::pair<llvm::GlobalValue* const, llvm::ConstantPointerRef*> > >>
            = {<_Rb_tree_alloc_base<std::pair<llvm::GlobalValue* const, llvm::ConstantPointerRef*>,std::allocator<std::pair<llvm::GlobalValue* const, llvm::ConstantPointerRef*> >,true>>
              = {_M_header = 0x0}, <No data fields>}, _M_node_count = 0,
              _M_key_compare = {<binary_function<llvm::GlobalValue*,llvm::GlobalValue*,bool>> = {<No data fields>}, <No data fields>}}}}

which is what causes the crash. The _Rb_tree::find call
(stl_tree.h:1268) is executing a line of code like this:

_Link_type __x = _M_root(); // Current node.

The _M_root() call is de-referencing the _M_header field.

This could, ostensibly, be a bug in std::_Rb_tree template but it could
also be a usage problem.

Note that the GVRefMap (in Module.cpp) has no constructor and just uses
the default. Presumably the default constructor of the std::map (member
Map) is also called but that constructor doesn't do much (i.e. provide a
value for _M_header).

One other note: this used to work a couple weeks ago. I just did a cvs
update and rebuilt LLVM. My code hasn't changed.

Any thoughts? Anyone seen this?


Nothing has really changed in this part of the compiler for a long time,
and I don't think we are abusing std::map's here. Is it possible that
part of your tree is out of sync with the rest of it or something? Maybe
make clean would help?


Sorry to trouble you with this. It was my own memory corruption problem. I accidentally allocated the LLVM Module in a memory segment type that is known to be buggy. Using the std::operator new makes the problem go away. Oops.


Reid (really glad I didn’t file a bug report now) Spencer.