問題描述 問題和 unordered_set 有關,相關代碼如下: //列印unordered_set的所有值 void printSet(const std::unordered_set<std::string> &data) { int index = 0; auto it = data.beg ...
問題描述
問題和 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,運行正常,算是暫時解決了這個問題,但是因為使用了編譯器優化,會不會導致邏輯不達預期,需要進一步測試
總結
那麼,造成此問題的原因究竟是什麼呢?