Como verificar quais binários dependem de certos arquivos em / lib?

4

Sei que, se eu fizer o comando ldd <name> em um arquivo binário em /bin ou /sbin , posso ver quais bibliotecas ele usa. Como faço o contrário? Ou seja fazer um comando em um arquivo em /lib e ver quais binários estão usando?

    
por Ted Desmond 28.05.2016 / 02:37

4 respostas

3

Isso não é exatamente o que você está pedindo, mas permitirá que você encontre a lista de binários usando uma determinada biblioteca. binstats gera um relatório sobre os binários e bibliotecas em seu sistema, principalmente para descobrir quais binários estão faltando bibliotecas e quais bibliotecas não são mais usadas.

No modo de depuração, ele deixa seus arquivos temporários para trás e um deles lista todos os binários no caminho (ou nas pastas que você especifica, usando a opção -b ), com todas as bibliotecas que eles usam. Depois de ter esse arquivo, você pode procurar a biblioteca em que está interessado para determinar o que o usa ...

Então basicamente:

binstats -d
awk '/^\// { binary=$1 }; /libtinfo.so.5/ { print binary }' etempb.00

listará todos os binários usando libtinfo.so.5 . (O nome do arquivo pode não ser etempb.00 , mas esperamos que você tenha a idéia ...)

Isso perderá os binários armazenados em diretórios que não estão no caminho, por exemplo em /usr/libexec , ou em /sbin e /usr/sbin se você não estiver executando como root , mas pode adicionar as pastas relevantes à opção -b .

    
por 28.05.2016 / 10:51
2

OP não esclareceu; no entanto, se você quiser saber quais processos atualmente em execução estão usando determinadas bibliotecas, lsof é útil, porque (usando os descritores de arquivo das bibliotecas compartilhadas), é possível listar todas as bibliotecas compartilhadas atualmente em uso junto com os nomes dos programas que os carregaram.

Por exemplo, aqui está uma listagem (removendo as primeiras poucas colunas) dos arquivos em uso para o editor de texto que estou usando:

cwd       DIR                8,1      4096  783366 /tmp
rtd       DIR                8,1      4096       2 /
txt       REG                8,1   1007808  659475 /usr/bin/vile
mem       REG                8,1     22664 1189463 /usr/lib/vile/vile-txt-filt.so
mem       REG                8,1     14472 1072690 /usr/lib/perl/5.14.2/auto/Tie/Hash/NamedCapture/NamedCapture.so
mem       REG                8,1     26984  717426 /usr/lib/perl/5.14.2/auto/List/Util/Util.so
mem       REG                8,1     18704  717420 /usr/lib/perl/5.14.2/auto/IO/IO.so
mem       REG                8,1     18672  717423 /usr/lib/perl/5.14.2/auto/Fcntl/Fcntl.so
mem       REG                8,1     14472  717444 /usr/lib/perl/5.14.2/auto/Cwd/Cwd.so
mem       REG                8,1     47616  914637 /lib/x86_64-linux-gnu/libnss_files-2.13.so
mem       REG                8,1     43560  914639 /lib/x86_64-linux-gnu/libnss_nis-2.13.so
mem       REG                8,1     89056  914574 /lib/x86_64-linux-gnu/libnsl-2.13.so
mem       REG                8,1     31584  914635 /lib/x86_64-linux-gnu/libnss_compat-2.13.so
mem       REG                8,1     10272  714121 /usr/lib/x86_64-linux-gnu/gconv/ISO8859-1.so
mem       REG                8,1 110939968  692851 /usr/lib/locale/locale-archive
mem       REG                8,1    530736  914572 /lib/x86_64-linux-gnu/libm-2.13.so
mem       REG                8,1     35104  914569 /lib/x86_64-linux-gnu/libcrypt-2.13.so
mem       REG                8,1    131107  913941 /lib/x86_64-linux-gnu/libpthread-2.13.so
mem       REG                8,1     14768  914571 /lib/x86_64-linux-gnu/libdl-2.13.so
mem       REG                8,1   1607696  914566 /lib/x86_64-linux-gnu/libc-2.13.so
mem       REG                8,1   1574680  717850 /usr/lib/libperl.so.5.14.2
mem       REG                8,1    167952  913960 /lib/x86_64-linux-gnu/libtinfo.so.5.9
mem       REG                8,1    136936  913944 /lib/x86_64-linux-gnu/ld-2.13.so
mem       REG                8,1     26066  714417 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
  0u      CHR              136,2       0t0       5 /dev/pts/2
  1u      CHR              136,2       0t0       5 /dev/pts/2
  2u      CHR              136,2       0t0       5 /dev/pts/2
  3r      REG                8,1      6317 1197635 /usr/share/vile/perl/capture.pm
  4r      REG                8,1      1875 1197632 /usr/share/vile/perl/Vile/Manual.pm
  5r      REG                8,1      1349 1197630 /usr/share/vile/perl/plugins.pl
  6r      REG                8,1      4916 1197634 /usr/share/vile/perl/hgrep.pm
  7r      REG                8,1       652 1197643 /usr/share/vile/perl/Visit.pm
  8r      REG                8,1      1680 1197625 /usr/share/vile/perl/Glob2re.pm
  9r      REG                8,1      3986 1197638 /usr/share/vile/perl/dirlist.pm
 10r     FIFO                0,8       0t0   25311 pipe

