Perl脚本(使用大量本地编写的模块,正在积极开发中)刚刚开始生成零星的
“尝试释放未引用的标量:SV 0xa6e685c,Perl解释器: 全局破坏期间的0x96d9008。“
消息。这总是可重复的,因为特定的命令序列总是产生消息,但是我没有设法隔离出一个简单的或独立的案例来引发它。特别是,从Perl调试器运行脚本时我还没有看到它(我可以在调试使用IPC :: Open3来运行目标脚本的脚本时得到它。)
我意识到这可能只是Perl中的一个错误,但更有可能是我正在做的事情,很可能是我对SVN :: Client的调用;但我很难找到一种方法来调查它,我想知道是否有人有任何指针。
Perl 5.10.0;各种版本的Fedora Linux。我将在Perl 5.12上尝试它,但除非它也在那里出现,否则它对我没有帮助。 编辑:在5.12中可靠地提供消息的特定情况不在5.12中。不幸的是,这并没有真正告诉我任何事情。
答案 0 :(得分:2)
迟到的答案,但我写了一篇关于这个特定主题的长篇文章,应该有助于调试:The Dreaded "Attempt to free unreferenced scalar"。
答案 1 :(得分:1)
这通常与线程问题有关,特别是在将变量从一个线程传递到另一个线程中运行的子例程时。这是模式的抽象示例:
<强> A.pl 强>
....
my $dummy;
threads->create("B::c", ($dummy));
....
<强> B.pm 强>
....
sub c{...}
....
我意识到在“加载本地编写的模块”中搜索类似于此的东西并不容易。也许你可以删除你的程序块,直到找到一些能改变行为的东西;这应该可以帮助你解决问题。
答案 2 :(得分:1)
我也经常遇到这些消息(在使用fork
的代码中)和全局破坏阶段中的分段错误的相关问题(也就是说,程序可以正常完成,但在此过程中出错全局销毁可以使程序以非零退出代码退出。我也不知道这些问题是否可以修复,但它们通常可以解决。
首先,使用全局变量来检测您是否处于全局销毁阶段:
our $_GLOBAL_DESTRUCTION = 0;
END { $_GLOBAL_DESTRUCTION = 1; }
(另请参阅Perl v中可用的${^GLOBAL_PHASE}
变量&gt; = 5.13.7)
然后避免在全局销毁阶段运行麻烦的代码:
sub MyObject::DESTROY {
return if $_GLOBAL_DESTRUCTION;
... # else proceed
}
sub other_function_that_frees_unreferenced_scalars {
return if $_GLOBAL_DESTRUCTION;
...
}
答案 3 :(得分:0)
检查任何引用指针的typeglobs,例如散列哈希的类型。我遇到了一个用于在不同的数组散列之间切换的typeglob。使用typeglob和原始哈希名称删除条目时出现错误。使用没有嵌套的简单哈希或摆脱typeglob消除了这个问题。
答案 4 :(得分:0)
foreach (@var)
是另一个很好的候选人。
以下代码给了我这个警告:
foreach (@list1) {
my ($i, $j) = @$_;
my $k = get_k($i, $j);
foreach (@$k) {
sub_that_uses_fork($_);
}
}
但以下没有:
while (scalar(@list1)) {
my ($i, $j) = @{shift(@list1)};
my $k = get_k($i, $j);
foreach (@$k) {
sub_that_uses_fork($_);
}
}