pthread_detach()在64位Linux上导致SIGSEGV

奥列格·奥索维斯基(Oleg Osovitskiy)

这是我的情况的描述:我必须照顾产品中的错误。线程创建为joinable,它必须完成工作,终止并没有人会要求pthread_join()它。因此,该线程是使用JOINABLE属性创建的(默认情况下),并且在终止之前调用下一个代码:

{  pthread_detach(pthread_self()); pthread_exit(NULL); }

在我遇到的所有32位Linux发行版上,它都像是一种魅力,但SIGSEGV在64位发行版上却引起了(Ubuntu 13.04 x86_64和Debian)。我没有尝试使用Slackware。这是一个核心:

Core was generated by `IsaVM -s=1 -PrjPath="/home/taf/Linux_Fov_540148/Cmds"  -stgMode=1 -PR -Failover'.
Program terminated with signal 11, Segmentation fault.
#0  0x00007f5911a7c009 in pthread_detach () from /lib/x86_64-linux-gnu/libpthread.so.0
(gdb) bt
#0  0x00007f5911a7c009 in pthread_detach () from /lib/x86_64-linux-gnu/libpthread.so.0
#1  0x000000000041310d in _kerCltDownloadThr (StartParams=0x6bfce0 <RESFOV>) at ./dker0clt.c:1258
#2  0x00007f5911a7ae9a in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0
#3  0x00007f591159f3fd in clone () from /lib/x86_64-linux-gnu/libc.so.6
#4  0x0000000000000000 in ?? ()

我想出了解决此错误的方法-pthread_attr_setdetachstate()在创建线程之前,为线程设置了CREATE_DETACHABLE属性(使用),并且该线程可以按预期工作。

但是我的问题是-调用此代码是否构成犯罪?

{  pthread_detach(pthread_self()); pthread_exit(NULL); }

pthread_detach()通话后是否会异步执行某些操作并导致pthread_exit()出现问题?但是崩溃点pthread_detach()不是pthread_exit()我完全不了解这次崩溃的原因!为什么要在32位上工作?pthread实施过程中是否存在竞争条件

pthread_join() 不要求此线程。

预先感谢您的任何想法。

奥列格·奥索维斯基(Oleg Osovitskiy)

我用受人尊敬的@MaximYegorushkin提供的方法完成了研究。AddressSanitizer向我展示了我们产品中的一个缓冲区obverflow,但这与我的问题无关(我以后肯定会修复它,拥有这样一个明智的工具来寻找bug总是很好的)。因此决定pthread_xxxLD_PRELOAD方法覆盖所有必要的功能我运行一个简单的测试以确保我的库能按预期工作:

[HACK] Loading pthread hack.
Starting thread...!
[HACK] pthread_create: thread=7FAC6C86D700
Waiting for 2 seconds...
[HACK] pthread_self: thread=7FAC6C86D700
thread_func: thread id = 7FAC6C86D700
Thread: sin(3.26) = -0.121109
[HACK] pthread_self: thread=7FAC6C86D700
[HACK] pthread_detach: thread=7FAC6C86D700
Terminating...

[HACK]开头的所有字符串都是由我的threadhack.so生成的然后,我使用该库运行我的项目,它为我指明了问题所在:

执行的代码: { pthread_detach(pthread_self()); pthread_exit(NULL); }

调试痕迹:

[HACK] pthread_create: thread=7F403251CB00
.....
[HACK] pthread_self: thread=7F403251CB00  
[HACK] pthread_detach: thread=3251CB00    

因此,我们看到它pthread_self返回了一个好的线程ID,但pthread_detach收到的它已经被篡改(切成32位)。怎么会这样 我为我的简单工作测试应用程序和项目生成了汇编代码:

参考应用:

call    pthread_self
movq    %rax, %rdi
call    pthread_detach
movl    $0, %edi
call    pthread_exit

因此,我们在这里看到该movq指令用于复制64位线程ID(movq %rax, %rdi)。OK,检查为我的项目生成什么GCC

movl    $0, %eax
call    pthread_self
movl    %eax, %edi
movl    $0, %eax
call    pthread_detach
movl    $0, %edi
movl    $0, %eax
call    pthread_exit

哇!我们有两条movl指令(32位),一条复制最低有效的32位(movl %eax, %edi),而不是最高有效部分总是将其置零!movl $0, %eax)。因此,这是损坏了thead id的原因。我不知道为什么代码如此不同-编译标志相同。GCC 4.7GCC 4.8(最新的软件包中Ubuntu 13.10 x86_64看到了这个错误

所以至少现在我明白了。感谢@Maxim和出色的工具。我又学了新东西。

PS:我不知道如何向GCC团队提交错误报告。我无法在一个简单的小型应用程序上重现该问题,也无法将其交给我的项目,因为它是专有软件,因此我接受了NDA的许可,不予分发。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

即使在pthread_detach之后也会泄漏

来自分类Dev

关于 pthread_join() 和 pthread_detach() 的问题

来自分类Dev

存在现有联接程序时的pthread_detach行为

来自分类Dev

未定义的引用(readline,pthread_create,pthread_detach),makefile不包含库

来自分类Dev

关于线程的pthread_join()和pthread_detach()的“回收存储”是什么意思?

来自分类Dev

不使用pthread_detach或pthread_join,会不会为其他新创建的线程清理资源?

来自分类Dev

在Linux Mint 64位上编译aflex

来自分类Dev

在64位gentoo linux上运行32位程序

来自分类Dev

Linux上的32位,64位CPU操作模式

来自分类Dev

在64位linux系统上的32位apache

来自分类Dev

在64位linux上从32位模式切换到64位(长模式)

来自分类Dev

编译 64 位时 pthread.h 上的“错误:预期标识符或 '(' 之前的 '{' 标记”

来自分类Dev

在64位Linux上使用中断0x80

来自分类Dev

64位Linux上的缓冲区溢出

来自分类Dev

在Linux上如何处理向64位的转换

来自分类Dev

如何在64位Arch Linux上安装AMD Crimson?

来自分类Dev

如何在 Linux 64 位上运行 Rebol 脚本

来自分类Dev

在Linux Ubuntu 13.10 64位上安装Navicat

来自分类Dev

linux 上的 pthread_cancel() 导致异常/核心转储,为什么?

来自分类Dev

如何在32位Linux上安装64位Linux虚拟机?

来自分类Dev

在64位Windows系统上的虚拟PC上安装32位Linux是否可以?

来自分类Dev

breakpad 32位构建在64位Linux系统上失败

来自分类Dev

在setup.sh之前使用linux 32时,64位Ubuntu上的32位程序失败

来自分类Dev

在64位Linux机器上运行32位应用程序

来自分类Dev

在setup.sh之前使用linux 32时,64位Ubuntu上的32位程序失败

来自分类Dev

如何在64位Linux上从32位Wine执行Shell脚本?

来自分类Dev

如何在64位Linux上找到32位版本的Java的路径?

来自分类Dev

在64位Linux上无法编译32位at&t汇编程序

来自分类Dev

在64位Windows 7(msys2 / mingw64)上构建GMP 6.1.0:由于mp_limb_t不是64位而导致配置失败

Related 相关文章

  1. 1

    即使在pthread_detach之后也会泄漏

  2. 2

    关于 pthread_join() 和 pthread_detach() 的问题

  3. 3

    存在现有联接程序时的pthread_detach行为

  4. 4

    未定义的引用(readline,pthread_create,pthread_detach),makefile不包含库

  5. 5

    关于线程的pthread_join()和pthread_detach()的“回收存储”是什么意思?

  6. 6

    不使用pthread_detach或pthread_join,会不会为其他新创建的线程清理资源?

  7. 7

    在Linux Mint 64位上编译aflex

  8. 8

    在64位gentoo linux上运行32位程序

  9. 9

    Linux上的32位,64位CPU操作模式

  10. 10

    在64位linux系统上的32位apache

  11. 11

    在64位linux上从32位模式切换到64位(长模式)

  12. 12

    编译 64 位时 pthread.h 上的“错误:预期标识符或 '(' 之前的 '{' 标记”

  13. 13

    在64位Linux上使用中断0x80

  14. 14

    64位Linux上的缓冲区溢出

  15. 15

    在Linux上如何处理向64位的转换

  16. 16

    如何在64位Arch Linux上安装AMD Crimson?

  17. 17

    如何在 Linux 64 位上运行 Rebol 脚本

  18. 18

    在Linux Ubuntu 13.10 64位上安装Navicat

  19. 19

    linux 上的 pthread_cancel() 导致异常/核心转储,为什么?

  20. 20

    如何在32位Linux上安装64位Linux虚拟机?

  21. 21

    在64位Windows系统上的虚拟PC上安装32位Linux是否可以?

  22. 22

    breakpad 32位构建在64位Linux系统上失败

  23. 23

    在setup.sh之前使用linux 32时,64位Ubuntu上的32位程序失败

  24. 24

    在64位Linux机器上运行32位应用程序

  25. 25

    在setup.sh之前使用linux 32时,64位Ubuntu上的32位程序失败

  26. 26

    如何在64位Linux上从32位Wine执行Shell脚本?

  27. 27

    如何在64位Linux上找到32位版本的Java的路径?

  28. 28

    在64位Linux上无法编译32位at&t汇编程序

  29. 29

    在64位Windows 7(msys2 / mingw64)上构建GMP 6.1.0:由于mp_limb_t不是64位而导致配置失败

热门标签

归档