ITPub博客
首页
博客
专栏
学院
社区
IT新媒体评选
发博
首页
>
>
>
编写安全代码:避免奇怪的逻辑引发的bug
编写安全代码:避免奇怪的逻辑引发的bug
作者:
u_453e1a12781dea
时间:2016-09-05 17:08:20
0
删除
编辑
ChinaUnix博主| GFree_Wind
本文版权由GFree_Wind所有,如需转载,请联系本公众号获取授权!
本文来自今天修改的一个Bug。Bug的产生完全是由于一段不合理或者奇怪的逻辑引发的。代码大致如下:
void reset_res(res_config,
new_res
)
{
old_res = res_config->res;
res_config->res = new_res;
barrier();
free_res(old_res);
}
int modify_config()
{
new_res_config = duplicate(old_res_config);
new_res = new_res();
reset_res(new_res_config, new_res)
config->res_config = new_res_config;
barrier();
free_res_config(old_res_config);
}
其中barrier可以保证所有的工作线程完成了一个循环。在reset_res中的barrier后,就保证了没有任何线程引用old_res这一地址,这样后面就可以安全的调用free_res释放old_res指向的资源了。而modify_config中的barrier同样保证了barrier后,没有任何线程再引用old_res_config了。
看上去代码写得很严谨,甚至使用了barrier保证了资源的安全释放。这样保证了不使用任何锁的条件下,完成了配置的变化。看上去很美很不错,然而却由于modify_config的不合理甚至有些奇怪的逻辑,导致了bug的产生。
下面说一下bug是如何发生的:
modify_config用于不阻塞工作线程的条件下,修改配置;
为了不阻塞工作线程,利用替换指针和barrier来完成配置的修改;
new_res_config = duplicate(old_res_config)复制旧的配置;
配置不同,需要新的资源new_res,然后调用reset_res完成res的替换和释放;
config->res_config = new_res_config; barrier()完成配置的更新;
Bug就出现在第三步。调用duplicate后,new_res_config和res_config指向了同一份资源,然后在reset_res中,这份资源被释放,而new_res_config指向了新的资源。这时bug出现了。因为目前的应用的配置仍然是res_config,其仍然指向旧资源,然而旧资源已经被释放。
那么如何修改这个Bug呢?
将第5步放到reset_res之前,代码示意如下:
config->res_config = new_res_config;
barrier();
reset_res(new_res_config, new_res)
虽然这样更正了bug。但是我觉得这样的逻辑看起来很怪。为啥?因为在更新了新的配置后,却又调用了reset_res去更新资源。这相当于new_res_config在还未准备完毕后,就更新了配置,这不免有些奇怪。
正常的逻辑应该是什么样子呢?
new_res_config = duplicate(old_config)只复制配置,不复制资源指针或者进行深拷贝;
reset_res(new_res_config, new_res) 获得新的资源赋给new_res_config;这里甚至都不需要barrier
config->res_config = new_res_config;
barrier()
小结:
其实这个bug的产生完全是由于之前错误的逻辑引起的,或者说是不好的编码风格。根源出自于duplicate函数,它只是一个memcpy,对于资源如指针来说,仅仅是一个浅拷贝。
燃爆九月!最后折扣来袭!
SACC2016
作为国内最受欢迎的架构师盛会,
2016第八届中国系统架构师大会(SACC)将于2016年10月27日-29日在北京万达索菲特大酒店撼世来袭!
大会以"架构创新之路"为主题,共设置两个主场分享时段,24个技术交流专场时段;邀请来自互联网、电子商务、金融、电信、政府、行业协会等20多个领域,150多位技术专家及行业领袖来分享他们的经验;并将吸引4000多名系统运维、架构师、及各种企业的IT决策人士参会,为他们提供最具价值的交流平台。
限时折扣!
9月28日前,订购SACC2016门票立享8.8折优惠!团购更有折上折!还不快来!
点击
“阅读原文”
立即购票!
原文作者:;如有侵权,请联系管理员删除。
上一篇:
Linux 系统 CPU 100% 异常排查实践与总结
下一篇:
Linux 中高效编写 Bash 脚本的 10 个技巧
请登录后发表评论
登录
全部评论
u_453e1a12781dea
注册时间:
2019-07-17
博文量
1982
访问量
17924
最新文章
流批一体在京东的探索与实践
高效沟通的5个原则,解决90%的沟通问题
IBM新设计,Linux性能有望大幅提升
MySQL数据库上线前要进行哪些优化?
61个案例!国资委发布!国有企业数字化转型案例汇总!
vivo统一告警平台建设与实践
两年滴滴和头条的后端开发经验!字字都是肺腑之言!
中移动离职中层自述:中国移动如何从优秀到崩溃
大数据拯救地球环境的10种方式
从技术走向管理,你准备好了么?【文末有惊喜】