如何使用克隆系统调用分配新的TLS区域 [英] How to allocate a new TLS area with clone system call

查看:107
本文介绍了如何使用克隆系统调用分配新的TLS区域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简短版本的问题:如果要为正在创建的线程分配新的TLS区域,我需要将什么参数传递给x86_64 Linux系统上的clone系统调用.

Short version of question: What parameter do I need to pass to the clone system call on x86_64 Linux system if I want to allocate a new TLS area for the thread that I am creating.

长版:

我正在做一个研究项目,为了进行一些实验,我想使用clone系统调用而不是pthread_create创建线程.但是,我也希望能够使用线程本地存储.我现在不打算创建多个线程,因此最好为我使用克隆系统调用创建的每个线程创建一个新的TLS区域.

I am working on a research project and for something I am experimenting with I want to create threads using the clone system call instead of using pthread_create. However, I also want to be able to use thread local storage. I don't plan on creating many threads right now, so it would be fine for me to create a new TLS area for each thread that I create with the clone system call.

我正在查看clone的手册页,其中包含有关TLS参数标志的以下信息:

I was looking at the man page for clone and it has the following information about the flag for the TLS parameter:

CLONE_SETTLS (since Linux 2.5.32)
   The newtls argument is the new TLS (Thread Local Storage) descriptor.
   (See set_thread_area(2).)

因此,我查看了set_thread_area的手册页,并注意到以下内容似乎很有希望:

So I looked at the man page for set_thread_area and noticed the following which looked promising:

 When  set_thread_area()  is  passed  an  entry_number  of -1, it uses a 
 free TLS entry. If set_thread_area() finds a free TLS entry, the value of
 u_info->entry_number is set upon return to show which entry was changed.

但是,经过一些实验后,看来在我的系统中未实现set_thread_area(在x86_64平台上为Ubunut 10.04).当我运行以下代码时,出现错误消息:set_thread_area() failed: Function not implemented

However, after experimenting with this some it appears that set_thread_area is not implemented in my system (Ubunut 10.04 on an x86_64 platform). When I run the following code I get an error that says: set_thread_area() failed: Function not implemented

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h> 
#include <sys/syscall.h>
#include <sys/types.h>
#include <linux/unistd.h>

 #include <asm/ldt.h>

int main()
{
  struct user_desc u_info;
  u_info.entry_number = -1; 
  int rc = syscall(SYS_set_thread_area,&u_info);
  if(rc < 0) {
    perror("set_thread_area() failed");
    exit(-1);
  }

  printf("entry_number is %d",u_info.entry_number);
}

我还看到,当我使用strace时,看到调用pthread_create时会发生什么,而我看不到对set_thread_area的任何调用.我也一直在看nptl pthread源代码,以试图了解它们在创建线程时的作用.但是我还没有完全理解它,而且我认为它比我想做的还要复杂,因为我不需要在pthread实现中具有同样强大功能的东西.我假设set_thread_area系统调用是针对x86的,并且x86_64使用了不同的机制.但是目前我还无法弄清楚到底是什么,所以我希望这个问题能帮助我对需要看的东西有所了解.

I also saw that when I use strace the see what happens when pthread_create is called that I don't see any calls to set_thread_area. I have also been looking at the nptl pthread source code to try to understand what they do when creating threads. But I don't completely understand it yet and I think it is more complex than what I'm trying to do since I don't need something that is as robust at the pthread implementation. I'm assuming that the set_thread_area system call is for x86 and that there is a different mechanism used for x86_64. But for the moment I have not been able to figure out what it is so I'm hoping this question will help me get some ideas about what I need to look at.

推荐答案

我正在研究一个项目,并且正在做一些试验,我想使用克隆系统调用而不是pthread_create来创建线程

I am working on a research project and for something I am experimenting with I want to create threads using the clone system call instead of using pthread_create

在不太可能发生的情况下,新线程永不调用任何libc函数(直接调用或通过调用其他调用libc的函数;这还包括动态符号解析)通过PLT),则可以将所需的任何TLS存储作为new_tls参数传递给clone.

In the exceedingly unlikely scenario where your new thread never calls any libc functions (either directly, or by calling something else which calls libc; this also includes dynamic symbol resolution via PLT), then you can pass whatever TLS storage you desire as the the new_tls parameter to clone.

您应该忽略对set_thread_area的所有引用-它们仅适用于32位/ix86大小写.

You should ignore all references to set_thread_area -- they only apply to 32-bit/ix86 case.

如果您计划计划在新创建的线程中使用libc,则应放弃您的方法:libc 期望 TLS用于以某种方式进行设置,而直接致电clone时,您将没有 安排此类设置.当libc发现您没有正确设置TLS时,新线程将间歇性地崩溃.调试此类崩溃非常困难,并且唯一可靠的解决方案是...使用pthread_create.

If you are planning to use libc in your newly-created thread, you should abandon your approach: libc expects TLS to be set up a certain way, and there is no way for you to arrange for such setup when you call clone directly. Your new thread will intermittently crash when libc discovers that you didn't set up TLS properly. Debugging such crashes is exceedingly difficult, and the only reliable solution is ... to use pthread_create.

这篇关于如何使用克隆系统调用分配新的TLS区域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