我正在为 pthread 库制作一个包装器,它允许每个线程拥有自己的一组非共享内存。现在,如果任何线程尝试读取另一个线程的数据,程序就会出现段错误。这很好,我可以用ighandler捕获它并调用pthread_exit()
并继续执行程序。
但并非每个段错误都是由不良 rwe 造成的。我需要找到一种方法来使用 siginfo 类型来确定段错误是否是错误的编程或此错误。有什么想法吗?
由于我使用 mmap 来管理内存页面,我认为在 siginfo
中使用 si_addr
会对我有所帮助。
最佳答案
听起来你真正想要的是线程本地存储,它已经比这更便携地解决了。 GCC提供了__thread,MSVC提供了__declspec(thread)。 boost::thread根据平台/工具链等,使用各种机制提供可移植的线程本地存储。
如果你真的想走这条路,它是可行的,但这条路充满了危险。从 SIGSEGV 中恢复在技术上是未定义的行为,尽管它可以在相当多的平台上工作,但它既不健壮也不可移植。不过,您也需要非常小心在信号处理程序中所做的事情 - async-safe 列表函数,即可以从信号处理程序合法安全调用的函数非常小。
我过去曾多次成功地使用过这个技巧,通常是为了在用户空间中将“页面”标记为“脏”。我这样做的方法是设置一个哈希表,其中包含我感兴趣的所有内存“页面”的基地址。当您在处理程序中捕获 SIGSEGV 时,您可以使用简单的方法将地址映射回页面算术运算。如果哈希表可以在没有锁的情况下读取,那么您就可以查找这是您关心的页面还是来自其他地方的段错误,并决定如何操作。
关于pthreads - 处理segfault信号SIGSEGV需要使用siginfo_t确定segfault的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1801788/