Can I get a thread's stack address from pthread_self()

纵饮孤独 提交于 2021-01-27 20:23:45

问题


I want to get the stack address of a thread through some function to which we can pass pthread_self(). Is it possible? The reason I am doing this is because I want to write my own assigned thread identifier for a thread somewhere in its stack. I can write near the end of the stack (end of the stack memory and not the current stack address. We can ofcourse expect the application to not get to the bottom of the stack and therefore use space from there).

In other words, I want to use the thread stack for putting a kind of thread local variable there. So, do we have some function like the following provided by pthread?

stack_address = stack_address_for_thread( pthread_self() );

I can use the syntax for thread local variables by gcc for this purpose, but I'm in a situation where I can't use them.


回答1:


Probably it's better to use pthread_key_create and pthread_key_getspecific and let the implementation worry about those details.

A good example of usage is here:

pthread_key_create

Edit: I should clarify -- I'm suggesting you use the libpthread provided method of creating thread-local information, instead of rolling your own by pushing something onto the end of the stack where it's possible your information could be lost.




回答2:


With GCC, it is simpler to declare your thread local variables with __thread keyword, like

  __thread int i;
  extern __thread struct state s;
  static __thread char *p;

That is GCC specific (but I'll guess clang has it also, and the newest C++ & future C standards have something similar), but less brittle than pointers hacks based upeon pthread_self() (and should be a bit faster, but less portable, than pthread_key_getsspecific, as suggested by Denniston)

But I would really like you to give more context and motivation in your questions.




回答3:


I want to write my own assigned thread identifier for a thread

There are multiple ways to achieve that. The most obvious one:

__thread int my_id;

I can use the syntax for thread local variables by gcc for this purpose, but I'm in a situation where I can't use them.

You need to explain why you can't use thread-locals. Chances are high that other solutions, such as pthread_getattr_np, wouldn't work either.




回答4:


First get the bottom of the stack and give read/write permission to it with the following code.

pthread_attr_t attr;
void * stackaddr;
int * plocal_var;
size_t stacksize;

pthread_getattr_np(pthread_self(), &attr);
pthread_attr_getstack( &attr, &stackaddr, &stacksize );

printf( "stackaddr = %p, stacksize = %d\n", stackaddr, stacksize );

plocal_var = (int*)mmap( stackaddr, 4096, PROT_READ | PROT_WRITE, 
          MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0 );
// Now try to write something 
*plocal_var = 4;

and then you can get the thread ID, with the function get_thread_id() shown below. Note that calling mmap with size 4096 has the effect of pushing the boundary of the stack by 4096, that is why we subtract 4096 when getting the local variable address.

int get_thread_id()
{
    pthread_attr_t attr;
    char * stackaddr;
    int * plocal_var;
    size_t stacksize;

    pthread_getattr_np(pthread_self(), &attr);
    pthread_attr_getstack( &attr, (void**)&stackaddr, &stacksize );

    //printf( "stackaddr = %p, stacksize = %d\n", stackaddr, stacksize );

    plocal_var = (int*)(stackaddr - 4096);

    return *plocal_var;
}


来源:https://stackoverflow.com/questions/8729384/can-i-get-a-threads-stack-address-from-pthread-self

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!