读一个无关的问题,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