首页 > 其他 > 详细

记一次shm_open的错误排查

时间:2021-01-20 17:29:40      阅读:110      评论:0      收藏:0      [点我收藏+]

正文

看redis的bg数据拷贝的时候想起进程的数据是cow的,想写个程序看看cow的细节,因为要用到信号量操作sem_post和sem_wait,信号量的创建依赖于共享内存对象shm_open,因为很久没使用过的这个系统调用结果导致出了乌龙,把第一个参数name给当成了路径+名字,结果创建的时候返回的对象句柄是-1, errno被设置成了EINVAL(无效参数)

int shm_open(const char *name, int oflag, mode_t mode);

b shm_open后打了一个断点进入shm_openni单步执行后, 发现shm_open先对name进行了处理,如果开头为/的话会先开头的所有/给干掉,应该是不允许name中有这样的特殊字符,这里的name因为被我当成path+name了,所以会走这个地方, man中的手册做创建的时候有时候也给name前加一个/,但是加了和不加效果是一样的。
技术分享图片

然后程序继续走,走着走着发现retq了,在中间找到了跳到retq的地方, 原来是shm_open+124中对name进行了检查看看是否还存在特殊字符/,如果存在则设置一些errno跳转到retq
技术分享图片
shm_open + 356中设置errno为EINVAL,再继续就是retq了
技术分享图片

这里有一个很奇怪的点,上面判断的shm_open+356将errno设置成了EINVAL主要是通过0x16判断得到,当然也可以通过errno的地址,后面标明了地址0x7ffff7dd3fb8,所以我们可以先打印errno的地址,然后再这段汇编里面对比查找一下,但是打印出来的结果却和汇编中给出的地址相差了8,这个点没有搞明白上st提了个问题,可能还是没看懂shm_open+356 到shm_open+365这段汇编导致的
{{uploading-image-133268.png(uploading...)}}

记一次shm_open的错误排查

原文:https://www.cnblogs.com/ishen/p/14303398.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!