现在的位置: 首页 > 综合 > 正文

static的map成员的初始化顺序居然和编译器相关

2014年11月03日 ⁄ 综合 ⁄ 共 4953字 ⁄ 字号 评论关闭

我十分不敢相信这是真的,但是确实发生了,而且足足折腾了我5个小时。

core文件的内容大概是这样:

#0  0x0000003071664cba in std::_Rb_tree_decrement(std::_Rb_tree_node_base*) () from /usr/lib64/libstdc++.so.6
(gdb) bt
#0  0x0000003071664cba in std::_Rb_tree_decrement(std::_Rb_tree_node_base*) () from /usr/lib64/libstdc++.so.6
#1  0x0000000000494520 in std::_Rb_tree_iterator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, void* (*)()> >::operator-- (this=0x7fff252b0810) at /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_tree.h:197
#2  0x0000000000494801 in std::_Rb_tree<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, void* (*)()>, std::_Select1st<std::pair<std::basic_string<char,
std::char_traits<char>, std::allocator<char> > const, void* (*)()> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const,
void* (*)()> > >::insert_unique (
    this=0x831e20, __v=...) at /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_tree.h:929
#3  0x00000000004948e3 in std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, void* (*)(), std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>,
std::allocator<char> > const, void* (*)()> > >::insert (this=0x831e20, __x=...)
    at /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_map.h:396
#4  0x00000000004939d4 in tac::agent::AgentFactory::RegistClass (name="CAdeRequestAgent", 
    method=0x493882 <Register<tac::agent::CAdeRequestAgent, (char const*)((char*)(&(tac::agent::CAdeRequestAgentArgv)))>::CreateInstance()>)
    at src/tac_agent_factory.cpp:49
#5  0x00000000004938cb in RegistyClass::RegistyClass (this=0x831df8, name="CAdeRequestAgent", 
    method=0x493882 <Register<tac::agent::CAdeRequestAgent, (char const*)((char*)(&(tac::agent::CAdeRequestAgentArgv)))>::CreateInstance()>)
    at ./include/tac_agent_regist.h:30
#6  0x000000000049dff2 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at ./include/tac_agent_regist.h:51
#7  0x000000000049e62b in global constructors keyed to _ZNSt3tr141_GLOBAL__N_src_main.cpp_00000000_5DB345946ignoreE(void) ()
    at src/main.cpp:414
#8  0x0000000000530746 in __do_global_ctors_aux ()
#9  0x000000000040f33b in _init ()
#10 0x0000000000000000 in ?? ()

从f6中可以看出,这是静态成员初始化的问题。

我的代码长得是这样的:

typedef void* (*CreateFuntion)(void);

class AgentFactory{
public:
    static void* GetAgent(const std::string &name);
    static void RegistClass(const std::string &name,CreateFuntion method);
private:
    static std::map<std::string,CreateFuntion> map_strName2PAgents_;
};

static void AgentFactoryDebug(const std::map<std::string,CreateFuntion>& _map)
{                                                                                                                                            
    std::map<std::string,CreateFuntion>::const_iterator it = _map.begin();
    for (;it != _map.end();++it) {
        DEBUG("Agent %s in factory", it->first.c_str());
    }
}

std::map<std::string,CreateFuntion>   AgentFactory::map_strName2PAgents_;  

void* AgentFactory::GetAgent(const std::string &name){
    AgentFactoryDebug(map_strName2PAgents_);
    std::map<std::string,CreateFuntion>::const_iterator it_find = 
        map_strName2PAgents_.find(name);
    if(it_find == map_strName2PAgents_.end()){
        DEBUG("Cant find agent %s", name.c_str());
        return NULL;
    }else{
        return it_find->second();
    }
}

void AgentFactory::RegistClass(const std::string &name,CreateFuntion method){
    map_strName2PAgents_.insert(std::make_pair(name,method));
}

在调用这个类的时候各种core,core的天昏地暗。。。

相同的代码,在其它服务上运行ok,跑到这里就不干活了,我是各种崩溃。

查了一些资料,找到googler的如下解释:

You could be coming up against the static initialization problem:

http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.15

How are you initialising the map?

算是一个解决问题的方向,于是,我按照这种想法修改了代码:

typedef void* (*CreateFuntion)(void);                                                                                                        

class AgentFactory{
public:
    static void* GetAgent(const std::string &name);
    static void RegistClass(const std::string &name,CreateFuntion method);
private:
    //static std::map<std::string,CreateFuntion> map_strName2PAgents_;
};

static std::map<std::string,CreateFuntion>& getMap()
{
    static std::map<std::string,CreateFuntion> __map;
    return __map;
}

static void AgentFactoryDebug(const std::map<std::string,CreateFuntion>& _map)
{
    std::map<std::string,CreateFuntion>::const_iterator it = _map.begin();
    for (;it != _map.end();++it) {
        DEBUG("Agent %s in factory", it->first.c_str());
    }   
}

//std::map<std::string,CreateFuntion>   AgentFactory::map_strName2PAgents_;  

void* AgentFactory::GetAgent(const std::string &name){
    //AgentFactoryDebug(map_strName2PAgents_);
    AgentFactoryDebug( getMap() );
    std::map<std::string,CreateFuntion>::const_iterator it_find = 
        //map_strName2PAgents_.find(name);
        getMap().find(name);
    //if(it_find == map_strName2PAgents_.end()){
    if(it_find == getMap().end()){
        DEBUG("Cant find agent %s", name.c_str());
        return NULL;
    }else{
        return it_find->second();                                                                                                            
    }   
}

void AgentFactory::RegistClass(const std::string &name,CreateFuntion method){
    //map_strName2PAgents_.insert(std::make_pair(name,method));
    getMap().insert(std::make_pair(name,method));
}

问题解决了。

但是对于map的静态成员为什么会出现这种情况还是很不解。

明天持续更新本帖。

抱歉!评论已关闭.