Não é possível capturar a criação de arquivos com strace

3

Quando executo o seguinte comando make em um diretório de compilação, ele está quase vazio (o arquivo em questão com certeza não está lá)

strace -f -e trace=execve,vfork,open,creat -s 1024 make <target>

Depois que terminar, o arquivo estará totalmente lá. Portanto, ele deve ter sido criado por make ou um de seus processos filhos (ou filhos de seus filhos e assim por diante).

No entanto, quando eu groco o strace log para o nome do arquivo ou para creat não consigo encontrar a chamada do sistema responsável pela criação deste arquivo.

O que estou perdendo? Existem outras chamadas de sistema que eu deveria monitorar?

EDITAR:

Acontece que o erro foi tanto no comamnd do meu strace quanto no meu grepping. Todas as respostas foram úteis, obrigado a todos pelo seu tempo.

Na verdade, não consegui comunicar que o arquivo estava em um subdir e estava usando o nome de um arquivo junto com o nome do subdiretório. Mas como strace não fornece informações sobre o diretório de trabalho atual, essa abordagem não funcionou tão bem (acabei aplicando chdir e rename chamadas para obter o efeito desejado).

A primeira sugestão de PaulHaldane foi correta e objetiva. Bem como a resposta de Larsks, na qual ele adivinhou como o arquivo foi criado.

    
por Vladislav Ivanishin 27.08.2016 / 11:21

2 respostas

4

Execute strace sem a opção -e e veja se isso melhora o resultado.

Existem várias maneiras de criar um arquivo. Em vez de open -ing, é altamente provável que, seja qual for a ferramenta que produz esse arquivo, primeiro abra um arquivo temporário, grave os dados e, em seguida, renomeie o arquivo na conclusão.

Com seu limite atual ( execve,vfork,open,creat ), você não verá esse tipo de comportamento.

Por exemplo, dado este script python simples:

import os
import tempfile

fd = tempfile.NamedTemporaryFile(dir='.', delete=False)
fd.write('this is a test\n')
fd.close()

os.rename(fd.name, 'output')

Executar strace com seus argumentos e, em seguida, procurar output nos resultados não gera nada:

$ strace -e trace=execve,vfork,open,creat -o trace -f -s 80 python tmptest.py
$ grep output trace
$

Mas se eu remover o filtro -e :

$ strace  -o trace -f -s 80 python tmptest.py
$ grep output trace
4523  rename("/home/lars/tmp/tmpZDwvPK", "output") = 0

Nos comentários sobre sua pergunta, Sato Katsura fornece um exemplo no qual você não verá seu nome de arquivo de destino na saída strace , mas acho que é improvável que você o encontre ao executar make contanto que você inicie com um ambiente de criação limpo.

    
por 27.08.2016 / 14:58
1

Outra opção é sysdig , por exemplo, um comando algo como:

sysdig -p '%proc.pname[%proc.ppid]: %proc.name -> %evt.type(%evt.args)' \
  evt.args contains /tmp/yourbuilddir

sendo executado em um terminal, depois com o arquivo temporário renomear o código de:

#!/usr/bin/perl
use File::AtomicWrite;
File::AtomicWrite->write_file(
    {   file   => "/tmp/yourbuilddir/foofile",
        input  => \"blah",
        MKPATH => 1
    }
);

executado e, em seguida, o sysdig executando novamente no outro terminal deve revelar algo como:

bash[13645]: perl -> stat(res=-2(ENOENT) path=/tmp/yourbuilddir )
bash[13645]: perl -> stat(res=-2(ENOENT) path=/tmp/yourbuilddir )
bash[13645]: perl -> mkdir(path=/tmp/yourbuilddir mode=0 )
bash[13645]: perl -> stat(res=0 path=/tmp/yourbuilddir )
bash[13645]: perl -> stat(res=0 path=/tmp/yourbuilddir/ )
bash[13645]: perl -> stat(res=0 path=/tmp/yourbuilddir/ )
bash[13645]: perl -> open(fd=3(<f>/tmp/yourbuilddir/.tmp.8XUnHhOrIn) name=/tmp/yourbuilddir/.tmp.8XUnHhOrIn flags=39(O_EXCL|O_CREAT|O_RDWR) mode=0 )
bash[13645]: perl -> ioctl(fd=3(<f>/tmp/yourbuilddir/.tmp.8XUnHhOrIn) request=5401 argument=7FFEF6BE5020 )
bash[13645]: perl -> lseek(fd=3(<f>/tmp/yourbuilddir/.tmp.8XUnHhOrIn) offset=0 whence=1(SEEK_CUR) )
bash[13645]: perl -> fstat(fd=3(<f>/tmp/yourbuilddir/.tmp.8XUnHhOrIn) )
bash[13645]: perl -> fcntl(fd=3(<f>/tmp/yourbuilddir/.tmp.8XUnHhOrIn) cmd=3(F_SETFD) )
bash[13645]: perl -> write(fd=3(<f>/tmp/yourbuilddir/.tmp.8XUnHhOrIn) size=4 )
sshd[678]: sshd -> read(res=970 data=bash[13645]: perl -> stat(res=-2(ENOENT) path=/tmp/yourbuilddir )..bash[13645]:  )
bash[13645]: perl -> close(fd=3(<f>/tmp/yourbuilddir/.tmp.8XUnHhOrIn) )
bash[13645]: perl -> rename(res=0 oldpath=/tmp/yourbuilddir/.tmp.8XUnHhOrIn newpath=/tmp/yourbuilddir/foofile )
sshd[678]: sshd -> read(res=186 data=bash[13645]: perl -> close(fd=3(<f>/tmp/yourbuilddir/.tmp.8XUnHhOrIn) )..bash[13 )
    
por 27.08.2016 / 17:06