为什么这个 Haxe try-catch 块在对 C++ 目标使用发布模式时仍然崩溃
Why is this Haxe try-catch block still crashing, when using Release mode for C++ target
我有一个 HaxeFlixel 项目,它在调试模式下针对其他目标运行正常,包括 flash、neko 和 windows。但是在 发布模式 中定位 Windows,我遇到了意外崩溃,令人惊讶的是它发生在 try-catch 块中。这是崩溃函数:
/**
* Will safely scan a parent node's children, search for a child by name, and return it's text.
* @param parent an Fast object that is parent of the `nodeNamed` node
* @param nodeName the node's name or a comma-separated path to the child (will scan recursively)
* @return node's text as String, or null if child is not there
*/
public static function getNodeText(parent:Fast, nodeName:String):String {
try {
var _node : Fast = getNodeNamed(parent, nodeName);
//if (_node == null)
// return null;
// next line will crash if _node is null
var it :Iterator<Xml> = _node.x.iterator();
if ( it == null || !it.hasNext() )
return null;
var v = it.next();
var n = it.next();
if( n != null ) {
if( v.nodeType == Xml.PCData && n.nodeType == Xml.CData && StringTools.trim(v.nodeValue) == "" ) {
var n2 = it.next();
if( n2 == null || (n2.nodeType == Xml.PCData && StringTools.trim(n2.nodeValue) == "" && it.next() == null) )
return n.nodeValue;
}
//does not only have data (has children)
return null;
}
if( v.nodeType != Xml.PCData && v.nodeType != Xml.CData )
//does not have data";
return null;
return v.nodeValue;
}catch (err:Dynamic) {
trace("Failed parsing node Text [" + nodeName+"] " + err );
return null;
}
}
通过启用 if (_node == null) return null;
行,它再次安全工作。通过捕获 Dynamic
错误,我认为我应该捕获所有可能的错误类型!为什么会这样?为什么它会出现在发布模式中?
我的 IDE 是 FlashDevelop,我使用的是 HaxeFlixel 3.3.6、lime 0.9.7 和 openFL 1.4.0,如果这有什么不同的话
编辑:我怀疑这与翻译的 C++ 代码如何错过 Dynamic
异常有关。等效生成的 C++ 代码是:
STATIC_HX_DEFINE_DYNAMIC_FUNC2(BaxXML_obj,_getNodeNamed,return )
::String BaxXML_obj::getNodeText( ::haxe::xml::Fast parent,::String nodeName){
HX_STACK_FRAME("bax.utils.BaxXML","getNodeText",0x4a152f07,"bax.utils.BaxXML.getNodeText","bax/utils/BaxXML.hx",56,0xf6e2d3cc)
HX_STACK_ARG(parent,"parent")
HX_STACK_ARG(nodeName,"nodeName")
HX_STACK_LINE(56)
try
{
HX_STACK_CATCHABLE(Dynamic, 0);
{
HX_STACK_LINE(57)
::haxe::xml::Fast _node = ::bax::utils::BaxXML_obj::getNodeNamed(parent,nodeName); HX_STACK_VAR(_node,"_node");
HX_STACK_LINE(63)
Dynamic it = _node->x->iterator(); HX_STACK_VAR(it,"it");
// ... Let's skip the irrelevant code
}
catch(Dynamic __e){
{
HX_STACK_BEGIN_CATCH
Dynamic err = __e;{
HX_STACK_LINE(82)
::String _g5 = ::Std_obj::string(err); HX_STACK_VAR(_g5,"_g5");
HX_STACK_LINE(82)
::String _g6 = (((HX_CSTRING("Failed parsing node Text [") + nodeName) + HX_CSTRING("] ")) + _g5); HX_STACK_VAR(_g6,"_g6");
HX_STACK_LINE(82)
::haxe::Log_obj::trace(_g6,hx::SourceInfo(HX_CSTRING("BaxXML.hx"),82,HX_CSTRING("bax.utils.BaxXML"),HX_CSTRING("getNodeText")));
HX_STACK_LINE(83)
return null();
}
}
}
HX_STACK_LINE(56)
return null();
}
这看起来很奇怪,一些问题可能有助于解决它。
- 看起来您对 xml 的外观做了相当多的假设(做一些手动操作
it.next()
),这是为什么呢?
- 你为什么要使用这个大屁股的 try-catch 块?
- getNodeNamed怎么看,好像可以return
null
.
- 您有示例xml 可以用来测试吗?
我想这归结为 C++ 如何处理空指针异常。它没有!
更多信息here or here
你定义了什么haxedefs?
将这些添加到您的 project.xml 中可能会有所帮助:
<haxedef name="HXCPP_CHECK_POINTER"/> <!--makes null references cause errors-->
<haxedef name="HXCPP_STACK_LINE" /> <!--if you want line numbers-->
<haxedef name="HXCPP_STACK_TRACE"/> <!--if you want stack traces-->
您也可以试试 crashdumper 库:
https://github.com/larsiusprime/crashdumper
(Crashdumper 将默认打开 HXCPP_CHECK_POINTER 作为其 include.xml 的一部分,并将为 hxcpp 的错误和 openfl/lime 的未捕获错误事件设置挂钩)
我有一个 HaxeFlixel 项目,它在调试模式下针对其他目标运行正常,包括 flash、neko 和 windows。但是在 发布模式 中定位 Windows,我遇到了意外崩溃,令人惊讶的是它发生在 try-catch 块中。这是崩溃函数:
/**
* Will safely scan a parent node's children, search for a child by name, and return it's text.
* @param parent an Fast object that is parent of the `nodeNamed` node
* @param nodeName the node's name or a comma-separated path to the child (will scan recursively)
* @return node's text as String, or null if child is not there
*/
public static function getNodeText(parent:Fast, nodeName:String):String {
try {
var _node : Fast = getNodeNamed(parent, nodeName);
//if (_node == null)
// return null;
// next line will crash if _node is null
var it :Iterator<Xml> = _node.x.iterator();
if ( it == null || !it.hasNext() )
return null;
var v = it.next();
var n = it.next();
if( n != null ) {
if( v.nodeType == Xml.PCData && n.nodeType == Xml.CData && StringTools.trim(v.nodeValue) == "" ) {
var n2 = it.next();
if( n2 == null || (n2.nodeType == Xml.PCData && StringTools.trim(n2.nodeValue) == "" && it.next() == null) )
return n.nodeValue;
}
//does not only have data (has children)
return null;
}
if( v.nodeType != Xml.PCData && v.nodeType != Xml.CData )
//does not have data";
return null;
return v.nodeValue;
}catch (err:Dynamic) {
trace("Failed parsing node Text [" + nodeName+"] " + err );
return null;
}
}
通过启用 if (_node == null) return null;
行,它再次安全工作。通过捕获 Dynamic
错误,我认为我应该捕获所有可能的错误类型!为什么会这样?为什么它会出现在发布模式中?
我的 IDE 是 FlashDevelop,我使用的是 HaxeFlixel 3.3.6、lime 0.9.7 和 openFL 1.4.0,如果这有什么不同的话
编辑:我怀疑这与翻译的 C++ 代码如何错过 Dynamic
异常有关。等效生成的 C++ 代码是:
STATIC_HX_DEFINE_DYNAMIC_FUNC2(BaxXML_obj,_getNodeNamed,return )
::String BaxXML_obj::getNodeText( ::haxe::xml::Fast parent,::String nodeName){
HX_STACK_FRAME("bax.utils.BaxXML","getNodeText",0x4a152f07,"bax.utils.BaxXML.getNodeText","bax/utils/BaxXML.hx",56,0xf6e2d3cc)
HX_STACK_ARG(parent,"parent")
HX_STACK_ARG(nodeName,"nodeName")
HX_STACK_LINE(56)
try
{
HX_STACK_CATCHABLE(Dynamic, 0);
{
HX_STACK_LINE(57)
::haxe::xml::Fast _node = ::bax::utils::BaxXML_obj::getNodeNamed(parent,nodeName); HX_STACK_VAR(_node,"_node");
HX_STACK_LINE(63)
Dynamic it = _node->x->iterator(); HX_STACK_VAR(it,"it");
// ... Let's skip the irrelevant code
}
catch(Dynamic __e){
{
HX_STACK_BEGIN_CATCH
Dynamic err = __e;{
HX_STACK_LINE(82)
::String _g5 = ::Std_obj::string(err); HX_STACK_VAR(_g5,"_g5");
HX_STACK_LINE(82)
::String _g6 = (((HX_CSTRING("Failed parsing node Text [") + nodeName) + HX_CSTRING("] ")) + _g5); HX_STACK_VAR(_g6,"_g6");
HX_STACK_LINE(82)
::haxe::Log_obj::trace(_g6,hx::SourceInfo(HX_CSTRING("BaxXML.hx"),82,HX_CSTRING("bax.utils.BaxXML"),HX_CSTRING("getNodeText")));
HX_STACK_LINE(83)
return null();
}
}
}
HX_STACK_LINE(56)
return null();
}
这看起来很奇怪,一些问题可能有助于解决它。
- 看起来您对 xml 的外观做了相当多的假设(做一些手动操作
it.next()
),这是为什么呢? - 你为什么要使用这个大屁股的 try-catch 块?
- getNodeNamed怎么看,好像可以return
null
. - 您有示例xml 可以用来测试吗?
我想这归结为 C++ 如何处理空指针异常。它没有!
更多信息here or here
你定义了什么haxedefs?
将这些添加到您的 project.xml 中可能会有所帮助:
<haxedef name="HXCPP_CHECK_POINTER"/> <!--makes null references cause errors-->
<haxedef name="HXCPP_STACK_LINE" /> <!--if you want line numbers-->
<haxedef name="HXCPP_STACK_TRACE"/> <!--if you want stack traces-->
您也可以试试 crashdumper 库: https://github.com/larsiusprime/crashdumper
(Crashdumper 将默认打开 HXCPP_CHECK_POINTER 作为其 include.xml 的一部分,并将为 hxcpp 的错误和 openfl/lime 的未捕获错误事件设置挂钩)