Strace na prática

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.

This entry was posted in Debian, Linux and tagged , , . Bookmark the permalink.

2 Responses to Strace na prática

  1. Marcos [Visitante] says:

    Xô ver… o sistema quebra e você resolve o problema com strace?
    Você está doente!

  2. Essa biblioteca é muito antiga (do tempo do Sarge), ela é legado do MDNS que depois foi substituído pelo zeroconf. ;)

Deixe um Comentário

O seu endereço de email não será publicado Campos obrigatórios são marcados *

*

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>