一个SIGSEGV问题定位实例

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 vec_;
    #endif
            string name_;
    };
    
    // Net.cpp
    Net::PrintName(){
            // 访问成员变量name_
            cout<name_<

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<name_< vec_;
    #endif
            string name_;
    };

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

    class Net{
    public:
            Net(){}
            void PrintName(){
                    // 访问成员变量name_
                    cout<name_<

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

你可能感兴趣的:(一个SIGSEGV问题定位实例)