ST源码分析-协程局部变量

SRS 的社群来了,想加入微信社群的朋友请购买《SRS原理》电子书,里有更高级的内容与答疑服务。


ST源码分析-st_thread_create》跟 《ST源码分析-内存保护》两篇文章,讲解了,协程函数的栈内存就是下图的区域,如下:

下面就来验证一下协程函数的局部变量是不是真的存储到这块内存区域。还是用 lookupdns 做演示。

首先,在st_thread_create() 函数加上以上代码。

stack->sp = sp - _ST_STACK_PAD_SIZE;
//下面是调试代码。
printf("stack->stk_bottom is %p \r\n",stack->stk_bottom);
printf("stack->sp is %p \r\n",stack->sp);

然后 修改 lookupdns.c 的代码,如下,打印局部变量 addr 的地址。

void *do_resolve(void *host)
{
    struct in_addr addr;
    printf("addr is %p \r\n",&addr);
    ....
    return NULL;
}
​

运行结果如下图:

上图的第一次打印是 idle 协程的,不用管他。

从上图可以看到,addr 的地址,确实在 stack->stk_bottom ~ stack->sp 之间,所以 stack->stk_bottom ~ stack->sp 之间的内存,就是协程函数的栈内存。

在 do_resolve() 函数里面,定义完 addr 之后,栈顶是 0x7f0114200d44。还剩 0x7f0114200d44 - 0x7f01141f1000 等于 0xFD44 字节。如果我再定义一个变量,超过这个数量的字节,就会触发访问保护内存。演示一下:

我对整个 do_resolve() 都做了修改,因为 printf() 的调用也会占用栈内存。代码如下:

void *do_resolve(void *host)
{
   struct in_addr addr;
    char str[64600] = {0};
    printf("1\r\n");
    return NULL;
}

上图我只定义了 一个 64600 长度的数组,还不够 0xFD44 字节,这是因为函数内部很多操作都会用到栈内存,不只是局部变量。

上图的代码,我运行一下,如下图:

可以正常打印,没问题,所以在我的环境里面 64600 长度的还可以接受,如果是其他的电脑,这个数值会有一点点偏差。

这时候,如果我把 64600 改成 64700 ,加 100 字节,就会里面报错,如下图:

因为访问了收保护的内存,如果真的有需要更大的内存,怎么办?st_thread_create() 函数是有一个参数可以定义申请的栈大小的,如下图,把这个值改大就可以了。


有几种情况,会使用 协程函数的栈内存。

1,协程函数内部调用函数,例如调 printf() 。

2,协程函数内部使用局部变量。

3,协程函数内部很多操作都会用到 栈内存,一个 if 都有可能用到栈内存。


相关阅读:

  1. 《Linux中mprotect()函数详解》

由于笔者的水平有限, 加之编写的同时还要参与开发工作,文中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果读者有任何宝贵意见,可以加我微信 Loken1。QQ:2338195090。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Loken2020

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值