NDK編譯選項cFlags中O0 導致的bug

2021-07-09 16:53:22 字數 1153 閱讀 4614

晚上在家試著編譯乙個apk例子,發現乙個有趣的現象,編譯環境為:

android studio 2.0 preview + sdk23+ ndk r10e

有這麼一段原始碼:

unsigned int mgetpid()

syscall = 20,getpid系統呼叫號。編譯執行,結果怎麼都不正確,一直返回20,真是奇了怪了。上ida,反彙編瞧了眼**:

.text:00001834 push

.text:00001836 sub sp, sp, #0xc

.text:00001838 movs r3, #0x14

.text:0000183a str r3, [sp,#0x10+var_c]

.text:0000183c movs r3, #0x14

.text:0000183e mov r7, r3

.text:00001840 mov.w r2, #0

.text:00001844 svc 0

.text:00001846 mov r0, r3

.text:00001848 add sp, sp, #0xc

.text:0000184a ldr.w r7, [sp+4+var_4],#4

.text:0000184e bx lr

神奇吧,svc呼叫結束後,居然用mov r0,r3,覆蓋掉了正確的返回值。

各種嘗試,原來惹禍的是build.gradle中ndk配置選項:

cflags 「-std=gnu++11 -fpermissive -ddebug -o0 -pie -fpie」

將其中 -o0改為-o1或-o2,再次反彙編,**如下:

.text:00001820 push

.text:00001822 movs r3, #0x14

.text:00001824 mov r7, r3

.text:00001826 mov.w r2, #0

.text:0000182a svc 0

.text:0000182c ldr.w r7, [sp+4+var_4],#4

.text:00001830 bx lr

一切正常。

o0的本意是不進行優化,沒有道理在內聯彙編**的後面修改r0吧,算不算是乙個bug呢?

gcc編譯選項 o和 c介紹

一 選項 o 1 點睛 選項 o用於指定要生成的結果檔案,後面跟的就是結果檔案名字。o是output的意思,不是目標的意思。結果檔案可能是預處理檔案 彙編檔案 目標檔案或者最終可執行檔案。2 示例 gcc s test.i o test.s s 說明只進行到編譯階段 生成彙編檔案test.s3 示例...

關於編譯優化選項o3的問題

今天我在優化 的時候。出現了問題。如下 periph.c 讀暫存器,引數 位址 返回內容 unsigned int readcmd unsigned char addr main.c define readhdat0 readcmd spi hdat0 hdat0 readhdat0 讀 檔案幀頭資...

關於編譯優化選項o3的問題

今天我在優化 的時候。出現了問題。如下 讀暫存器,引數 位址 返回內容 unsigned int readcmd unsigned char addr define readhdat0 readcmd spi hdat0 hdat0 readhdat0 讀 檔案幀頭資訊 假如我不用o3優化項。我讀出...