【问题标题】:Call C function with different stack pointer (gcc)使用不同的堆栈指针 (gcc) 调用 C 函数
【发布时间】:2012-06-22 03:02:19
【问题描述】:

我正在寻找一种在不同堆栈中调用 C 函数的方法,即保存当前堆栈指针,将堆栈指针设置到不同位置,调用函数并在返回时恢复旧堆栈指针。

这样做的目的是为编程语言提供一个轻量级的线程系统。线程将在非常小的堆栈上运行,检查何时需要更多堆栈并动态调整其大小。这样可以在不浪费大量内存的情况下分配数千个线程。在调用 C 代码时,使用小堆栈是不安全的,因为 C 代码不知道检查和调整大小,所以我想使用一个大的 pthread 堆栈,它仅用于调用 C(在轻量级线程之间共享相同的 pthread)。

现在我可以编写可以正常工作的汇编代码存根,但我想知道是否有更好的方法来做到这一点,例如 gcc 扩展或已经实现它的库。如果不是,那么我想我会埋头于 ABI 和汇编语言手册 ;-) 我只是出于懒惰而不想重新发明轮子。

【问题讨论】:

  • 您可以使用克隆系统调用来实现您自己的“线程”和个性化的堆栈。如果您使用直接系统调用而不是 libc 包装器,则它的工作方式与 fork 非常相似,只是您可以指定共享哪些资源和命名空间。

标签: c pointers gcc stack


【解决方案1】:

假设您正在使用 POSIX 线程并且在 POSIX 系统上,您可以使用信号来实现这一点。设置备用信号处理堆栈 (sigaltstack) 并指定一个特殊的实时信号以使其处理程序在备用信号堆栈上运行。然后raise 信号切换到堆栈,并让信号处理程序从线程本地数据中读取要调用的函数和传递的参数的数据。

请注意,这种方法相当昂贵(更改堆栈的多个系统调用),但应该 100% 可移植到 POSIX 系统。由于它很慢,您可能希望使用汇编语言编写特定于拱门的调用 alt-stack 函数,并且只使用我的通用解决方案作为您尚未编写汇编版本的拱门的后备方案。

【讨论】:

  • 这是一个有趣的想法,但由于它使用系统调用,所以成本太高。无论如何感谢您的回复。
  • 好吧,如果您愿意为您关心的 CPU 编写 asm,它可能会提供一个不错的后备。您还可以考虑将旧的 makecontext API(在 POSIX 2001 中已过时,于 2008 年删除)作为第一个后备,因为它可以完全在用户空间中完成。
  • 一般来说,设置您自己的堆栈并拥有几个汇编存根来交换上下文就可以了。但是,您可能会遇到强制堆栈指针位于特定内存范围内的“堆栈检查”。您需要与堆栈指针一起交换堆栈限制(无论它存储在平台上的什么位置)。例如,在 windows 中,它位于 GS 段中的 _TIB::StackLimit 和 _TIB::StackBase 中。
猜你喜欢
  • 1970-01-01
  • 2011-12-05
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
  • 2020-05-08
  • 1970-01-01
  • 2020-01-03
  • 1970-01-01
相关资源
最近更新 更多