企业新闻
企业新闻 行业新闻 安全时讯
Python程序异常退出问题的解决与思考
2019-12-31 浏览:57

Python编程语言是一种解释性语言,给开发人员的映像就是简单易学、面向对象。并且由于Python有垃圾回收机制,不需要理会内存的申请和释放操作,这给开发人员带来了极大的方便。不像C语言编程,时刻要注意内存的申请和释放,避免出现内存泄漏以及内存重复释放的问题。
某天在某台设备上,测试人员发现该设备上的Python进程发生异常退出的情况(CPython环境)。问题出现后,首先想到的就是查看日志信息。查看错误日志,出现“double free or corruption”错误信息。而且调试信息里面并没有出现exception信息打印。也就是说该错误无法被try/exception机制捕捉。进一步查阅了“double free or corruption”错误,该问题类似于C程序中的内存重复释放。


 图片1


等等,Python代码中不是没有内存操作相关的代码吗?为什么会出现类似于C程序中的内存问题?原来, Python的底层是用 C 语言写的,很多标准库和第三方库也都是用 C 语言写的。在底层的调用上出现问题,是可能出现内存相关的问题的。
如果要定位问题,必须先得复现问题。根据问题出现的现场环境和复现操作,初步定位到一个具体的模块。通过改写并简化相关模块的代码(注释掉某些线程代码),按照测试人员所做的操作进行复现。该问题需要在长时间重复做某种操作才会出现。在触发问题的时间上有一定的偶然性,每次复现时长都不一定(7-15分钟之间),但是出问题是必然的。通过不断的修改代码并复现,问题集中到了该模块的某个流程相关的代码。该流程包括同一个进程中的两个线程。既然“double free or corruption”错误是内存重复释放的问题,那就重点关注资源的申请和释放操作相关的代码。
此时,一个全局LIST类型的变量C出现在视野中,该变量会在线程A中进行初始化(清空),在线程B中会进行遍历以及append操作。这与资源的申请和释放操作有很大的相关性。


图片2


LIST类型变量不是线程安全的。提到线程安全,大家会想到要加锁之类的操作。同时Python开发人员对GIL锁并不陌生。GIL的作用是,对于一个解释器,只能有一个线程在执行字节码。所以任何时刻只有一条字节码在被一个线程执行。GIL在字节码层面上保证了线程安全,但是Python多线程包里依然提供了加锁机制,这是为何?
假设有个操作,比如x+= 1,这个操作需要多个字节码操作,在执行这个操作的多条字节码期间,可能会发生线程切换,这样就出现了线程竞争的情况。如下图,“INPLACE_ADD”就是一条字节码。


图片3


也可以理解成GIL锁保证的是字节码操作的原子性,而不是Python程序中某条语句执行的原子性。对于LIST变量的初始化以及append操作,肯定也可以拆分成多个字节码操作。那么在线程A中LIST变量C的初始化操作的正在执行过程中,是很有可能被线程B打断来执行LIST变量C的append操作的;或者线程B执行LIST变量C的append操作的过程中,被线程A打断来执行LIST变量C的初始化操作。总之,GIL锁无法保证LIST变量C某个操作的原子性,必须依靠Python的线程同步机制,如对关键全局变量加互斥锁。
在原有代码中,由于编程人员的疏忽,没有对LIST变量C加互斥锁操作。通过对LIST变量C加互斥锁操作,执行之前的问题复现操作,进程运行正常,没有出现异常退出的情况,问题完美解决。
通过上述问题的原因分析和问题解决,总结如下:
1.在Python程序中必须要注意全局变量在多线程中的使用。如果是非线程安全变量,需要利用Python的同步机制,如互斥锁。否则会出现意想不到的问题,随机性很大,并且出现的问题无法被try/exception机制捕捉到,问题复现和问题的定位都非常困难。
2.GIL锁是无法保证非线程安全变量在多线程中使用的安全性,必须依靠Python的线程同步机制,如对非线程安全变量加互斥锁。
3.常见的非线程安全变量包括LIST(列表)、DICT(字典)等;常见的线程安全变量包括Queue(队列)。

本文由北京天地和兴科技有限公司原创,转载时请注明:工控安全网址:http://www.tdhxkj.com/
关于我们
公司简介 企业文化
发展历程 企业荣誉
人才招聘
联系我们
公司简介
企业文化

公司地址:北京市海淀区中关村软件园8号 华夏科技大厦三层

服务热线:400-810-8981 / 010-82896289

E-MAIL:tdhx@tdhxkj.com

友情链接
国家电网 中国大唐集团 中国华电 国家能源集团 华能集团 中核集团 中国石油 酒钢集团 马钢集团 中国通号 中国铁路 上汽集团 北汽集团 东风柳汽 中国海油 SIMENS Honeywell EMERSON 和利时 研华科技 工控安全 浙江大学 华北电力大学
扫一扫,关注天地和兴公众微信号