ldd , a propósito, não está disponível universalmente; lsof é usado na maioria das plataformas do tipo Unix.

Aqui está um script de exemplo, que gera um relatório para todas as bibliotecas no sistema em execução no momento (se os argumentos forem fornecidos, ele corresponderá àqueles no nome da biblioteca):

#!/usr/bin/perl -w
# $Id: lsof-libs,v 1.2 2016/05/28 13:59:33 tom Exp $
#
# Process the output from "lsof", obtaining a list of binaries by library path.

use strict;

open( FP, "lsof|" ) || do {
    print STDERR "Can't open lsof: $!\n";
    return;
};
my (@input) = <FP>;
close(FP);

my $program = "";
my $library = "";
my %libs;
for my $n ( 0 .. $#input ) {
    my @fields = split /\s+/, $input[$n];
    next if ( $#fields < 8 );
    next unless ( $fields[8] =~ /^\// );
    my $pathname = $fields[8];
    if ( $fields[3] eq "txt" ) {
        $program = $pathname;
    }
    elsif ( $fields[3] eq "mem" ) {
        next unless ( $pathname =~ /\/lib[^\/]/ );
        $library = $pathname;
        my $found = ( $#ARGV < 0 );
        if ( $#ARGV >= 0 ) {
            for my $a ( 0 .. $#ARGV ) {
                if ( $ARGV[$a] eq $library ) {
                    $found = 1;
                    last;
                }
            }
        }
        if ($found) {
            my %obj;
            %obj = %{ $libs{$library} } if ( $libs{$library} );
            $obj{$program}  = 1;
            $libs{$library} = \%obj;
        }
    }
}
for my $lib ( sort keys %libs ) {
    printf "%s\n", $lib;
    my %obj = %{ $libs{$lib} };
    for my $prog ( sort keys %obj ) {
        printf "\t%s\n", $prog;
    }
}
1;

Leitura adicional:

por 28.05.2016 / 14:35
1

Contanto que você fique com os binários fornecidos pela sua distribuição, ele rastreia isso por meio de dependências de pacotes.

  1. Determine o pacote que contém esse arquivo de biblioteca.
  2. Listar os pacotes que dependem deste pacote de bibliotecas.
  3. Listar executáveis nesses pacotes.

É claro que isso não informará sobre programas que não são instalados através do mecanismo de empacotamento de sua distribuição. Isso também listará os executáveis extras quando um pacote contiver mais de um executável. Por outro lado, para muitos propósitos, o pacote é a informação que você precisa, ao invés do executável.

Como realizar cada uma dessas etapas depende do gerenciador de pacotes usado pela sua distribuição. O pacman rosetta possui uma tabela de comandos de gerenciamento de pacotes em distribuições populares. Por exemplo, no Debian, Ubuntu, Linux Mint, SO elementar e outras distribuições baseadas no dpkg / apt:

dpkg -S /path/to/library.so   # which package contains this library?
aptitude search "~i ~Dlibrary-package" # which installed packages depend on this library?
dpkg -L $(aptitude search -F %p "~i ~D$(dpkg -S /path/to/library.so | sed 's/:.*//')") | grep /bin
    
por 29.05.2016 / 00:05
0

Em caso de dúvida, use força bruta:

#!/bin/bash
# $1 -- target library
IFS=:
find $PATH -maxdepth 1 -executable -type f -o -type l 2>/dev/null | 
while read b; do
  ldd "$b" 2>/dev/null | grep -q -F "$1" &&  echo "$b"
done

Demora cerca de um minuto para percorrer todos os meus executáveis PATH (~ 4K) no meu sistema.

    
por 29.05.2016 / 02:16