Pergunta

Um colega me disse uma vez que a última opção quando tudo deixou de depuração no Linux era usar strace .

Eu tentei aprender a ciência por trás desta ferramenta estranho, mas eu não sou um guru de administração do sistema e eu realmente não obter resultados.

Assim,

  • O que é exatamente eo que ele faz?
  • Como e em que casos deve ser usado?
  • Como deve ser a saída de ser entendido e processados?

Em breve, em palavras simples , como funciona este material?

Foi útil?

Solução

Strace Overview
strace pode ser visto como um depurador de peso leve. Ele permite que um programador / usuário para descobrir rapidamente como um programa está interagindo com o OS. Ele faz isso por meio do monitoramento de chamadas e sinais do sistema.

Usos
Bom para quando você não tem o código-fonte ou não quer ser incomodado para realmente passar por isso.
Além disso, útil para o seu próprio código, se você não se sentir como abertura GDB, mas estão apenas interessados ??na interação externa entendimento.

A introdução bom pequeno
Corri para esta introdução ao uso strace apenas no outro dia: strace Olá mundo

Outras dicas

Em palavras simples, strace rastreia todas as chamadas de sistema emitidas por um programa junto com seus códigos de retorno. Acho que as coisas tais como operações de arquivo / soquetes e os muito mais obscuros.

É mais útil se você tem algum conhecimento de trabalho de C desde aqui chamadas de sistema iria ficar com mais precisão para chamadas de biblioteca C padrão.

Vamos dizer que seu programa é / usr / local / bin / tosse. Simplesmente use:

strace /usr/local/bin/cough <any required argument for cough here>

ou

strace -o <out_file> /usr/local/bin/cough <any required argument for cough here>

para escrever em 'out_file'.

Toda a saída de strace irão para stderr (cuidado, o grande volume de, muitas vezes, pede um redirecionamento para um arquivo). Nos casos mais simples, o programa irá abortar com um erro e você será capaz de ver o que seus últimos interações com o sistema operacional na saída strace.

Mais informação deve estar disponível com:

man strace

listas Strace todos os sistema chama feito pelo processo é aplicado. Se você não sabe o que chamadas de sistema Quer dizer, você não será capaz de obter muito mais quilometragem com isso.

No entanto, se o seu problema envolve arquivos ou caminhos ou valores de ambiente, correndo strace sobre o programa problemático e redirecionando a saída para um arquivo e, em seguida, grepping esse arquivo para o seu caminho / arquivo de corda / env pode ajudá-lo a ver o que o seu programa é realmente tentando fazer, como distinto do que você esperava.

Strace destaca-se como uma ferramenta para investigar os sistemas de produção onde não se pode dar ao luxo de executar esses programas sob um depurador. Em particular, temos strace utilizados nas duas situações seguintes:

  • foo Programa parece estar em impasse e tornou-se indiferente. Isto poderia ser um alvo para o GDB; No entanto, não tive sempre o código-fonte ou às vezes estavam lidando com linguagens de script que não eram simples e direta para executar sob um depurador. Neste caso, você corre strace em um programa já em execução, e você obterá a lista de chamadas do sistema estão sendo feitas. Isto é particularmente útil se você está investigando um aplicativo cliente / servidor ou uma aplicação que interage com um banco de dados
  • Investigando por que um programa é lento. Em particular, tinha acabado de se mudar para um novo sistema de arquivos distribuídos ea nova taxa de transferência do sistema era muito lento. Você pode especificar strace com a opção '-T', que irá dizer-lhe quanto tempo foi gasto em cada chamada do sistema. Isso ajudou a determinar por que o sistema de arquivos estava causando coisas a abrandar.

Para um exemplo de análise utilizando strace ver a minha resposta para esta pergunta .

Eu uso strace o tempo todo para problemas de permissão de depuração. A técnica é a seguinte:

$ strace -e trace=open,stat,read,write gnome-calculator

Onde gnome-calculator é o comando que você deseja executar.

