记录一次使用unordered_set插入数据异常的问题
  boyxdPuSbXft 2024年04月01日 75 0
C++

问题描述

问题和 unordered_set 有关,相关代码如下:

//打印unordered_set的所有值
void printSet(const std::unordered_set<std::string> &data)
{
    int index = 0;
    auto it = data.begin();
    for (; it != data.end(); ++it)
    {
        const std::string& key = *it;
        EASE_ERROR("%d:%s", index++, key.c_str());
    }
}

...//其他业务代码
    
std::unordered_set<std::string> defined_task_variable;//数据定义

defined_task_variable.emplace(task_variable);	//插入代码
printSet(defined_task_variable);				//打印所有值

这些代码作为so提供给 程序A 调用,但是程序执行过程中发现,defined_task_variable 插入值后,printSet()方法应该遍历defined_task_variable,打印出其内部数据的,但实际上其打印出来的都是(null),且只在arm平台出现,且必现,但x86一切正常

排查思路

1、怀疑是线程资源冲突

相关操作函数增加线程id打印,确定是单线程,排除

2、怀疑是局部变量task_variable被释放

首先,unordered_set的emplace方法采用完美转发,不可能因为传入参数生命周期结束而导致没有值

其次,修改代码,emplace插入纯字符串,发现问题依然,排查

3、怀疑是程序A的问题

编写测试程序B,加载同一个so

此时,测试发现一个奇怪的现象。首先,x86依然正常,但是arm平台出现两种情况:

测试程序B因为代码量小,编译出来的结果在1M以下,运行正常;此时,相同的程序B再额外加上一些代码(这些代码没有用到),导致编译出来的二进制文件大小达到24M,此时运行,复现错误

什么原因呢?运行的问题出现在so中,但是却是调用so的二进制文件大小决定问题是否出现。有点诡异啊。

最终,仍然没有找到根本原因,但是既然文件大小会影响运行结果,那么减小文件是不是就可以避免了呢?

3.1、二进制文件大小

编译时加入编译器优化选项,使用-O3

set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -O3  -Wall")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3  -Wall")

原本编译出来的程序A大小从20多M,降到了5M,运行正常,算是暂时解决了这个问题,但是因为使用了编译器优化,会不会导致逻辑不达预期,需要进一步测试

总结

那么,造成此问题的原因究竟是什么呢?

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2024年04月01日 0

暂无评论

推荐阅读
  8Tw5Riv1mGFK   20天前   31   0   0 C++
  BYaHC1OPAeY4   13天前   33   0   0 C++
  yZdUbUDB8h5t   16天前   22   0   0 C++
  oXKBKZoQY2lx   4天前   16   0   0 C++
boyxdPuSbXft