作成 2012.01.28
更新 2012.03.11
更新 2012.03.11
FreeBSD のアップグレード後に各実行ファイルの Shared Object ファイルがリンクできているか確認する
FreeBSD を 9.0 へアップグレードした際に動かないのが多かったため。
コード
ldd-recursion.pl download
#!/usr/bin/perl
use strict;
use warnings;
sub ldlist;
sub chk_ldd;
my $ldd = '/usr/bin/ldd';
my @list = ('/sbin', '/bin', '/usr/sbin', '/usr/bin',
'/usr/games','/usr/local/sbin','/usr/local/bin',
'/lib','/usr/lib','/usr/local/lib',
'/libexec', '/usr/libexec', '/usr/local/libexec');
my %libs = ();
my %done = ();
foreach my $dir_path (@list){
print "###################\n";
&ldlist($dir_path);
}
sub ldlist{
print "DIR ".$_[0]."\n";
my $top_dir = $_[0];
opendir(DIR,$top_dir);
my @file = readdir(DIR);
closedir(DIR);
my $path;
foreach(@file){
if($_ eq '.' || $_ eq '..'){ next; }
$path = $top_dir.'/'.$_;
if(-l $path){
$path = readlink($path);
if($path =~ /^[^\/]/){
$path = $top_dir.'/'.$path;
}
}
if(-d $path){
&ldlist($path);
next;
}
if(-x $path){
&chk_ldd($path);
}elsif($path =~ /\.so/){
&chk_ldd($path);
}
}
}
sub chk_ldd{
my $chk_file = $_[0];
my $i;
if(exists $done{$chk_file}){ return; }
$done{$chk_file} = 1;
print $chk_file."\n";
my @res = `$ldd $chk_file`;
for($i=1; $i<=$#res; $i++){
my $r = $res[$i];
if($r =~ /not/i){
print $r;
}else{
$r =~ s/^\s*(.*?)\s*$/$1/;
my @l = split(/ +/,$r);
if(exists $libs{$l[0]}){ next; }
$libs{$l[0]} = $l[2];
print "*\t".$l[0]."\t".$l[2]."\n";
&chk_ldd($l[2]);
}
}
}
実行例
result.log が作成されるので、"found" のキーワードで検索して見つからなければ多分OK。
$ perl ldd-recursion.pl > result.log 2>&1
not found の行が見つかった場合
とりあえず、アップデートが無いか確認。
"-a" だと全部まとめて。
例えば、libz.so.5 not found の場合は、以下の要領で。
# portsnap fetch # portsnap update # portaudit -Fda # pkg_version | grep -v "="アップデート。バージョン指定の port がある場合は、個別にアップデートしてから実行する。
"-a" だと全部まとめて。
# portmaster -aこれでも残っていた場合は、各ファイルが所属しているパッケージを検索し、再インストールする。
# grep -r ファイル名 /var/db/pkg # portmaster パッケージ名再インストールで解決しない場合、libファイルのアップデート版からリンクする。
例えば、libz.so.5 not found の場合は、以下の要領で。
# ln -s /lib/libz.so.6 /lib/libz.so.5未確認情報。依存するパッケージをすべて再インストール
# portmaster -R -r パッケージ