我已经搜索了这个问题的答案了很长一段时间,我认为很多都与我对子进程模块的工作方式不熟悉有关。如果有人有兴趣,这是一个模糊测试程序。另外,我应该提到这一切都是在Linux中完成的(我认为这是相关的)我有一些像这样的代码:
# open and run a process and log get return code and stderr information
process = subprocess.Popen([app, file_name], stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
return_code = process.wait()
err_msg = process.communicate()[1]
# insert results into an sqlite database log
log_cur.execute('''INSERT INTO log (return_code, error_msg)
VALUES (?,?)''', [unicode(return_code), unicode(error_msg)])
log_db.commit()
在100次中有99次可以正常工作但偶尔会出现类似于以下错误:
UnicodeDecodeError:'utf8'编解码器无法解码位置43的字节0xce:无效的连续字节
编辑:完整跟踪
Traceback (most recent call last):
File "openscadfuzzer.py", line 72, in <module>
VALUES (?,?)''', [crashed, err_msg.decode('utf-8')])
File "/home/username/workspace/GeneralPythonEnv/openscadfuzzer/lib/python2.7/encodings/utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xdb in position 881: invalid continuation byte
这是子进程的问题,我使用它运行的应用程序还是我的代码?任何指针都会受到赞赏(尤其是当它与子进程stdout和stderr的正确用法有关时)。
答案 0 :(得分:2)
我的猜测是问题在于这个问题:
unicode(error_msg)
error_msg的类型是什么?我相当确定默认情况下子进程API将返回子程序输出的原始字节,对unicode
的调用尝试通过假设某些编码将字节转换为字符(代码点)(在本例中为utf8) )。
我的猜测是字节无效utf8,但是有效的latin1。您可以指定在字节和字符之间转换的编解码器:
error_msg.decode('latin1')
这是一个有希望展示问题和解决方法的示例:
>>> b'h\xcello'.decode('utf8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.2/encodings/utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xce in position 1: invalid continuation byte
>>> b'h\xcello'.decode('latin1')
'hÎllo'
更好的解决方案可能是让您的子进程输出utf8,但这取决于您的数据库能够存储的数据。
答案 1 :(得分:1)
你可以在这里找到非常好的子流程教程http://pymotw.com/2/subprocess/及其官方文档:http://docs.python.org/2/library/subprocess.html,但是根据你获得的错误的格式,似乎不是你的代码,而是你的获取错误的应用程序,而您只是看到它,因为您正在收集输出。要确认这一点,您可以使用简单的bash
循环在代码外部运行您的应用程序,以查看是否可以再次捕获错误并在代码中检查应用程序的退出代码 - 当您看到错误时如果应用程序正确提供退出代码,它应该与0
不同。