【问题标题】:What will happen if we return between pthread_cleanup_push and pthread_cleanup_pop in Unix? And why?如果我们在 Unix 中返回 pthread_cleanup_push 和 pthread_cleanup_pop 之间会发生什么?为什么?
【发布时间】:2017-04-05 14:21:21
【问题描述】:

我在Advanced Programming in the UNIX Environment (3rd Edition),11.5,Thread Termination 中读到过这个:

如果我们在 FreeBSD 或 Mac OS X 上运行相同的程序,我们会看到 程序发生分段违规并丢弃核心。有时候是这样的 因为在这些系统上,pthread_cleanup_push 被实现为 在堆栈上存储一些上下文的宏。当线程 1 返回时 在调用 pthread_cleanup_push 和调用 pthread_cleanup_pop,堆栈被覆盖,这些平台尝试 在调用清理时使用此(现在已损坏)上下文 处理程序。在单一 UNIX 规范中,在两者之间返回 一对匹配的 pthread_cleanup_push 调用和 pthread_cleanup_pop 导致未定义的行为。唯一的便携 在这两个函数之间返回的方法是调用 pthread_exit。

那么,我想知道的是什么叫栈上的上下文,什么是被覆盖和损坏的上下文,为什么返回不能按预期工作?

【问题讨论】:

    标签: c multithreading unix undefined-behavior


    【解决方案1】:

    当调用 C 函数时,它会将一些信息(如局部变量)存储在内存的“堆栈”部分。同样,当这个函数调用另一个函数时,这个新函数将它的信息存储在调用函数之后。

    当函数调用结束时,它的内存被释放/释放,类似于从堆栈中取出一个盘子。这个空间现在可以重复使用了。

    memory http://www.firmcodes.com/wp-content/uploads/2014/08/memory.png

    如果将pthread_cleanup_push 实现为在堆栈上存储信息(上下文)的宏,则该内存将被释放,并可能被下一个函数调用覆盖。

    如果这发生在调用pthread_cleanup_pop 之前,“上下文”很可能会被连续的函数调用覆盖,从而破坏pthread_cleanup_pop 期望读取的内存。

    【讨论】:

    • “此内存将被释放,并可能被下一个函数调用覆盖”,这不是真的,但这肯定会导致进程因违反分段而终止吗?我认为 pthread_cleanup_pop 将读取损坏的内存,其行为将变得不可预测,但不一定会终止。你怎么看?
    猜你喜欢
    • 1970-01-01
    • 2019-10-07
    • 1970-01-01
    • 2014-03-01
    • 1970-01-01
    • 2021-12-31
    • 2012-01-13
    • 1970-01-01
    • 2012-10-11
    相关资源
    最近更新 更多