antlr4中NoViableAltException 异常引起程序崩溃

ANTLR4在遇到NoViableAltException时可能导致程序coredump。问题出在ParserATNSimulator.cpp的execATN和execATNWithFullContext函数,异常处理不当引起double free崩溃。解决方案是调整析构函数参数,避免异常对象过早释放。文章也提到C++异常处理中对象生命周期的问题。
摘要由CSDN通过智能技术生成

NoViableAltException 异常引起的 coredump 问题

使用antlr4解析时,在遇到 NoViableAltException 异常的时候,有些情况下会遇到 coredump 错误,如果仅仅抛出异常还好,但是出现崩溃问题在项目中就是大问题了,这个必须得找到并解决。

antlr4 解析时,在 ParserATNSimulator.cpp 中的 execATN 函数的 179 行,和 execATNWithFullContext 函数的 345 行,都会调用

NoViableAltException e = noViableAlt();
// 创建 NoViableAltException 对象

179:

NoViableAltException e = noViableAlt(input, outerContext, previousD->configs.get(), startIndex, false);

NoViableAltException 中的 _deleteConfigs 的值为 false,析构函数为

~NoViableAltException() {
	if (_deleteConfigs)
		delete _deadEndConfigs;
}

354:

NoViableAltException e = noViableAlt(input, outerContext, previous, startIndex, previous != s0);

因为 previous != s0,所以 _deleteConfigs 的值为 true,所以析构的时候会 delete _deadEndConfigs

此时,在 DefaultErrorStrategy.cpp:148 行,

recognizer->notifyErrorListeners(..., std::make_exception_ptr(e))

std::make_exception_ptr Creates an std::exception_ptr that holds a reference to a copy of e.

参数为保持 NoViableAltException 拷贝的一个引用的变量(std::exception_ptr)。如果 NoViableAltException 被析构了,那么其所指向的 _deadEndConfigs 指针也会被释放,但是 NoViableAltException 这个变量在后面还会被释放一次,造成 double free 的程序崩溃。

这里只需要将 354 行按照 179 行一样,将函数最后一个参数设置为 false 即可。
因为不懂 antlr4 原理,那部分代码也没有看懂,作者为什么抛出那样的异常不是很明白,也就没法修改了。我提了一个 issue,感兴趣的可以关注一下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猫步旅人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值