Mac OS X получает поддельный обратный адрес

В реализации pthreads в OS X ( 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 */

Я не понимаю, как это не приведет к сбою с недопустимой инструкцией /segfault, когда функция, выполняемая потоком, вызывает 'ret' и выскакивает этот адрес из стека. Может кто-нибудь объяснить, как это предотвращается / обрабатывается?

1 ответ

Решение

Не глядя на остальную часть кода, я могу только рискнуть. Моя интуиция говорит, что вызываемая процедура потока (предоставленная пользователем 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,

Другие вопросы по тегам