2

在 OS X pthreads 实现(http://www.opensource.apple.com/source/Libc/Libc-825.26/pthreads/thread_setup.c?txt)中,它们在线程堆栈(第 140 行)上提供了一个虚假的返回地址:

    ts->rip = (uintptr_t) routine;

    /*
    ** We need to simulate a 16-byte aligned stack frame as if we had
    ** executed a call instruction. The stack should already be aligned
    ** before it comes to us and we don't need to push any arguments,
    ** so we shouldn't need to change it.
    */

    ts->rdi = (uintptr_t) thread;   /* argument to function */
    *--sp = 0;            /* fake return address */
    ts->rsp = (uintptr_t) sp;   /* set stack pointer */

我不明白当线程正在执行的函数调用“ret”并从堆栈中弹出返回地址时,这不会因非法指令/段错误而崩溃。谁能解释这是如何预防/处理的?

4

1 回答 1

3

不看其余代码,我只能冒险猜测。我的直觉是,被调用的线程过程(用户提供的start_routine参数)永远不应该返回调用函数。

想一想:如果新线程确实返回,您将有两个线程在相同的原始代码路径上运行。我想实际调用的线程函数是一个调用用户提供的包装器start_routine。当start_routine返回时,包装器然后调用pthread_exit.

(main thread)
     v
pthread_create
     v
thread_setup  (sets up stack), and spawns new thread
     v                                     |
return to main thread                      |
                                           |
                                           |
                                           v
                                      wrapper_function
                                           v
                    user-supplied    start_routine
                                           |   (returns)
                                           v
                                wrapper_function  calls
                                           v
                                     pthread_exit

同样,这只是一个猜测,但重点是,新线程永远不应该返回调用pthread_create. 包装器的目的是确保调用它pthread_exit

我得看看他们传递的是routine什么thread_setup

我的感觉得到证实,你不必打电话pthread_exit

于 2013-05-03T01:33:03.283 回答