一段时间后 eval 无法匹配正则表达式
我从用户那里得到的第一个输入是节点的树(具有显着的高度和深度)。每个节点都包含一个正则表达式和修饰符。这棵树被保存在内存中。这仅在应用程序启动时执行一次。
第二个输入是从树的根节点开始匹配的值,直到找到完全匹配的叶节点(深度优先搜索)。匹配确定如下:
my $evalstr = <<EOEVAL;
if(\$input_value =~ /\$node_regex/$node_modifiers){
1;
}else{
-1;
}
EOEVAL
no strict 'refs';
my $return_value = eval "no strict;$evalstr";
第二输入由源在应用程序的整个生命周期中连续提供。
问题: 上面的代码在一段时间内(大约 10 小时)运行得很好,但是在连续输入这一次之后,eval 不断开始失败,我在 $return_value 中得到 -1。应用程序的所有其他功能都工作得很好,包括其他比较语句。如果我重新启动应用程序,匹配会再次启动并给出正确的结果。
观察结果: 1)我多次收到深度递归警告,但我在某处读到这是正常的,因为考虑到输入树的大小,我的堆栈大小多次会超过 100。 2)如果我使用简单的逻辑进行正则表达式匹配而没有如上所述的 eval,那么应用程序的任何连续运行都不会出现任何问题。
if($input_value =~ /$node_regex/){
$return_value=1;
}else{
$return_value=-1;
}
但随后我必须牺牲动态修饰符,按照 Dynamic修饰符
检查: 1)我检查了$@,但它是空的。 2)还打印了$input_value、$node_regex和$node_modifiers的各自值,它们是正确的并且应该与故障点处的正则表达式匹配。 3) 我检查了内存使用情况,但随着时间的推移,perl 进程的内存使用情况相当稳定。 4)使用perl 5.8.8然后将其更新到5.12,但仍然面临同样的问题。
问题 : 造成上述问题的原因可能是什么?为什么一段时间后会失败,但重新启动应用程序后却可以正常工作?
I get first input from user which is a tree (having significant height and depth) of nodes. Each of the node contains a regex and modifiers. This tree gets saved in memory. This is taken only once at the application startup.
The second input is a value which is matched starting at the root node of the tree till an exact matching leaf node is found (Depth First Search). The match is determined as follows :
my $evalstr = <<EOEVAL;
if(\$input_value =~ /\$node_regex/$node_modifiers){
1;
}else{
-1;
}
EOEVAL
no strict 'refs';
my $return_value = eval "no strict;$evalstr";
The second input is provided continuously throughout the application's life time by a source.
problem:
The above code works very well for some time (approx. 10 hours), but after continuous input for this time, the eval continuously starts failing and I get -1 in $return_value. All other features of the application work very fine including other comparison statements.If I restart the application, the matching again starts and gives proper results.
Observations:
1) I get deep recursion warning many times, but I read somewhere it is normal as stack size for me would be more than 100 many a times, considering the size of the input tree.
2) If I use simple logic for regex match without eval as above, I don't get any issue for any continuous run of the application.
if($input_value =~ /$node_regex/){
$return_value=1;
}else{
$return_value=-1;
}
but then I have to sacrifice dynamic modifiers, as per Dynamic Modifiers
Checks:
1) I checked $@ but it is empty.
2) Also printed the respective values of $input_value,$node_regex and $node_modifiers, they are correct and should have matched the value with regex at the failure point.
3) I checked for memory usage, but it's fairly constant over the time for the perl process.
4) Was using perl 5.8.8 then updated it to 5.12, but still face the same issue.
Question :
What could be the cause of above issue? Why it fails after some time, but works well when the application is restarted?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
一个明确的答案需要比我更多的 Perl 内部知识。但是考虑到您正在做的事情,连续解析大树,似乎可以安全地假设已达到某些限制,某些资源已耗尽。我会仔细检查事情并确保在解析的每次迭代之间释放所有资源。我会特别关注复杂结构中的循环引用,并确保不存在循环引用。
A definitive answer would require more knowledge of perl internals than I have. But given what you are doing, continuous parsing of large trees, it seems safe to assume that some limit is being reached, some resource is exhausted. I would take a close look at things and make sure that all resources are being released between each iteration of a parse. I would be especially concerned with circular references in the complex structures, and making sure that there are none.