strace -tfp PID irá monitorar chamadas de sistema do processo PID, assim podemos depurar / monitorar nosso status do processo / programa.

Strace pode ser usado como uma ferramenta de depuração, ou como um profiler primitivo.

Como um depurador, você pode ver como dadas as chamadas do sistema foram chamados e executados, e que eles retornam. Isto é muito importante, pois permite-lhe ver não só que um programa falhou, mas por um programa falhou. Geralmente é apenas um resultado de péssimo codificação não pegar todos os possíveis resultados de um programa. Outras vezes é apenas codificado caminhos para arquivos. Sem strace você tem que adivinhar o que deu errado, onde e como. Com strace você começa uma ruptura de um syscall, geralmente apenas olhando para um valor de retorno, diz muita coisa.

Profiling é um outro uso. Você pode usá-lo para o tempo de execução de cada syscalls individualmente ou como um agregado. Embora isso possa não ser suficiente para resolver seus problemas, ele vai pelo menos grandemente diminuir a lista de potenciais suspeitos. Se você ver um monte de fopen / pares próximos em um único arquivo, você provavelmente unnecessairly abrir e fechar arquivos a cada execução de um ciclo, em vez de abertura e fechamento fora de um loop.

ltrace é primo próximo do strace, também muito útil. Você deve aprender a diferenciar onde o gargalo é. Se uma execução total é de 8 segundos, e você gasta apenas 0.05secs em chamadas de sistema, então stracing o programa não vai fazê-lo muito bem, o problema está no seu código, que normalmente é um problema de lógica, ou o programa realmente precisa para levar tanto tempo para ser executado.

O maior problema com strace / ltrace está lendo sua produção. Se você não sabe como as chamadas são feitas, ou pelo menos os nomes dos syscalls / funções, que vai ser difícil de decifrar o significado. Saber o que as funções de retorno também pode ser muito benéfico, especialmente para diferentes códigos de erro. Embora seja uma dor de decifrar, eles às vezes realmente retornar uma pérola do conhecimento; Uma vez eu vi uma situação onde eu corri para fora de inodes, mas não fora do espaço livre, portanto, todos os utilitários habituais não me deu qualquer aviso, eu apenas não poderia fazer um novo arquivo. A leitura do código de erro da saída de strace apontou-me na direção certa.

Strace é uma ferramenta que lhe diz como suas interage aplicação com o seu sistema operacional.

Ele faz isso, dizendo-lhe o que o sistema OS chama seus usos aplicação e com quais parâmetros que chama-los.

Assim, por exemplo, você ver o que seus arquivos de tentativas programa para abrir, e resistir a chamada tiver êxito.

Você pode depurar todos os tipos de problemas com esta ferramenta. Por exemplo, se a aplicação diz que ele não pode encontrar biblioteca que você sabe que tem instalado, você strace iria dizer-lhe onde o aplicativo está olhando para esse arquivo.

E isso é apenas a ponta do iceberg.

strace é uma boa ferramenta para aprender como o programa faz várias chamadas de sistema (pedidos para o kernel) e também relata os que falharam, juntamente com o valor de erro associada a esse fracasso. Nem todas as falhas são bugs. Por exemplo, um código que está tentando procurar um arquivo pode ter uma ENOENT (Nenhum tal lima ou diretório) erro, mas que pode ser um cenário aceitável na lógica do código.

Um bom caso de uso de usar strace é condições de corrida de depuração durante a criação do arquivo temporário. Por exemplo, um programa que pode ser a criação de arquivos anexando o ID do processo (PID) para alguma corda predecided podem enfrentar problemas em cenários multi-threaded. [A PID + TID (processo id id + fio) ou uma melhor chamada de sistema, tais como mkstemp vai corrigir isso].

Também é bom para depurar falhas. Você pode encontrar este (meu) artigo sobre strace e depuração acidentes útil.

eu gostei algumas das respostas onde se lê cheques strace como você interage com o sistema operacional.

