讀一個無關的問題,exposes a pattern that looked similar to yours,我想我找到了你的奇怪代碼的由來。
最大的可能是這個代碼來自線程相關的C++ 11功能的擴展,在使用__gthread_active_p()
檢查,如果pthread
庫中居然掛特別的東西。
是有可能
大多數代碼應對線程的libstdC++的問題(但如果不需要線程支持合理的回退)充斥着
if(__gthread_active_p())
這又通常歸結爲檢查是否符號__pthread_key_create
是定義爲不同於NULL
的內容。這裏的訣竅是,這樣一個函數是,它被聲明爲和__attribute__ ((weak))
,所以,如果沒有提供定義(即如果pthread
庫未鏈接),而不是抱怨,鏈接器只是解析其對NULL的引用。
所以,你在代碼中看到的是編譯器留下來做線程相關的東西(比如獲取一個保護一些共享資源的互斥鎖)的檢查。預連接代碼可能是這樣的:
mov eax,__pthread_key_create
test rax,rax
jz .skip_mutex_init
call __pthread_init_some_mutex
.skip_mutex_init:
mov rax, 0xffffffffffffff60
sub rbx,r15
add QWORD PTR fs:[rax],rbx`
在那裏你看到決心NULL
指針所有__pthread
符號。當然,最終的代碼是非常愚蠢的 - 編譯器不知道鏈接器是否將被調用-lpthread
,並且鏈接器只是執行愚蠢的替換 - 再次運行優化器太晚了(除非啓用了LTO,但這是一個完全不同的遊戲)。
您可以看到自己類似的圖案playing with the compiler explorer:嘗試啓用/禁用鏈接完整的二進制文件(右邊的按鈕和11010標題),並在命令行上添加/刪除-pthread
。現在
,我沒能精確再現你的結果,但可能是來自不同版本的libstdc++
被使用,或者在你的代碼中使用了不同的線程感知組件(我只是嘗試用std::mutex
和std::shared_ptr
) 。
嘗試移除該位,看看它是否有所作爲。 –
@MadPhysicist? – vladon
@PeterCordes它與-O2一起叮噹響。看,有eax歸零,但rax測試。 – vladon