Strace nasıl kullanılmalıdır?


273

Bir meslektaşım bir keresinde bana her şeyin Linux'ta hata ayıklamada başarısız olduğu son seçeneğin strace kullanmak olduğunu söyledi .

Bu garip aracın arkasındaki bilimi öğrenmeye çalıştım, ancak sistem yöneticisi bir guru değilim ve gerçekten sonuç alamadım.

Yani,

  • Tam olarak nedir ve ne işe yarar?
  • Nasıl ve hangi durumlarda kullanılmalıdır?
  • Çıktı nasıl anlaşılmalı ve işlenmelidir?

Kısacası, basit bir deyişle , bu şeyler nasıl çalışır?


2
strace -p <pid> programınızla şu anda neler olduğunu anlatacak .....
GDB'den

1
Şahsen man straceokumayı gerçekten kolay ve kullanışlı buluyorum . (PS bir Linux uzmanı değil dünden önce sıkıntıyı bilmiyordu)
Alexander Malakhov

1
"strace bir sistem çağrısı izleyicisidir" - programınızın sonucunda çekirdek işlevlerinin (argümanlarıyla) çağrıldığını gösterir.
Pithikos

Yanıtlar:


184

Askılı Genel Bakış askısı
hafif bir hata ayıklayıcı olarak görülebilir. Bir programcının / kullanıcının bir programın işletim sistemi ile nasıl etkileşime girdiğini hızlı bir şekilde öğrenmesini sağlar. Bunu sistem çağrılarını ve sinyallerini izleyerek yapar.

Kullanımları
İyi kaynak kodunu yoksa veya gerçekten geçmesi rahatsız edilmek istemediğinizde için.
Ayrıca, GDB'yi açmak istemiyorsanız, ancak sadece dış etkileşimi anlamakla ilgileniyorsanız, kendi kodunuz için yararlıdır.

İyi bir
giriş, geçen gün kullanımı zorlamak için bu girişe girdim: strace merhaba dünya


Peki ya katmanların altında izlenen katmanı kullanırsanız ne olur?
Pacerier

Bu durumda @Pacerier check ltrace stackoverflow.com/a/52012215/5884955
prosti

Sadece / çoğunlukla ilginç olan sistem çağrıları yapmak için mevcut olan düşük seviyeli programlarda hata ayıklamak veya sisteminizin ne yaptığını görmek için sistem çağrılarının yeni seçenekleri denemek için harikadır. Temel olarak bir kerelik deneyler için günlüğe kaydetme / hata kontrolü kodu yazma sorununu ortadan kaldırır. (Veya yanlışlıkla yanlış argümanları veya hatta çağrı numarasını geçme şansınızın olduğu bir şey veya bir şey yazıyorsanız.) Strace GDB'den çok daha hızlıdır, çünkü sizin için errno kodlarına bakar, örneğin -EFAULT(ayy, salt okunur buffer) veya -ENOENT(oops, göreli yolun çalışmadığı yanlış
Peter Cordes

62

Basitçe söylemek gerekirse, strace bir program tarafından verilen tüm sistem çağrılarını dönüş kodlarıyla birlikte izler. Dosya / soket işlemleri ve çok daha belirsiz olanları düşünün.

Burada sistem çağrıları standart C kütüphane çağrılarını daha doğru bir şekilde ifade edeceğinden, C hakkında biraz çalışma bilginiz varsa en kullanışlıdır.

Diyelim ki programınız / usr / local / bin / cough. Basitçe kullanın:

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

veya

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

'out_file' içine yazmak.

Tüm strace çıktıları stderr'e gidecektir (dikkat edin, bunun büyük hacmi genellikle bir dosyaya yeniden yönlendirmeyi ister). En basit durumlarda, programınız bir hata ile iptal edilir ve strace çıktısında işletim sistemi ile son etkileşimlerinin nerede olduğunu görebilirsiniz.

Aşağıdakilerle ilgili daha fazla bilgi mevcut olmalıdır:

man strace

36

strace, uygulandığı işlem tarafından yapılan tüm sistem çağrılarını listeler . Sistem çağrılarının ne anlama geldiğini bilmiyorsanız, bundan fazla kilometre alamazsınız.

Bununla birlikte, sorununuz dosya veya yolları veya ortam değerlerini içeriyorsa, sorunlu programda strace çalıştırmak ve çıktıyı bir dosyaya yönlendirmek ve daha sonra bu dosyayı path / file / env dizeniz için selamlamak programınızın gerçekte ne yapmaya çalıştığını görmenize yardımcı olabilir . beklediğinizden farklı olarak yapın.


