Como deve strace ser usado?
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?
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.
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
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:
-
env -i ASDF=qwer
para controlar as variáveis ??de ambiente: https://unix.stackexchange.com/questions/48994/how-to-run-a-program-in-a-clean-environment-in-bash -
-s999 -v
para mostrar informações mais completas sobre os logs
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 comostrace
executadoshello.out
, incluindo argumentos CLI e meio ambiente como documentado noman 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 noman 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.