一條cltq指令引發的血案

2021-07-05 04:34:30 字數 2269 閱讀 5113

文章**我的個人部落格上了  但是很久沒有維護已經被關掉了。現在重新將裡面的東西移到csdn上了。

兩個 a.c b.c, a.c裡實現了乙個函式 void **malloc2d()返回乙個void型的二級指標,然後b.c裡會呼叫這個malloc2d的函式,但是在除錯的時候始終得不到正確的值,遂用gdb進行除錯一番,發現在呼叫malloc2d過後,rax暫存器的值發生了變化,高32位被擷取為0了,我靠,這還了得,猜想會不會是哪把我這個記憶體給採掉了,我x,百思不得其解。於是乎慢慢的試,先將malloc2d的實現放在了b.c裡了,結果是沒問題的,這就很納悶了,難道是跨檔案惹的禍,將改變後的二進位制檔案進行objdump反彙編與原來的二進位制的反彙編進行比較,發現原來的在呼叫malloc2d後多了一條指令cltq

1159   400f75:       e8 8f 03 00 00          callq  401309

1160   400f7a:       48 98                  cltq

1161   400f7c:       48 89 05 05 0d 20 00    mov    %rax,0x200d05(%rip)        # 601c88

我x,這是一條神馬指令啊,為什麼不是直接將返回值rax賦給變數呢,為什麼要先cltq啊,我***,到底***是什麼情況啊,有木有人知道啊,神啊,救救我吧,哎,說多了,繼續。

然後再用gdb除錯了下原二進位制檔案,

(gdb) 

0x0000000000400f7a in create_tmp_suite_table (mysql=0x7fffffffdde0, suite=0x601c50 "oglconform_31", 

cases=0x601c64 "(1.5)") at mysql_operation.c:165

165case_with_funcid = malloc2d(846, 626, sizeof(int), &tmp);

1: x/i $pc

=> 0x400f7a :cltq    下一條要執行的指令

(gdb) p /x $rax    先 check下 $rax

$3 = 0x7ffff6ebc010

(gdb) si          執行一條指令cltq

0x0000000000400f7c165case_with_funcid = malloc2d(846, 626, sizeof(int), &tmp);

1: x/i $pc

=> 0x400f7c :mov    %rax,0x200d05(%rip)        # 0x601c88

(gdb) p /x $rax     再check 下rax

$4 = 0xfffffffff6ebc010

看出來了吧,rax高32位被截了全補1了,md什麼情況,為什麼gcc 出來會多一條沒用的cltq 指令啊,

算了,不知道了,google吧,

cltq r[%rax ] <- signextend(r[%eax]) convert %eax to quad word,將$eax轉化為4字,不就是rax了嘛,切,

cltq是有符號數的擴充套件,如果$eax的最高的32位為1的話,剛rax的高32擴充套件後全為1,相反如果$eax的高位為0的話,則擴充套件出來後全為0

所以剛剛的$eax擴充套件後$rax 為0xfffffffff6ebc010多了,

but,but,but, 問題是找到了,但是是什麼原因觸發了這個cltq指令呢,google了一下

別說,還真讓找到了,

二樓的兄弟給了這樣的解釋:

my guess is that "heap_sbrk"is not properly declared in the latter case, and thecompiler assumes it is returning an int (32 bits) instead of an uintptr_t (64 bits). check the inclusion of the header file.

真***的精闢啊,原來在寫makefile的時候a.c 直接寫的是gcc -c a.c 產生a.o,gcc a.o b.c -o b這樣在編譯b.c的時候,malloc2d函式會在a.o裡找到malloc2d的sysbol,但是它並沒有在b.c時申明,所以編譯器會預設它返回32位,而我們在用malloc2d的時候會(int **)malloc2d強制轉一次為64位(btw,my os is 64 bit)的了,所以它要擴充套件下eax,就這樣了,

所以在編譯的時候最好加上 -werror 引數 it will make you a much better developer.

Oracle中一條sql引發的血案(一)

血案sql如下 create table yw wg 17 as select distinct acc from yw wc cust 1715 a where a.acc not in select distinct acc from yw wc cust 17 b where a.acc b....

一條clickhouse SQL語句引發的問題思考

前段時間在實際工作中,使用者的一條sql引發了我一些思考。寫一篇簡單的博文來記錄下。實際表的列名等已替換。select from db1.table1 as t1 left join db2.table2 as t2 on t1.col1 t2.col2 where t1.time 2020 01 ...

一條命令引發的思考

背景 要求把 user目錄裡31乙個省份資料夾許可權全部更改為700許可權,並給在群裡貼出修改的命令如下 hadoop fs chmod r 700 user 操作 這個還不簡單,就是手敲下各個身份嘛,頗為簡單,直接開工如下 hadoop fs chmod r 700 user hadoop fs ...