Algumas ferramentas de ‘baixo’ nível são bem úteis de vez em quando. Um exemplo de uma delas é o strace.
Mas o que o strace faz? Da documentação:
In the simplest case strace runs the specified command until it exits. It intercepts and records the system calls which are called by a process and the signals which are received by a process. The name of each system call, its arguments and its return value are printed on standard error or to the file specified with the -o option.
Ou seja, ele intercepta e imprime as chamadas de sistema sendo feitas em um comando. Para mais sobre chamadas de sistema, consulte a wikipédia e leia o excelente artigo do Hugo Augusto. Um exemplo de como isso me foi útil:
Ano passado (segundo, o timestamp do arquivo, dia 03 de janeiro do ano passado), após a atualização no debian unstable do Ricardo (eu e ele usamos o unstable nos nossos desktop, herança do tempo do sarge, que eu considerava muito desatualizado), o computador do Ricardo ficou estranho. O Opera conseguia acessar sites, mas o Firefox não. Após alguns testes, constatamos que o problema era na resolução de nomes. O meu computador não apresentava nenhum desses problemas.
Partimos então pro mínimo caso possível: um simples wge t google.com (Sim, sempre ele…)
Pra encurtar a história, apenas a parte relevante:
O resultado do meu strace:
open("/usr/lib/libnss_mdns4_minimal.so.2", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\3\3\1@\v00"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0644, st_size=8676, ...}) = 0
mmap2(NULL, 11688, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7efb000
mmap2(0xb7efd000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1) = 0xb7efd000
close(3) = 0
Basicamente, isso significa ler a biblioteca libnss_mdns4_minimal.so.2 e jogá-la em memória.
No computador do Ricardo:
open("/lib/tls/i686/sse2/cmov/libnss_mdns4_minimal.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls/i686/sse2/cmov", 0xbfeedb6c) = -1 ENOENT (No such file or directory)
open("/lib/tls/i686/sse2/libnss_mdns4_minimal.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls/i686/sse2", 0xbfeedb6c) = -1 ENOENT (No such file or directory)
open("/lib/tls/i686/cmov/libnss_mdns4_minimal.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls/i686/cmov", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
open("/lib/tls/i686/libnss_mdns4_minimal.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls/i686", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
open("/lib/tls/sse2/cmov/libnss_mdns4_minimal.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls/sse2/cmov", 0xbfeedb6c) = -1 ENOENT (No such file or directory)
open("/lib/tls/sse2/libnss_mdns4_minimal.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls/sse2", 0xbfeedb6c) = -1 ENOENT (No such file or directory)
open("/lib/tls/cmov/libnss_mdns4_minimal.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls/cmov", 0xbfeedb6c) = -1 ENOENT (No such file or directory)
open("/lib/tls/libnss_mdns4_minimal.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
open("/lib/i686/sse2/cmov/libnss_mdns4_minimal.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/i686/sse2/cmov", 0xbfeedb6c) = -1 ENOENT (No such file or directory)
open("/lib/i686/sse2/libnss_mdns4_minimal.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/i686/sse2", 0xbfeedb6c) = -1 ENOENT (No such file or directory)
(uma parte da saída foi omitida, já que é semelhante o trecho apresentado)
Ou seja, ele procurou a danada em todo lugar e não achou. Logo depois disso, eu copiei a minha biblioteca por ssh pra ele. (O ssh estava funcionando).
# apt-file search libnss_mdns4_minimal libnss-mdns: lib/libnss_mdns4_minimal.so.2
Bastou eu ver em qual pacote estava o arquivo faltoso e instalar no computador do Ricardo. Sobre o Opera, provavelmente usava outra forma ou outra biblioteca par resolução de nomes
Por curiosidade, hoje eu testei o wget.
Ele vai direto em
open("/lib/i686/cmov/libnss_files.so.2", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\3\3\1\340\30"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0644, st_size=38412, ...}) = 0
mmap2(NULL, 41624, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7a3d000
mmap2(0xb7a46000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x8) = 0xb7a46000
close(3) = 0
munmap(0xb7a48000, 96386) = 0
Resultado: removi o libnss-mdns. Não deu quebra de dependência nenhuma. Está tudo OK.
Xô ver… o sistema quebra e você resolve o problema com strace?
Você está doente!
Essa biblioteca é muito antiga (do tempo do Sarge), ela é legado do MDNS que depois foi substituído pelo zeroconf.