在一個小測試文件,我可以運行文件句柄和XML ::簡單 - >內存損壞。不能隔離問題
#!/usr/bin/perl
use warnings;
use strict;
use open qw{:utf8 :std};
use XML::Simple;
my @cmdline = ("hg", "log", "-v", "--style", "xml");
open my $xml, "@cmdline |";
my $xmllog = XMLin($xml, ForceArray => ['logentry', 'parent', 'copy', 'path']);
foreach my $rev (@{$xmllog->{logentry}}) {
#do stuff
}
,它工作正常。當運行在一個更大的程序相同的代碼(具有相同的XML輸入),將其與
*** glibc detected *** /usr/bin/perl: malloc(): memory corruption: 0x0a40e308 ***
(full crash log @ pastebin.com)終止
但是,如果我做交流
#open my $xml, "@cmdline |";
my $xml = `@cmdline`;
然後它可以工作(在兩個文件中),所以對於我來說這更像是一個好奇心問題,而不是真正的問題。
- 有沒有人有什麼關於我的測試用例和更大的代碼庫之間的區別可能是什麼?
- 有沒有速度/記憶/?在不同的命令調用中的區別?最佳實踐?
Debian Sid:Perl 5.12.4-1。
(這是我的第一個Perl的遭遇,所以不要以爲太多關於我「應該」知道的語言。我只是一頭扎進現有的代碼。)
(較大的項目是ikiwiki,所以該代碼是不是祕密,但我不知道去哪裏找的麻煩,我可以不包括在這個帖子實際原因的所有代碼。這涉及到水銀後端)。
由於根據cjm的建議,我加了print "$_\n" for sort grep /XML/, keys %INC;
這給出了輸出
RPC/XML.pm
RPC/XML/Client.pm
RPC/XML/ParserFactory.pm
XML/NamespaceSupport.pm
XML/Parser.pm
XML/Parser/Expat.pm
XML/SAX.pm
XML/SAX/Base.pm
XML/SAX/Exception.pm
XML/SAX/Expat.pm
XML/SAX/ParserFactory.pm
XML/Simple.pm
在大型項目
,並
XML/NamespaceSupport.pm
XML/Parser.pm
XML/Parser/Expat.pm
XML/SAX.pm
XML/SAX/Base.pm
XML/SAX/Exception.pm
XML/SAX/Expat.pm
XML/SAX/ParserFactory.pm
XML/Simple.pm
在測試文件
。
更新:我安裝了Debian軟件包libxml-libxml-perl
並添加$XML::SAX::ParserPackage = "XML::LibXML::SAX";
的建議。這也應聲,用不同的信息,時間:
*** stack smashing detected ***: /usr/bin/perl terminated
這一次,它在兩個大國和小文件始終發生,但。此外,只有在使用open
時,而不是在使用反引號時。
我也安裝了libxml-libxml-simple-perl
,但這不應該比實際中的包裝更多地總是使用XML :: LibXML作爲解析器。它也有不同的表現,並抱怨設置了XMLin()的選項,所以我放棄了它。
試圖明確(並盲目地)讓程序使用print "$_\n" for sort grep /XML/, keys %INC;
給出的每個備選方案都似乎指向默認情況下使用XML :: SAX :: Expat,因爲cjm表示(因爲所有其他替代方法都會以錯誤退出,和XML :: SAX:Expat的行爲與兩個文件中的原始問題完全相同。顯式要求的XML :: Simple進入一個分配我所有內存的循環。
我很感謝學習不同的XML解析器,並且XML :: Simple自動選擇不同的解析器。儘管我的原始問題的兩個部分仍然有所保留:
- 爲什麼程序的行爲有所不同?即使我在兩個程序中明確地設置了
$XML::SAX::ParserPackage = "XML::SAX::Expat"
,也會崩潰(使用open
)和其他作品。 - 我應該使用另一種方法從外部命令接收輸出嗎?是否期望XMLin()ta與
open
一起工作(但爲什麼它在一種情況下工作,然後呢?)?
或者他們是否簡單的提出了「錯誤」的問題(即無關緊要)?
UPDATE:一個多星期過去了,活動不亂舞在這裏,我解決它有點不同,現在,沒有任何問題。我將cjm的答案標記爲正確,因爲它讓我進一步瞭解錯誤分析。謝謝!
爲什麼「使用open」? XML不是utf-8編碼; XML是二進制的,它由解析器來檢測編碼 - 這就是<?xml'的用途。 (這給瞭解析器足夠的關於編碼的信息來讀取charset =聲明,然後用它來實際解析文檔。)當然,這不應該導致段錯誤,但可能會有不良的交互。刪除'使用open'並看看會發生什麼。 – jrockway
另外值得注意的是:我快速瀏覽了XML :: Parser的XS代碼,並注意到它使用「utf8標誌」播放速度非常快。無論緩衝區是否爲有效utf8,都會打開標誌。使用XML :: LibXML :) – jrockway
「使用open」只是爲了重新創建大型程序中已經存在的頭文件。我希望儘可能平等的環境來隔離問題,但不是,在這種情況下,它沒有任何區別。 –