今天遇到了一个SIGSEGV程序崩溃的问题
今天遇到了一个SIGSEGV程序崩溃的问题:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x73e22420 (LWP 2190)]
0x76dcdb54 in ?? () from /usr/lib/arm-linux-gnueabihf/libstdc++.so.6
(gdb) bt
#0 0x76dcdb54 in ?? () from /usr/lib/arm-linux-gnueabihf/libstdc++.so.6
#1 0x76e0e26a in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() () from /usr/lib/arm-linux-gnueabihf/libstdc++.so.6
#2 0x0008a3f0 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) quit
使用gdb大法都搞不定啊。打印调用堆栈只有两行。
同时添加日志,发现该崩溃发生在函数返回位置。
说明是老朋友了。就是局部变量过大,导致堆栈段溢出。
把局部变量修改为全局变量后,之前的崩溃位置不在崩溃。
但是崩溃位置变成其他用到这个类型的局部变量的函数返回位置。
经过灵机一动的分析。认为是函数返回的时候,这个类型的析构函数崩溃。
进一步调查发现是建构函数错误初始化的原因。
eval_value() { memset((void *)&poseFake, 0x00, sizeof(poseFake)); memset((void *)&jointFake, 0x00, sizeof(jointFake)); memset((void *)&prRegDataFake, 0x00, sizeof(prRegDataFake)); // memset((void *)&srRegDataFake, 0x00, sizeof(srRegDataFake)); memset((void *)&rRegDataFake, 0x00, sizeof(rRegDataFake)); // memset((void *)&mrRegDataFake, 0x00, sizeof(mrRegDataFake)); resetNoneValue() ; }
prRegDataFake的定义如下:
PrRegData prRegDataFake;
PrRegData定义如下:
typedef struct { int pos_type; double pos[9]; // support up to 9 axes per control group bool posture[4]; int group_id; }PrValue; typedef struct { int id; std::string name; std::string comment; PrValue value; }PrRegData;
我把std::string给memset了。
好囧。。。。