简体   繁体   中英

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

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.

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.

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.

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.

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM