Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos Mac OS X pthreads假返回地址_Macos_Pthreads_Mach - Fatal编程技术网

Macos Mac OS X pthreads假返回地址

Macos Mac OS X pthreads假返回地址,macos,pthreads,mach,Macos,Pthreads,Mach,在OS X pthreads实现()中,它们在线程堆栈上提供了一个假返回地址(第140行): 我不明白当线程正在执行的函数调用'ret'并从堆栈中弹出返回地址时,这如何不会因非法指令/segfault而崩溃。有人能解释一下这是如何防止/处理的吗?不看代码的其余部分,我只能大胆猜测一下。我的直觉是,被调用的线程过程(用户提供的start\u例程参数)应该永远不会返回调用函数 想想看:如果新线程确实返回,您将有两个线程在相同的原始代码路径上运行。我设想实际调用的线程函数是一个包装器,它调用用户提供的

在OS X pthreads实现()中,它们在线程堆栈上提供了一个假返回地址(第140行):


我不明白当线程正在执行的函数调用'ret'并从堆栈中弹出返回地址时,这如何不会因非法指令/segfault而崩溃。有人能解释一下这是如何防止/处理的吗?

不看代码的其余部分,我只能大胆猜测一下。我的直觉是,被调用的线程过程(用户提供的
start\u例程
参数)应该永远不会返回调用函数

想想看:如果新线程确实返回,您将有两个线程在相同的原始代码路径上运行。我设想实际调用的线程函数是一个包装器,它调用用户提供的
start\u例程
。当
start_例程
返回时,包装器随后调用
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\u create
的代码。然后,包装器的目的是确保调用
pthread\u exit

我必须查看它们作为
例程
传递给
线程设置
的内容


事实上,传递给
\u pthread\u setup
的“例程”似乎总是
\u pthread\u body
(在这个文件中搜索该标识符:),它与您推测的包装器完全一样。实际的线程工作线程(最初传递给
pthread\u create
的函数指针)隐藏在
pthread\u t
对象中。我不知道为什么
thread\u setup
在它自己的文件中,但是这种低级代码通常是一堆乱七八糟的。想想看,
thread\u setup
中的“假返回地址”可能是为了确保包装器是否真的返回(这在C库中可能是一个bug,但仍然如此)您得到的是一个可预测的崩溃,而不是跳转到某个可能有代码的随机地址。@Zack感谢您确认这一切!当我回答时,我真的没有时间调查,所以我感谢你的跟进。这一切都是有道理的。实际的用户函数被调用为_pthread_exit的参数,然后_pthread_exit使用thread_terminate终止自己的线程,永远不会返回给用户。
(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