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
,