带有XML Twig seg perulting的Perl脚本,子节点以信号11终止

时间:2014-01-03 00:02:48

标签: xml perl xml-parsing segmentation-fault xml-twig

我正在尝试运行一个perl脚本,其中构建了一些细枝。 此脚本应采用xml文件并返回在文件中作为属性存在的版本号。 每次我尝试解析一个大文件(23 MB)时,脚本都会崩溃 -

"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 $attr\n";
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故障?

1 个答案:

答案 0 :(得分:1)

很难给出具体的答案,因为细分错误意味着某些东西的混乱(这是一个基于记忆的问题)。

XML非常容易占用大量内存,而且在很大程度上,XML :: Twig的最大优势之一就是它能够使用twig_handlers和{{来解析和丢弃1}}。

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

我无法明确看出是什么给了你一个段错误,但是 - 在perl中,你经常得不到段错误,它可能是外在的东西。

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

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

purge

虽然你的&#39; doc root&#39;永远是那个&#39; config&#39;您尝试提取的分支,您可以进一步简化:

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;
}

我试过这个 - 它适用于你迄今为止给出的两个样本。如果您仍然在进行分类,我会考虑检查您已安装的内容。

(可能值得做一个&#39; twig处理程序&#39;陷入标签的方法,但我不会发现这是特别必要的,因为随着你去的大优势将被清除考虑到问题的大小,这看起来并不合适)。

XML :: Twig中列出的错误:

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

  

解析期间的段错误   在使用5.16之前的Perl版本解析大型文档或许多小文档时会发生这种情况。

     

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

     

修复程序要么升级到Perl 5.16或更高版本(perlbrew是在同一台机器上管理多个perl安装的好工具)。

     

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

我不确定这适用于你,因为我不会真的打电话给23MB&#39;一个巨大的XML。 (即使记住XML的内存占用量大约是10倍)。