美文网首页
一个SIGSEGV问题定位实例

一个SIGSEGV问题定位实例

作者: JxYoung | 来源:发表于2018-06-13 17:39 被阅读88次

    C++开发时,有时会遇到程序崩溃的情况,今天和大家分享一个SIGSEGV崩溃问题。

    SIGSEVG问题一般是访问了非法内存导致。

    问题场景还原

    两个so,a.so和b.so,b.so依赖a.so

    a模块有三个文件:

    • Net.h
    • Net.cpp
    • Android.mk
        // Net.h
        // 注意Net类的声明中有宏定义MACRO包含的成员
        
    
        class Net{
        public:
                Net(){}
                void PrintName();
        #ifdef MACRO
                void DoSthWithMACRO(){}
        #endif
        
        private:
                int id_;
        #ifdef MACRO
                vector<int> vec_;
        #endif
                string name_;
        };
        
        // Net.cpp
        Net::PrintName(){
                // 访问成员变量name_
                cout<<this->name_<<endl;
        }
        
        // Android.mk
        // 编译文件中定义了MACRO
        CFLAGS += -DMACRO
    

    b模块有三个文件:

    • User.h
    • User.cpp
    • Android.mk
        // User.h
        // User类中有Net成员
        #include Net.h
        class User{
        public:
                void PrintNetName();
        private:
                // 拥有Net成员
                Net* net_;
        };
        
        // User.cpp
        User::PrintNetName(){
                net_ = new Net();
                net_->PrintName();
        }
        
        // Android.mk
        // 编译文件中并没有定义MACRO宏
    

    由于两个模块(so)中一个定义了宏MACRO,一个没有定义,就会导致class Net在两个模块的声明有差异:a.so中比b.so中的class Net多了

    #ifdef MACRO
    ...
    #endif
    

    之间的内容。

    差异如下:
    在a.so中Net的定义是:

        class Net{
        public:
                Net(){}
                void PrintName(){
                        // 访问成员变量name_
                        cout<<this->name_<<endl;
                }
        #ifdef MACRO
                void DoSthWithMACRO(){}
        #endif
        
        private:
                int id_;
        #ifdef MACRO
                vector<int> vec_;
        #endif
                string name_;
        };
    

    在b.so中的Net的定义是:

        class Net{
        public:
                Net(){}
                void PrintName(){
                        // 访问成员变量name_
                        cout<<this->name_<<endl;
                }
        private:
                int id_;
                string name_;
        };
    

    因此在b.so中创建的Net对象并调用a.so中Net.cpp的PrintName()访问成员变量name_时就会崩库。因为内存地址对应不上。

    相关文章

      网友评论

          本文标题:一个SIGSEGV问题定位实例

          本文链接:https://www.haomeiwen.com/subject/bgfseftx.html