不靠谱的backtrace

#起因
今天遇到一个问题,程序收到abort信号后退出,打开core文件后很快定位到目标代码,但是很奇怪的是目标代码似乎没有问题,反而是目标代码附近的代码看起来比较可疑。
增加日志后调试发现确实如此,backtrace报告的代码不是真正出问题的代码。

#重现

#include "base.h"
#include "stdio.h"
boost::shared_ptr<std::string> err_str;
boost::shared_ptr<std::string> normal_str2;
int main(int argc, char **argv)
{
    err_str.reset();
    normal_str2 = boost::shared_ptr<std::string>(new std::string);
    *normal_str2 = "test";
    printf("before\n");
    std::string l_test_str = *(err_str); // !!!
    printf("after\n");
    printf("%c\n", normal_str2->at(0));
    return 0;
}

上面代码的错误很明显,使用*获取一个空指针的值,会导致BOOST_ASSERT失败,程序会因abort信号而退出。在我的机器上,gdb告诉我,是reset的那行代码出了问题,真让人摸不着头脑。当然before还是会打印出来的。

#include "base.h"
#include "stdio.h"
boost::shared_ptr<std::string> err_str;
boost::shared_ptr<std::string> normal_str2;
int main(int argc, char **argv)
{
    err_str.reset();
    normal_str2 = boost::shared_ptr<std::string>(new std::string);
    *normal_str2 = "test";
    printf("before\n");
    assert(err_str.get()); // !!!
    printf("after\n");
    printf("%c\n", normal_str2->at(0));
    return 0;
}

上面的代码会在错误行abort,并且backtrace给出的行号是正确的。

结论

相信日志吧!backtrace仅供参考。
本人能力有限,目前只能怀疑是*操作破坏了栈,导致backtrace报告了错误的代码位置。有心的朋友可以用objdump看看汇编代码,若找到真正原因,希望也能和我分享。谢谢!