gpsd返回不完整DEVICES消息引发JSON解析错误问题咨询
问题现象
在小型Prometheus部署环境中收到数百条格式如下的syslog日志:
Sep 23 08:09:01 raspi4-bolli gpsd-exporter[20242]: 0 {"class":"DEVICES","devices":[{"class":"DEVICE","path":"/dev/stdin","driver":"NMEA0183","activated":"2021-09-23T06:08:59.997Z","flags":1,"native":0,"bps":9600,"parity":"}]} Sep 23 08:09:01 raspi4-bolli gpsd-exporter[20242]: Invalid control character at: line 1 column 173 (char 172)
编写最小可复现代码如下:
import gpsd gpsd.connect()
运行后输出结果:
{"class":"VERSION","release":"3.17","rev":"3.17","proto_major":3,"proto_minor":12} 0 {"class":"DEVICES","devices":[{"class":"DEVICE","path":"/dev/stdin","driver":"NMEA0183","activated":"2021-09-23T06:35:47.017Z","flags":1,"native":0,"bps":9600,"parity":"}]} 0 {"class":"DEVICES","devices":[{"class":"DEVICE","path":"/dev/stdin","driver":"NMEA0183","activated":"2021-09-23T06:35:47.017Z","flags":1,"native":0,"bps":9600,"parity":"}]} Invalid control character at: line 1 column 173 (char 172) 1 {"class":"WATCH","enable":true,"json":false,"nmea":false,"raw":0,"scaled":false,"timing":false,"split24":false,"pps":false}
最终确认gpsd返回的DEVICES消息存在不完整问题:"parity":"}]}字段截断。
根因定位
该问题是gpsd 3.17版本的已知缺陷,与Python客户端库无关:
- gpsd 3.17生成DEVICES类JSON响应时,
parity字段的序列化逻辑存在边界错误,当串口奇偶校验位未配置或设备返回空值时,序列化逻辑未正确补全引号闭合,直接拼接后续JSON结构,导致字段截断、JSON格式非法。 - 报错中提到的无效控制字符,是JSON解析器读到未闭合的引号后,将后续的
}、]等符号按字符串内容解析,读到结构末尾时触发的格式校验错误。
解决方法
- 优先方案:升级gpsd版本
升级到3.19及以上版本,该版本已修复DEVICES响应的JSON序列化缺陷,升级后重启gpsd服务即可解决截断问题。 - 临时规避方案:客户端兼容处理
若暂时无法升级gpsd,可在Python客户端中对返回的原始报文做预处理,匹配不完整的"parity":"}]}结构,替换为合法的"parity":""}]}后再做JSON解析,临时规避解析报错。 - 优化方案:配置明确的串口参数
给gpsd连接的GPS设备配置明确的奇偶校验参数(无校验、奇校验、偶校验三选一),避免gpsd读取到空的校验位值触发序列化逻辑缺陷。
内容的提问来源于stack exchange,提问作者Michael Bolli
相关产品推荐
相关产品推荐