7
Önemsiz programlar için bu genellikle bir yangın hortumundan içmeye benzer, bu yüzden sonuçlardan geçtiğiniz için işinizi kesmiş olursunuz ...
dmckee --- eski moderatör kedi yavrusu

17
strace <prog_name>bir programı izlemek için. strace -o <out_file> <prog_name>bir dosyaya koymak
Jestin Joy

8
strace prog 2> ve 1 | grep ^ open \ (
eisbaw

10
Veya sadece: strace -e open myprogOR dosya ile ilgili tüm sys aramaları için:strace -e file myprog
Amit Naidu

17

Strace, bu programları bir hata ayıklayıcı altında çalıştırmayı göze alamayacağınız üretim sistemlerini araştırmak için bir araç olarak öne çıkıyor. Özellikle, aşağıdaki iki durumda strace kullandık:

  • Program foo kilitlenme içinde gibi görünüyor ve yanıt vermiyor. Bu gdb için bir hedef olabilir; ancak, kaynak koduna her zaman sahip olmadık veya bazen bir hata ayıklayıcı altında çalıştırılması kolay olmayan kodlanmış dillerle uğraştık. Bu durumda, zaten çalışan bir programda strace çalıştırırsınız ve yapılan sistem çağrılarının listesini alırsınız. Bu, bir istemci / sunucu uygulamasını veya bir veritabanıyla etkileşime giren bir uygulamayı araştırıyorsanız özellikle yararlıdır
  • Bir programın neden yavaş olduğunu araştırmak. Özellikle, yeni dağıtılmış bir dosya sistemine geçtik ve sistemin yeni üretimi çok yavaştı. Her sistem çağrısında ne kadar zaman harcandığını size bildirecek olan '-T' seçeneğiyle strace belirtebilirsiniz. Bu, dosya sisteminin neden yavaşlamaya neden olduğunu belirlemeye yardımcı oldu.

Strace kullanarak analiz örneği için bu soruya verdiğim cevaba bakınız .


15

İzin sorunlarını ayıklamak için her zaman strace kullanıyorum. Teknik şu şekilde gider:

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

Nerede gnome-calculatorÇalıştırmak istediğiniz komut .


8

strace -tfp PID, PID işleminin sistem çağrılarını izler, böylece süreç / program durumumuzda hata ayıklayabilir / izleyebiliriz.


6

Strace, bir hata ayıklama aracı veya ilkel bir profil oluşturucu olarak kullanılabilir.

Bir hata ayıklayıcı olarak, verilen sistem çağrılarının nasıl çağrıldığını, yürütüldüğünü ve geri döndüklerini görebilirsiniz. Bu çok önemlidir, çünkü sadece bir programın başarısız olduğunu değil, bir programın neden başarısız olduğunu görmenizi sağlar. Genellikle sadece bir programın tüm olası sonuçlarını yakalamayan berbat kodlamanın bir sonucudur. Diğer durumlarda dosyalara giden sabit kodlu yollar. Strace olmadan neyin nerede ve nasıl yanlış gittiğini tahmin edersiniz. Strace ile bir sistem çağrısının dökümü elde edersiniz, genellikle sadece bir dönüş değerine bakmak size çok şey anlatır.

Profil oluşturma başka bir kullanımdır. Her bir sistem çağrısının tek tek veya toplu olarak yürütülmesini zamanlamak için kullanabilirsiniz. Bu, sorunlarınızı çözmek için yeterli olmasa da, en azından potansiyel şüphelilerin listesini büyük ölçüde daraltacaktır. Tek bir dosyada çok fazla fopen / close çifti görürseniz, bir döngü dışında açmak ve kapatmak yerine, dosyaları bir döngünün her yürütülmesinde gereksiz yere açıp kapatabilirsiniz.

Ltrace, strace'nin yakın kuzenidir, aynı zamanda çok faydalıdır. Darboğazınızın nerede olduğunu fark etmeyi öğrenmelisiniz. Toplam yürütme 8 saniyeyse ve sistem çağrılarına yalnızca 0,05 sn harcıyorsanız, programın izlenmesi size çok iyi gelmeyecektir, sorun genellikle bir mantık sorunu olan kodunuzdadır veya programın gerçekten ihtiyacı vardır uzun sürmesi için.

Strace / ltrace ile ilgili en büyük sorun çıktılarını okumaktır. Aramaların nasıl yapıldığını veya en azından sistem çağrılarının / işlevlerinin adlarını bilmiyorsanız, anlamı deşifre etmek zor olacaktır. Özellikle farklı hata kodları için, işlevlerin ne döndürdüğünü bilmek de çok yararlı olabilir. Deşifre etmek bir acı olsa da, bazen gerçekten bir bilgi incisi döndürürler; bir kez inode'um bitti, ancak boş alanımın olmadığı bir durum gördüğümde, bu nedenle her zamanki yardımcı programlar bana herhangi bir uyarı vermedi, yeni bir dosya yapamadım. Strace'nin çıktısından hata kodunu okumak beni doğru yöne çekti.


4

Strace, uygulamanızın işletim sisteminizle nasıl etkileşime girdiğini anlatan bir araçtır.

Bunu, uygulamanızın hangi işletim sistemi çağrılarını kullandığını ve hangi parametrelerle çağırdığını söyleyerek yapar.

Örneğin, programınızın hangi dosyaları açmaya çalıştığını görürsünüz ve çağrı başarılı olur.

Bu araçla her türlü sorunu ayıklayabilirsiniz. Örneğin, uygulama yüklediğinizi bildiğiniz kitaplığı bulamadığını söylüyorsa, strace uygulamanın o dosyayı nerede aradığını söyler.

Ve bu sadece buzdağının bir ucu.


bu çok hassas.
prosti

4

strace, programınızın çeşitli sistem çağrılarını (çekirdeğe yapılan istekler) nasıl yaptığını öğrenmek için iyi bir araçtır ve ayrıca başarısız olanları ve başarısızlıkla ilgili hata değerini bildirir. Tüm hatalar hata değildir. Örneğin, bir dosya aramaya çalışan bir kod bir ENOENT (böyle bir dosya veya dizin yok) hatası alabilir, ancak bu kod mantığında kabul edilebilir bir senaryo olabilir.

Strace kullanımının iyi bir kullanım durumu, geçici dosya oluşturma sırasında yarış koşullarında hata ayıklamaktır. Örneğin, işlem kimliğini (PID) tahmin edilen bazı dizelere ekleyerek dosya oluşturabilen bir program, çok iş parçacıklı senaryolarda sorunlarla karşılaşabilir. [Bir PID + TID (işlem kimliği + evre kimliği) veya mkstemp gibi daha iyi bir sistem çağrısı bunu düzeltir].

Ayrıca çökmeleri hata ayıklamak için de iyidir. Sen bulabilirsiniz strace bu (benim) makalesine ve ayıklama çöküyor faydalıdır.


4

Minimal çalıştırılabilir örnek

Bir kavram net değilse, bunu açıklayan görmediğiniz daha basit bir örnek vardır.

Bu durumda, bu örnek Linux x86_64 derleme bağımsız (libc yok) merhaba dünyasıdır:

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 akış yukarı .

Birleştirin ve çalıştırın:

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

Beklenen çıktılar:

hello

Şimdi bu örnek üzerinde strace kullanalım:

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

Kullanırız:

strace.log şimdi içeriyor:

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

Böyle minimal bir örnekle, çıktının her bir karakteri kendini belli eder:

  • execvesatır: gösterileri nasıl straceidam hello.outde belgelendiği gibi CLI argümanlar ve çevre dahil olmak üzere,man execve

  • writeline: yaptığımız yazma sistemi çağrısını gösterir. 6dizenin uzunluğudur "hello\n".

    = 6belgelendiği gibi man 2 writeyazılan bayt sayısı olan sistem çağrısının dönüş değeridir .

  • exitline: yaptığımız çıkış sistemi çağrısını gösterir. Programdan çıkıldığı için dönüş değeri yoktur!

Daha karmaşık örnekler

Strace uygulaması elbette programınızın hatalarını ayıklamak / optimize etmek için karmaşık programların gerçekte hangi sistem çağrılarını yaptığını görmektir.

Özellikle, Linux'ta karşılaşma olasılığı çoğu sistem çağrıları, glibc sarmalayıcılarını var POSIX birçoğu .

Dahili olarak, glibc sarmalayıcıları satır içi montajı aşağıdaki gibi kullanır: şöyle kullanır: Satır içi montajda sysenter aracılığıyla bir sistem çağrısı nasıl çağrılır?

Çalışmanız gereken bir sonraki örnek POSIX write merhaba dünyası:

main.c

#define _XOPEN_SOURCE 700
#include <unistd.h>

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

Derleyin ve çalıştırın:

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

Bu sefer glibc tarafından daha önce bir grup sistem çağrısı yapıldığını göreceksiniz. main main için güzel bir ortam .

Çünkü artık bağımsız bir program değil, libc işlevselliğine izin veren daha yaygın bir glibc programı kullanıyoruz.

Ardından, her iki uçta strace.logşunları içerir:

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

Bu yüzden writePOSIX işlevinin kullandığı, sürpriz !, Linuxwrite sistem çağrısı olarak

Bunun yerine return 0bir exit_groupçağrıya yol açtığını da gözlemliyoruz exit. Ha, bunu bilmiyordum! Bu yüzden straceçok havalı. man exit_groupsonra açıklar:

Bu sistem çağrısı, yalnızca çağıran iş parçacığını değil, çağıran işlemin iş parçacığı grubundaki tüm iş parçacıklarını sonlandırması dışında exit (2) öğesine eşdeğerdir.

Ve hangi sistem çağrısının dlopenkullandığı çalıştığım başka bir örnek : /unix/226524/what-system-call-is-used-to-load-libraries-in-linux/462710#462710

Ubuntu 16.04, GCC 6.4.0, Linux çekirdeği 4.4.0'da test edilmiştir.


2

Web sitelerine girmek için strace'yi nasıl kullandığımın bazı örnekleri. Umarım bu yardımcı olur.

İlk bayta kadar zaman kontrol edin:

time php index.php > timeTrace.txt

İşlemlerin yüzde kaçının ne yaptığını görün. Bir sürü lstatve fstatönbelleği temizleme zamanı geldiğinin bir göstergesi olabilir:

strace -s 200 -c php index.php > traceLstat.txt

Çıkışlar bir trace.txtsen çağrılar yapılıyor tam olarak ne görebilirsiniz.

strace -Tt -o Fulltrace.txt php index.php

Şey arasında alıp almadığını kontrol etmek bunu kullanın .1için .9yüke saniyenin:

cat Fulltrace.txt | grep "[<]0.[1-9]" > traceSlowest.txt

Hangi eksik dosyaların veya dizinlerin içinde yakalandığını görün strace. Bu, sistemimizle ilgili bir çok şey üretir - yalnızca ilgili bitler müşterinin dosyalarını içerir:

strace -vv php index.php 2>&1 | sed -n '/= -1/p' > traceFailures.txt

1

Okuduğu bazı cevapları beğendim strace, işletim sisteminizle nasıl etkileşime girdiğinizi kontrol ediyor.

Bu tam olarak görebildiğimiz şey. Sistem çağırır. Karşılaştırırsanız straceve ltracefark daha belirgindir.

$>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

Öte yandan ltraceizlerin işlevleri vardır.

$>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

Kılavuzları birkaç kez kontrol etsem de, adın kaynağını bulamadım, straceancak bu açık olduğu için muhtemelen sistem çağrısı izleme.

Hakkında söylenecek üç büyük not var strace.

Not 1: bu işlevler Hem straceve ltracesistem çağrı kullanıyoruz ptrace. Yani ptracesistem çağrısı etkili bir şekilde straceçalışır.

Ptrace () sistem çağrısı, bir işlemin ("izleyici") başka bir işlemin ("izleyici") yürütülmesini gözlemleyebileceği ve denetleyebileceği ve izleyicinin belleğini ve kayıtlarını inceleyip değiştirebileceği bir yol sağlar. Öncelikle kesme noktası hata ayıklama ve sistem çağrısı izlemeyi uygulamak için kullanılır.

Not 2: Eğer kullanabileceğiniz farklı parametreler vardır strace, çünkü straceçok ayrıntılı olabilir. Ben denemek istiyorum, -changi şeylerin bir özeti gibidir. Buna dayanarak, yalnızca bu çağrıyı göreceğiniz -cgibi bir sistem çağrısı seçebilirsiniz -e trace=open. İzlediğiniz komut sırasında hangi dosyaların açılacağını inceliyorsanız bu ilginç olabilir. Ve elbette, grepaynı amaç için kullanabilirsiniz, ancak 2>&1 | grep etckomut verildiğinde yapılandırma dosyalarına başvurulduğunu anlamak için bu şekilde yeniden yönlendirmeniz gerektiğini unutmayın .

Not 3: Bu çok önemli notu buluyorum. Belirli bir mimariyle sınırlı değilsiniz. straceaklınızı başınızdan alacak çünkü farklı mimarilerin ikili dosyalarının izini sürecek. resim açıklamasını buraya girin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.