st_thread_create()
创建协程的时候,会调 _st_stack_new()
来申请一块内存,_st_stack_new()
里面额外申请了 2*REDZONE
的内存,在我的电脑上 一个 REDZONE
是 4096 字节。这个 两个 REDZONE
是一个在栈顶,一个在栈底。
,如下图:
如上图代码所示,棕色的内存块 2*REDZONE
被 函数 mprotect()
保护起来了。mprotect()
函数可以修改调用进程内存页的保护属性,如果调用进程尝试以违反保护属性的方式访问该内存,则内核会发出一个 SIGSEGV
信号给该进程。
下面用 lookupdns
程序演示一下,修改一下 lookupdns
,在 st_thread_exit()
前面加个 sleep(600)
。休眠 10分钟,这样协程就不会运行,然后退出,就有时间去查看内存。记得包含 头文件 unistd.h
#include <unistd.h>
sleep(600);
st_thread_exit(NULL);
运行情况如下,我往 lookupdns
加了一些 printf
,方便调试:
上图 圈出来的内存,有两块的 权限 是 ---p
的,就是保护内存。
为什么要搞两个保护内存出来呢?请看下一篇文章《ST源码分析-协程局部变量》,我会演示,如何突破保护内存,让 内核发 SIGSEGV
信号。
相关阅读:
由于笔者的水平有限, 加之编写的同时还要参与开发工作,文中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果读者有任何宝贵意见,可以加我微信 Loken1。QQ:2338195090。