看板 C_and_CPP 關於我們 聯絡資訊
開發平台(Platform): (Ex: Win10, Linux, ...) linux openwrt 編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出) gcc 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) 問題(Question): 傳入參數被莫名的修改 某個API 如下 CfaIfmNotifyInterfacStat (u4IfIndex, u1AdminStatus, &u1OperStatus, u1IsFromMib, u1IsRegToIp, &IfInfo)) != CFA_SUCCESS) 傳入時的值: u4IfIndex=43 , u1AdminStatus=1, &u1OperStatus=(UINT1 *) 0xb1e0256f 進入API後值卻變成 https://upload.cc/i1/2023/07/23/ZnvhDF.jpg
u4IfIndex=0, u1AdminStatus=0 , pu1InOperStatus=0x0, 前面4個參數都被變成0 請問各位網友其會被修改到的原因 是不是因為Mutil thread 所造成 其值被其他thread StackOverflow 修改 但由於thread 眾多 各位網友是不是有甚麼的方式或tool 能介紹給我 去debug 找出是哪個thread 哪段code 所造成 謝謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 106.1.107.225 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1690094718.A.61A.html tanted:轉錄至看板 Soft_Job 07/23 14:55
stupid0319: thread很固定的改到別的thread的stack,見鬼了 07/23 15:39
LPH66: 你有取消最佳化參數後再去嘗試除錯過嗎? 07/23 17:23
seanwu: 只錯前四個的話,我感覺比較像gdb抓參數抓錯,自己照calli 07/23 22:41
seanwu: ng convention對一下參數值有沒有變 07/23 22:42
seanwu: 然後沒記錯的話,gdb預設應該是all-stop mode, 07/23 22:51
seanwu: 所有thread都會停下來才對 07/23 22:51
seanwu: 真的要抓,如果支援的話可以試試看watchpoints 07/23 22:54
其實這不是及時gdb的抓取的,這是因為程式crash後,產生了core dump,用gdb去看 的,而程式為什麼crash,最主要原因pu1InOperStatus=0x0 ,因為這是個pointer,而code 對它做指向操作造成segment fault。 只錯前四個是因為我發現到前四個的參數的存放記憶位置是連續,但第5個的記憶體位置 和前4個不是連續的。 目前 其實是這樣認為的 "原本thread 在進入 API,cpu 因context switch 換到其他的thread 而這個thread buff 沒有處理好 Overflow 蓋掉原本thread 的 stack buff" ※ 編輯: tanted (106.1.107.225 臺灣), 07/23/2023 23:40:33
LPH66: 那我覺得最佳化等級的影響可能會更大 07/24 01:41
LPH66: 或者是上面說的 gdb 沒使用對的呼叫慣例去找參數 07/24 01:41
LPH66: 每個 thread 會有他自己的 stack, 如果因為堆疊溢位寫到了 07/24 01:43
LPH66: 其他 thread 的 stack, 那它其實已經蓋掉更多東西了 07/24 01:43
LPH66: 幾乎不可能到了切過去時才會當掉 07/24 01:44
LPH66: (如果真蓋掉更多東西, 很高機會會在蓋掉後不久當掉) 07/24 01:44
LPH66: 你還是把最佳化選項 (-O3 等) 拔掉後再跑跑看 07/24 01:45
descent: pthread_attr_setstackaddr 用這個設定不同的 stack addr 07/24 09:09
descent: 看看是不是一樣有這問題 07/24 09:09
感謝LPH66 給提示的 後來我開始推測可能是進入API後 前面4個變數給記憶體位置可能是不可寫入 也就說從頭到位 變數的值未被修改過 也沒有被其他thread 修改 從一開始進入這個API 就產生segment fault https://upload.cc/i1/2023/07/24/oJ6wfn.jpg
u4IfIndex 的記憶體位置 是 0xaa303f9c 查看 thread map https://upload.cc/i1/2023/07/24/2bNjEW.jpg
https://upload.cc/i1/2023/07/24/Bf2Mkn.jpg
右上圖圈選 得知 0xaa303f9 的確在不可存取記憶空間 目前推測會造成這樣原因 因為我們code 分成三個部分 在build 可能帶的最佳化選項 -O 後面數字都不一樣所造成 ※ 編輯: tanted (106.1.107.225 臺灣), 07/24/2023 21:58:16
leolarrel: 用gdb , or gcc 編譯加上-fsanitize=address,or 用 07/28 14:29
leolarrel: Valgrind等工具探查記憶體 07/28 14:30
Lipraxde: 加 compile option 前要先對好環境,不然會很痛苦喔XDD 07/28 23:02
其實目前這個issue 尚未解掉 但可以避掉 因為那是讓user telnet 進來執行 才creat 出來thread ,如果一次只執行一個thread 就是只讓一個user進來 就不會有這種情形,如果此時再讓第二個user 進來 ,此時creat 出來thread 就會有這種情形。 ※ 編輯: tanted (106.1.107.225 臺灣), 07/29/2023 13:37:44
stupid0319: create 07/29 17:03
stupid0319: https://www.gdbgui.com/ 07/29 17:17
stupid0319: trace 看看 07/29 17:17
我想目前這跟 gdb 或如何trace無關了 為何local stack variable 會被賦一個"不可存取的記憶位置" 是toolchain 出了問題造成的嗎 toolchain 為 toolchain-arm_cortex-a9+vfpv3-d16_gcc-8.4.0_glibc_eabi 或是編譯時gcc設定參數有關嗎 ※ 編輯: tanted (106.1.107.225 臺灣), 07/29/2023 18:23:17
stupid0319: 寫code寫到懷疑toolchain還是gcc有問題的 07/29 18:40
stupid0319: 9成9都是低級bug造成 07/29 18:40
b0920075: 不能直接watch那個地址嗎 07/29 19:05
b0920075: 怎麼看你描述只是未初始化變數 07/29 19:10
這四個變數是API的參數,所以一進去API 他就會被賦予上層傳給他引數值, 所以不可能是未初始化變數,但觀察上層引數卻跟傳下來 前四個參數值不一樣,但後面兩個參數跟上層引數是一樣的。 前四個參數值都變成0,一開始我以為可能被其他thread 類似做memset() 可能使用長度過長導致越界去修改到這個thread 堆疊記憶體導致變成0。 後來經過LPH66 提示,他認為不可能是stackoverflow 造成。 加上我使用GDB trace 使用step 進入這個API 就出現segment fault的訊息出來 讓我開始懷疑可能是被給了不可寫入memory address 我上面貼圖 已經很明顯 看到第一個參數的memory address 是在不可存取區間 而第5個參數是在可寫入memory address,所以他和上層傳來引數是相同 但為什麼會前四個參數的memory address會被賦予在不可存取區間 我目前不得而知 ※ 編輯: tanted (106.1.107.225 臺灣), 07/29/2023 20:29:13
lc85301: 我覺得這個問題沒那麼簡單,看你能不能丟完整 code 出來 07/29 20:31
lc85301: 不能的話大家只能給你一點想法,剩下的靠通靈 07/29 20:32
lc85301: 另外這個函數我去查也只有你的文章,不是通用的函式 07/29 20:33
tanted: 因為這不是opensource Code 不能隨意放出來 07/29 20:34
lc85301: 看你的 toolchain 跟 openwrt 應該是在開發嵌入式系統 07/29 20:35
Lipraxde: 如果是自己刻的話,有沒有可能是 thread 的實作有問題 07/29 20:37
Lipraxde: ,傳 stack 的時候沒對好 ABI? 07/29 20:37
lc85301: 我個人通靈的話,我會在進去函數的引數的位址設 watch 07/29 20:39
lc85301: 另外你描述方法讓我聯想到這篇古早的文章: 07/29 20:41
b0920075: 如果你很確定是multithread在搞何不用 set scheduler-l 07/30 12:08
b0920075: ocking on 之類看看不讓thread切換會不會出問題?雖然 07/30 12:08
b0920075: 不知道用不同優化選項有沒有差但能用sanitizer 或是rr 07/30 12:08
b0920075: 應該有幫助 07/30 12:08
descent: 如果確定是在 stack 的變數, 那和編譯器無關 07/31 14:17
descent: 這是在程式載入時, sp 被設定了這個位址 07/31 14:18
descent: gcc 產生的 code 只是在當時 sp 指到的地方存取這些變數 07/31 14:19
descent: 你還是可以試試 pthread_attr_setstackaddr, 07/31 14:20
descent: 把 thread stack 換成 malloc 出來的, 應該就不會在 07/31 14:21
descent: aa3 開頭的區域, 可能可以避開這問題。 07/31 14:21
leolarrel: 認同stupid0319.會懷疑toolchain,我認為是還沒抓到自己 08/16 18:51
leolarrel: 的問題 08/16 18:51
sunneo: 也有可能是pthread_create傳入的closure的生命週期結束 08/19 18:07