Este é exatamente o que nós podemos ver. O sistema chama. Se você comparar strace e ltrace a diferença é mais evidente.

$>strace -c cd
Desktop  Documents  Downloads  examples.desktop  Music  Pictures  Public  Templates  Videos
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  0.00    0.000000           0         7           read
  0.00    0.000000           0         1           write
  0.00    0.000000           0        11           close
  0.00    0.000000           0        10           fstat
  0.00    0.000000           0        17           mmap
  0.00    0.000000           0        12           mprotect
  0.00    0.000000           0         1           munmap
  0.00    0.000000           0         3           brk
  0.00    0.000000           0         2           rt_sigaction
  0.00    0.000000           0         1           rt_sigprocmask
  0.00    0.000000           0         2           ioctl
  0.00    0.000000           0         8         8 access
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         2           getdents
  0.00    0.000000           0         2         2 statfs
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         9           openat
  0.00    0.000000           0         1           set_robust_list
  0.00    0.000000           0         1           prlimit64
------ ----------- ----------- --------- --------- ----------------
100.00    0.000000                    93        10 total

Por outro lado, há ltrace que traça funções.

$>ltrace -c cd
Desktop  Documents  Downloads  examples.desktop  Music  Pictures  Public  Templates  Videos
% time     seconds  usecs/call     calls      function
------ ----------- ----------- --------- --------------------
 15.52    0.004946         329        15 memcpy
 13.34    0.004249          94        45 __ctype_get_mb_cur_max
 12.87    0.004099        2049         2 fclose
 12.12    0.003861          83        46 strlen
 10.96    0.003491         109        32 __errno_location
 10.37    0.003303         117        28 readdir
  8.41    0.002679         133        20 strcoll
  5.62    0.001791         111        16 __overflow
  3.24    0.001032         114         9 fwrite_unlocked
  1.26    0.000400         100         4 __freading
  1.17    0.000372          41         9 getenv
  0.70    0.000222         111         2 fflush
  0.67    0.000214         107         2 __fpending
  0.64    0.000203         101         2 fileno
  0.62    0.000196         196         1 closedir
  0.43    0.000138         138         1 setlocale
  0.36    0.000114         114         1 _setjmp
  0.31    0.000098          98         1 realloc
  0.25    0.000080          80         1 bindtextdomain
  0.21    0.000068          68         1 opendir
  0.19    0.000062          62         1 strrchr
  0.18    0.000056          56         1 isatty
  0.16    0.000051          51         1 ioctl
  0.15    0.000047          47         1 getopt_long
  0.14    0.000045          45         1 textdomain
  0.13    0.000042          42         1 __cxa_atexit
------ ----------- ----------- --------- --------------------
100.00    0.031859                   244 total

Embora eu verifiquei os manuais várias vezes, eu não encontrou a origem do nome strace mas é provável trace sistema de chamada, uma vez que este é óbvia.

Há três notas maiores a dizer sobre strace.

Nota 1: Ambas as funções strace e ltrace estão usando a chamada de sistema ptrace . Assim chamada de sistema ptrace é efetivamente como funciona strace.

A chamada do sistema ptrace () proporciona um meio pelo qual um processo (a "Tracer") pode observar e controlar a execução de outro processo (O "tracee"), e examinar e alterar a memória do tracee e registradores. Ele é usado principalmente para implementar ponto de interrupção de depuração e chamada de sistema de rastreamento.

Nota 2: Há diferentes parâmetros que você pode usar com strace, desde strace pode ser muito detalhado. Eu gosto de experimentar com -c que é como um resumo das coisas. Baseado em -c você pode selecionar um sistema de chamada como -e trace=open onde você vai ver só isso chamada. Isso pode ser interessante se você está examinando quais arquivos serão abertos durante o comando que você está traçando. E, claro, você pode usar o grep para a mesma finalidade, mas note que você precisa redirecionar assim 2>&1 | grep etc a entender que os arquivos de configuração são referenciadas quando o comando foi emitido.

