带有XML Twig-seg错误的Perl脚本,子脚本以信号11终止



我正在尝试运行一个perl脚本,其中正在构建一些小树枝。这个脚本应该获取xml文件,并返回作为文件中的一个属性存在的版本号。每次我试图解析一个大文件(23MB)时,脚本都会崩溃,出现以下错误-

"Child 341 terminated with signal 11".

调用子程序的代码,这些子程序将获得所需的属性-

my $version = $strm_obj->get_attr(file=>$file1,tag=>"config",attr=>"contentversion");
print "Version of $file1 is $version n";
my $globalversion = $strm_obj->get_attr(file=>$file2,tag=>"config",attr=>"globalcontentversion");
print "Version of $file2 is $globalversion n";

获取所需属性的子程序-

sub get_attr{
my ($self,%args) = @_;
my $file = $args{file};
my $tag = $args{tag};
my $attr = $args{attr};
my $val;
$self->{_ATTR} = $attr;
$self->{_TAG} = $tag;
test_log(DEBUG,"Value of tag is $tag, attribute is $attr");
my $twig= XML::Twig->new(
twig_roots => { $tag
=> sub {$self->get_attr_helper(@_,$tag,$val); } } )
->parsefile($file);
if ($val){
test_log(INFO,"value of attribute $attr is $val");
}
if (!$val){
test_log(INFO,"The attribute $attr that you are looking for, is not present in $file");
return -1;
}
$twig->purge;
$twig->dispose;
return $val;
}
sub get_attr_helper{
my($self,$obj,$tag,$act_tag,$val) = @_;
my $attr = $self->{_ATTR};
#print "my attr is $attrn";
for my $node ($tag->findnodes("//$self->{_TAG}")){
if ($node->att("$attr")){
$$val = $node->att("$attr");
}
}
$obj->purge;
}

xml文件的格式如下:

$file1-

<config contentversion="378">
<tag1>
.
.
.
<tag n>
</config>

$file2-

<config globalcontentversion="378">
<tag1>
.
.
.
<tag n>
</config>

我在这里无法真正提供实际的xml文件。

我知道这个脚本最多会占用我机器20%的内存(2GB RAM)。

我环顾四周,一直找不到解决这个问题的办法。

如何消除seg故障?

很难给出具体的答案,因为分段故障意味着某个东西正在混乱地崩溃(这是一个基于内存的问题)。

XML很容易占用大量内存,而且在很大程度上,XML::Twig最大的优势之一是它能够使用twig_handlerspurge进行解析和丢弃。

这使得它非常适合从XML中部分提取内容。

我看不出是什么给了你一个segfault,但在perl中,你不会经常得到segfault——它很可能是外部的。

除此之外,您似乎正在做一些非常复杂的事情来从文件中提取版本号。(这是假设我没有误读你想要提取的内容)。

这样的东西不适合你的需要吗?:

use strict;
use warnings;
use XML::Twig;
sub get_attr {
my ( $self, %args ) = @_;
my $file = $args{file};
my $tag  = $args{tag};
my $attr = $args{attr};
my $twig = XML::Twig->new()->parsefile($file);
my $val = $twig->root->first_child($tag)->att($attr);
#maybe error check to see if 'first_child($tag)' is defined first?
return $val;
}

尽管如果你的"文档根"总是你试图提取的"配置"分支,你可以进一步简化:

my $val  = $twig->root->att($attr);

我已经试过了——到目前为止,它对你给出的两个样本都有效。不过,如果你仍然在分段,我会考虑检查你安装了什么。

(使用"树枝处理程序"方法捕获标记可能是值得的,但我认为这不是特别必要的,因为最大的优势是边清除边清除,考虑到问题的规模,这似乎没有必要)。

XML::Twig:中列出的一个错误

http://search.cpan.org/~mirod/XML-Twig-3.48/Twig.pm#BUGS

解析过程中的segfault当使用5.16之前的Perl版本解析大型文档或许多小型文档时,就会发生这种情况。

这是由于Perl中处理弱引用的方式存在错误。

修复方法是升级到Perl5.16或更高版本(perlbrew是一个很好的工具,可以在同一台机器上管理多个Perl安装)。

另一种不推荐的解决问题的方法是通过编写XML::Twig::_set_weakrefs(0)来关闭弱引用;位于代码顶部。这是完全不支持的,并可能导致其他问题,尽管,

但我不确定这是否适用于您,因为我不会真正称"23MB"为巨大的XML。(甚至要记住,XML的内存占用大约是10倍)。

相关内容

  • 没有找到相关文章

最新更新