我正在使用Term :: EditLine在perl中编写基于EditLine的应用程序。在大多数情况下,一切都很好。我注意到了什么看起来像是一个内存管理问题,我想知道是否有人看到类似的东西或知道某种解决方法。
我编写了一个函数来完成命令并将其绑定到一个键。它在适当的时候被调用,似乎有效。问题是如果我的回调函数操作大型数组,那么虽然命令完成仍然有效,但当Term :: EditLine :: gets返回时,它会返回undef(并且perl有时会出现seg错误)。
问题与完成功能实际对命令行的作用无关。它似乎只与函数分配的内存量有关。
这是一个提炼的例子:
#!/usr/bin/env perl
use strict;
use Term::EditLine qw(CC_REFRESH);
my $el = Term::EditLine->new( 'demo' );
$el->set_prompt( 'prompt> ' );
$el->add_fun( 'my-completer', 'Test completer', &complete );
$el->bind( '^I', 'my-completer' );
while( 1 ) {
$_ = $el->gets();
last if not defined $_;
print "$_\n";
last if $_ =~ /^exit/;
}
exit(0);
sub complete {
my $el = shift;
my @dummy;
foreach my $i ( 0 .. 1000 ) {
push @dummy, "i$i";
}
my @dummy2 = @dummy;
$el->insertstr( 'hello' );
return CC_REFRESH;
}
如果@dummy代码被注释掉,那么它就可以了。有趣的是,我需要将@dummy复制到@ dummy2以使其失败 - 如果永远不使用@dummy,perl可能会进行优化。
如果您尝试此操作,则按TAB(^ I)将在命令行中插入“hello”。按返回后,gets将返回undef,这将导致while循环中断,并且perl将在尝试关闭时发生故障。
看起来perl正在分配libedit正在使用的内存,所以我假设在XS for Term :: EditLine中有些东西不太正确。我不知道XS是否足以自己调试它。有没有人有建议?