Nota 3: Acho isso muito importante nota. Você não está limitado a uma arquitetura específica. strace vai explodir se importa, uma vez que pode traçar sobre binários de arquiteturas diferentes. enter descrição da imagem aqui

Minimal exemplo executável

Se um conceito não é clara, há um exemplo mais simples que você não tenha visto isso explica tudo.

Neste caso, esse exemplo é o x86_64 Linux montagem independentes (sem libc) Olá mundo:

hello.S

.text
.global _start
_start:
    /* write */
    mov $1, %rax    /* syscall number */
    mov $1, %rdi    /* stdout */
    mov $msg, %rsi  /* buffer */
    mov $len, %rdx  /* buffer len */
    syscall

    /* exit */
    mov $60, %rax   /* exit status */
    mov $0, %rdi    /* syscall number */
    syscall
msg:
    .ascii "hello\n"
len = . - msg

GitHub a montante .

Montar e executar:

as -o hello.o hello.S
ld -o hello.out hello.o
./hello.out

Emite o esperado:

hello

Agora vamos uso strace em que exemplo:

env -i ASDF=qwer strace -o strace.log -s999 -v ./hello.out arg0 arg1
cat strace.log

Nós usamos:

strace.log agora contém:

execve("./hello.out", ["./hello.out", "arg0", "arg1"], ["ASDF=qwer"]) = 0
write(1, "hello\n", 6)                  = 6
exit(0)                                 = ?
+++ exited with 0 +++

Com um exemplo tão mínima, cada personagem da saída é evidente:

  • linha execve: mostra como strace executados hello.out, incluindo argumentos CLI e meio ambiente como documentado no man execve

  • linha write: mostra a chamada sistema de gravação que fizemos. 6 é o comprimento do "hello\n" string.

    = 6 é o valor de retorno da chamada de sistema, que conforme documentado no man 2 write é o número de bytes escritos.

  • linha exit: mostra a chamada de sistema exit que fizemos. Não há valor de retorno, desde que o programa parar!

Exemplos mais complexos

A aplicação de strace é, naturalmente, para ver qual sistema chama programas complexos estão realmente fazendo para ajudar a depurar / otimizar o seu programa.

Notavelmente, a maioria das chamadas de sistema que você é provável encontrar em Linux têm invólucros glibc, muitos deles de POSIX .

Internamente, os invólucros glibc usar linha de montagem mais ou menos assim: Como invocar uma chamada de sistema via sysenter na linha de montagem?

O próximo exemplo, você deve estudar é um mundo write Olá POSIX:

main.c

#define _XOPEN_SOURCE 700
#include <unistd.h>

int main(void) {
    char *msg = "hello\n";
    write(1, msg, 6);
    return 0;
}

compilar e executar:

gcc -std=c99 -Wall -Wextra -pedantic -o main.out main.c
./main.out

Desta vez, você vai ver que um monte de chamadas do sistema estão sendo feitas por glibc antes main configurar um ambiente agradável para o principal.

Isto é porque nós agora não está usando um programa independente, mas sim um programa glibc mais comum, que permite a funcionalidade libc.

Então, no cada fim, strace.log contém:

write(1, "hello\n", 6)                  = 6
exit_group(0)                           = ?
+++ exited with 0 +++

Assim, podemos concluir que a write função POSIX usos, surpresa !, a chamada de sistema write Linux.

Também observamos que leva return 0 a uma chamada exit_group vez de exit. Ha, eu não sabia sobre este! É por isso que strace é tão legal. man exit_group seguida, explica:

Esta chamada de sistema é equivalente a saída (2), exceto que ele termina não só o segmento de chamada, mas os tópicos no grupo de discussão do processo de chamada.

E aqui está outro exemplo onde estudei usos dlopen que chamadas de sistema: https://unix.stackexchange.com/questions/226524/what-system-call-is-used-to-load-libraries-in-linux / 462710 # 462710

Testado no Ubuntu 16.04, GCC 6.4.0, Linux Kernel 4.4.0.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top