今天遇到了一個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了。
好囧。。。。