windoze 发表于 2015-08-06 14:17

C++ABI的天坑:在静态链接的Linux程序中使用std::thread

本帖最后由 windoze 于 2015-08-06 14:52 编辑

家里有一个小NAS盒子,用的是一个赛扬的嵌入式Linux系统,昨天心血来潮想给它写点代码,然后就掉进一个天坑里……

故事是这样的,这个鬼系统用的是64位内核,但绝大多数user land程序和库都是32位的,我本着不浪费的精神决定用64位程序,但系统中居然没有64位的libdl.so……好吧,反正我也不太需要动态库,我决定把程序静态链接。
地球人都知道glibc不支持静态链接,所以我就不浪费时间了,直接用musl,这个libc对静态链接支持良好。
重新build一个基于musl的libstdc++,没什么好说的,标准的cross compiling流程,也没遇到什么问题
编译链接我自己的程序,一切正常。
正当我以为万事大吉的时候,我忽然发现编译出来的程序不能跑,呐尼?
terminate called after throwing an instance of 'std::system_error'
what():Enable multithreading to use std::thread: Operation not permitted
为毛说不行泥?检查一下linker flag,发现没有-pthread,加上再试。
还是不行?试试-lpthread,还是不行?
用nm看看
               U pthread_create
搞毛线?我一个静态链接的程序里面居然有未解决引用的符号?
看来问题找到了,pthread的函数没有链接进去,看来只能hack了:
g++ ... -Wl,--whole-archive -lpthread ...
还是不行?看来它是要逼着我发大招了,天马流……不对放错碟了……手动链接符号拳!
g++ ... -lpthread -Wl,-u,pthread_cancel,-u,pthread_cond_broadcast,-u,pthread_cond_destroy,-u,pthread_cond_signal,-u,pthread_cond_wait,-u,pthread_create,-u,pthread_detach,-u,pthread_cond_signal,-u,pthread_equal,-u,pthread_join,-u,pthread_mutex_lock,-u,pthread_mutex_unlock,-u,pthread_once,-u,pthread_setcancelstate ...
再试,嗯,好了,搞定收工。

改下代码不用std::thread,用boost::thread,一切正常,木有这种古怪问题。

bruceteen 发表于 2015-08-06 14:21

强      

lxyscls 发表于 2015-08-06 14:26

猫哥威武{:yct75:}

刚好今天也碰到个链接静态库,显示undefined的问题了

fender0107401 发表于 2015-08-06 14:48

这个std::thread跟boost里面的thread是同一个吗?

cokeboL 发表于 2015-08-06 15:14

猫哥雄壮威武,收藏

shang2010 发表于 2015-08-06 15:47

这个线程问题有点不合常理

windoze 发表于 2015-08-06 16:11

回复 6# shang2010

这不是我这边的特例,这是Linux/GCC/glibc/libstdc++这一套东西的综合问题。

改用musl的原因就是64位glibc本身不支持静态链接
要手动链接符号的原因是libstdc++处于某种未知的原因就喜欢动态bind线程库。

周末试试musl+libc++/libc++abi/libcxxrt,希望不会有这些问题,至少FreeBSD上的libc和libc++/libcxxrt可以正确生成静态链接的可执行程序。

myworkstation 发表于 2015-08-06 17:05

回复 1# windoze


    猫兄试过这个吗?-Wl,--whole-archive -lpthread -Wl,--no-whole-archive这里有这个问题的详细说明:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52590#c4

windoze 发表于 2015-08-06 17:23

回复 8# myworkstation

试过了,你看我的帖子里有,但不知道为什么不好使。
懒得猜了,所以我干脆手动链接符号。

myworkstation 发表于 2015-08-06 18:02

回复 9# windoze


    比较坑爹的是参数还有顺序相关的,你试试把参数放到参数中源文件的后面。
页: [1] 2
查看完整版本: C++ABI的天坑:在静态链接的Linux程序中使用std::thread