Bagaimana seharusnya strace digunakan?


273

Seorang kolega pernah mengatakan kepada saya bahwa opsi terakhir ketika semuanya gagal debug pada Linux adalah menggunakan strace .

Saya mencoba mempelajari ilmu di balik alat aneh ini, tetapi saya bukan guru sistem admin dan saya tidak benar-benar mendapatkan hasil.

Begitu,

  • Apa itu sebenarnya dan apa fungsinya?
  • Bagaimana dan dalam kasus apa sebaiknya digunakan?
  • Bagaimana seharusnya output dipahami dan diproses?

Singkatnya, dengan kata-kata sederhana , bagaimana cara kerjanya?


2
strace -p <pid> akan memberi tahu Anda apa yang terjadi sekarang dengan program Anda ..... cepat dan mudah daripada GDB
ernesto

1
Saya pribadi menemukan man stracesangat mudah dibaca dan bermanfaat. (PS belum tahu tentang strace sebelum kemarin dan bukan pakar Linux)
Alexander Malakhov

1
"strace adalah pelacak panggilan sistem" - ini hanya menunjukkan kepada Anda apa fungsi-fungsi kernel yang dipanggil (dengan argumennya) sebagai hasil dari program Anda.
Pithikos

Jawaban:


184

Ikhtisar Strace
strace dapat dilihat sebagai debugger ringan. Ini memungkinkan seorang programmer / pengguna untuk dengan cepat mengetahui bagaimana suatu program berinteraksi dengan OS. Ini dilakukan dengan memonitor panggilan dan sinyal sistem.

Menggunakan
Baik untuk ketika Anda tidak memiliki kode sumber atau tidak ingin diganggu untuk benar-benar pergi melalui itu.
Juga, berguna untuk kode Anda sendiri jika Anda tidak ingin membuka GDB, tetapi hanya tertarik untuk memahami interaksi eksternal.

Sebuah perkenalan kecil yang bagus
saya bertemu intro ini untuk menggunakan strace beberapa hari yang lalu: strace hello world


Jadi bagaimana jika Anda menggunakan sesuatu di bawah lapisan yang strace monitor?
Pacerier

Dalam hal ini @Pacerier periksa ltrace stackoverflow.com/a/52012215/5884955
prosti

Ini bagus untuk debugging program tingkat rendah yang hanya ada / sebagian besar untuk membuat panggilan sistem yang menarik, atau bereksperimen dengan opsi baru untuk syscalls untuk melihat apa yang OS Anda lakukan. Ini pada dasarnya menghemat masalah penulisan log / kode pemeriksaan kesalahan untuk eksperimen satu kali. (Atau jika Anda menulis dalam asm atau sesuatu di mana ada peluang bagus Anda secara tidak sengaja melewati argumen salah atau bahkan nomor panggilan.) Strace jauh lebih cepat daripada GDB karena mencari kode errno untuk Anda, misalnya -EFAULT(oops, read-only buffer) atau -ENOENT(oops, lari dari direktori yang salah di mana jalur relatif tidak berfungsi).)
Peter Cordes

62

Dengan kata sederhana, strace melacak semua panggilan sistem yang dikeluarkan oleh suatu program bersama dengan kode kembali mereka. Pikirkan hal-hal seperti operasi file / socket dan banyak lagi yang tidak jelas.

Ini sangat berguna jika Anda memiliki pengetahuan tentang C karena di sini panggilan sistem akan lebih akurat untuk panggilan perpustakaan C standar.

Katakanlah program Anda adalah / usr / local / bin / cough. Cukup gunakan:

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

atau

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

untuk menulis ke 'out_file'.

Semua output strace akan menuju ke stderr (berhati-hatilah, volume tipisnya sering meminta pengalihan ke file). Dalam kasus yang paling sederhana, program Anda akan dibatalkan dengan kesalahan dan Anda akan dapat melihat di mana interaksi terakhirnya dengan OS dalam output strace.

Informasi lebih lanjut harus tersedia dengan:

man strace

36

strace mendaftar semua panggilan sistem yang dilakukan oleh proses yang diterapkan. Jika Anda tidak tahu apa arti panggilan sistem, Anda tidak akan bisa mendapatkan banyak jarak tempuh dari itu.

Namun demikian, jika masalah Anda melibatkan file atau path atau nilai lingkungan, menjalankan strace pada program yang bermasalah dan mengarahkan output ke file dan kemudian mengambil file itu untuk path / file / string env Anda dapat membantu Anda melihat apa yang sebenarnya sedang dicoba program Anda untuk lakukan. lakukan, berbeda dari apa yang Anda harapkan.


7
Dan untuk program non-sepele ini sering seperti minum dari selang api, sehingga Anda memiliki pekerjaan Anda dipotong untuk Anda melalui hasil ...
dmckee --- mantan moderator kucing

17
strace <prog_name>untuk melacak suatu program. strace -o <out_file> <prog_name>untuk keluar dimasukkan ke file
Jestin Joy

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

10
Atau cukup: strace -e open myprogATAU untuk semua panggilan sistem terkait file:strace -e file myprog
Amit Naidu

17

Strace menonjol sebagai alat untuk menyelidiki sistem produksi di mana Anda tidak mampu menjalankan program-program ini di bawah debugger. Secara khusus, kami telah menggunakan strace dalam dua situasi berikut:

  • Program foo tampaknya menemui jalan buntu dan menjadi tidak responsif. Ini bisa menjadi target untuk gdb; namun, kami tidak selalu memiliki kode sumber atau terkadang berhadapan dengan bahasa skrip yang tidak mudah dijalankan di bawah debugger. Dalam hal ini, Anda menjalankan strace pada program yang sudah berjalan dan Anda akan mendapatkan daftar panggilan sistem yang dibuat. Ini sangat berguna jika Anda sedang menyelidiki aplikasi klien / server atau aplikasi yang berinteraksi dengan database
  • Menyelidiki mengapa program lambat. Secara khusus, kami baru saja pindah ke sistem file terdistribusi baru dan throughput baru sistem sangat lambat. Anda dapat menentukan strace dengan opsi '-T' yang akan memberi tahu Anda berapa banyak waktu yang dihabiskan dalam setiap panggilan sistem. Ini membantu menentukan mengapa sistem file menyebabkan segalanya melambat.

Untuk contoh menganalisis menggunakan strace lihat jawaban saya untuk pertanyaan ini .


15

Saya menggunakan strace setiap saat untuk men-debug masalah izin. Tekniknya seperti ini:

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

Di mana gnome-calculatorperintah yang ingin Anda jalankan.


8

strace -tfp PID akan memonitor panggilan sistem proses PID, sehingga kami dapat men-debug / memantau status proses / program kami.


6

Strace dapat digunakan sebagai alat debugging, atau sebagai profiler primitif.

Sebagai debugger, Anda dapat melihat bagaimana panggilan sistem yang diberikan dipanggil, dieksekusi dan apa yang mereka kembalikan. Ini sangat penting, karena memungkinkan Anda untuk melihat tidak hanya bahwa suatu program gagal, tetapi MENGAPA sebuah program gagal. Biasanya itu hanya hasil dari pengkodean yang buruk tidak menangkap semua hasil yang mungkin dari suatu program. Lain kali itu hanya jalur hardcoded ke file. Tanpa strace Anda bisa menebak apa yang salah di mana dan bagaimana. Dengan strace Anda mendapatkan rincian dari syscall, biasanya hanya dengan melihat nilai pengembalian memberitahu Anda banyak.

Pembuatan profil adalah kegunaan lain. Anda dapat menggunakannya untuk waktu eksekusi setiap syscall secara individual, atau sebagai agregat. Meskipun ini mungkin tidak cukup untuk memperbaiki masalah Anda, setidaknya akan sangat mempersempit daftar tersangka potensial. Jika Anda melihat banyak pasangan terbuka / tertutup pada satu file, Anda mungkin tidak perlu membuka dan menutup file setiap kali eksekusi loop, alih-alih membuka dan menutupnya di luar loop.

Ltrace adalah sepupu dekat Strace, juga sangat berguna. Anda harus belajar membedakan mana kemacetan Anda. Jika total eksekusi adalah 8 detik, dan Anda hanya menghabiskan 0,05 detik untuk panggilan sistem, maka mengganti program tidak akan banyak membantu Anda, masalahnya ada dalam kode Anda, yang biasanya merupakan masalah logika, atau program sebenarnya membutuhkan membutuhkan waktu lama untuk berjalan.

Masalah terbesar dengan strace / ltrace adalah membaca outputnya. Jika Anda tidak tahu bagaimana panggilan dibuat, atau setidaknya nama syscalls / fungsi, itu akan sulit untuk menguraikan artinya. Mengetahui fungsi yang dikembalikan juga bisa sangat bermanfaat, terutama untuk kode kesalahan yang berbeda. Meskipun sulit untuk diuraikan, terkadang mereka benar-benar mengembalikan mutiara pengetahuan; begitu saya melihat situasi di mana saya kehabisan inode, tetapi tidak keluar dari ruang kosong, jadi semua utilitas yang biasa tidak memberi saya peringatan, saya tidak bisa membuat file baru. Membaca kode kesalahan dari output strace menunjuk saya ke arah yang benar.


4

Strace adalah alat yang memberi tahu Anda bagaimana aplikasi Anda berinteraksi dengan sistem operasi Anda.

Itu melakukan ini dengan memberi tahu Anda apa sistem OS panggilan aplikasi Anda gunakan dan dengan apa parameter itu memanggil mereka.

Jadi misalnya Anda melihat file apa yang coba dibuka oleh program Anda, dan cuaca panggilan berhasil.

Anda dapat men-debug segala macam masalah dengan alat ini. Sebagai contoh jika aplikasi mengatakan bahwa itu tidak dapat menemukan perpustakaan yang Anda tahu telah Anda instal, Anda strace akan memberi tahu Anda di mana aplikasi mencari file itu.

Dan itu hanyalah puncak gunung es.


ini sangat tepat.
prosti

4

strace adalah alat yang baik untuk mempelajari bagaimana program Anda melakukan berbagai panggilan sistem (permintaan ke kernel) dan juga melaporkan yang gagal bersama dengan nilai kesalahan yang terkait dengan kegagalan itu. Tidak semua kegagalan adalah bug. Misalnya, kode yang mencoba mencari file mungkin mendapatkan kesalahan ENOENT (Tidak ada file atau direktori) tetapi itu mungkin skenario yang dapat diterima dalam logika kode.

Salah satu kasus penggunaan yang baik dari menggunakan strace adalah untuk men-debug kondisi ras selama pembuatan file sementara. Misalnya program yang mungkin membuat file dengan menambahkan ID proses (PID) ke beberapa string yang telah ditentukan mungkin menghadapi masalah dalam skenario multi-berulir. [PID + TID (id proses + id utas) atau panggilan sistem yang lebih baik seperti mkstemp akan memperbaikinya].

Ini juga bagus untuk debugging crash. Anda mungkin menemukan artikel (saya) ini tentang strace dan debugging macet berguna.


4

Contoh runnable minimal

Jika suatu konsep tidak jelas, ada contoh sederhana yang belum Anda lihat yang menjelaskannya.

Dalam hal ini, contoh itu adalah hello world assembly x86_64 freestanding (no libc) hello world:

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 hulu .

Merakit dan menjalankan:

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

Output yang diharapkan:

hello

Sekarang mari kita gunakan strace pada contoh itu:

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

Kita gunakan:

strace.log sekarang mengandung:

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

Dengan contoh minimal seperti itu, setiap karakter tunggal dari output jelas:

  • execvebaris: menunjukkan bagaimana stracedieksekusi hello.out, termasuk argumen dan lingkungan CLI seperti yang didokumentasikan diman execve

  • writeline: menunjukkan panggilan sistem tulis yang kami buat. 6adalah panjang dari string "hello\n".

    = 6adalah nilai balik dari panggilan sistem, yang seperti yang didokumentasikan man 2 writeadalah jumlah byte yang ditulis.

  • exitline: menunjukkan panggilan keluar sistem yang kami buat. Tidak ada nilai balik, karena program berhenti!

Contoh yang lebih kompleks

Penerapan strace tentu saja untuk melihat sistem mana yang memanggil program kompleks yang sebenarnya dilakukan untuk membantu men-debug / mengoptimalkan program Anda.

Khususnya, sebagian besar panggilan sistem yang mungkin Anda temui di Linux memiliki pembungkus glibc, banyak dari mereka dari POSIX .

Secara internal, pembungkus glibc menggunakan perakitan inline kurang lebih seperti ini: Bagaimana menjalankan panggilan sistem melalui sysenter dalam perakitan inline?

Contoh selanjutnya yang harus Anda pelajari adalah writedunia hello POSIX :

main.c

#define _XOPEN_SOURCE 700
#include <unistd.h>

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

Kompilasi dan jalankan:

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

Kali ini, Anda akan melihat bahwa banyak panggilan sistem sedang dilakukan oleh glibc sebelum mainmenyiapkan lingkungan yang bagus untuk main.

Ini karena kita sekarang tidak menggunakan program berdiri bebas, melainkan program glibc yang lebih umum, yang memungkinkan fungsionalitas libc.

Kemudian, di setiap akhir, strace.logberisi:

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

Jadi kami menyimpulkan bahwa writefungsi POSIX menggunakan, kejutan !, Linuxwrite panggilan sistem .

Kami juga mengamati bahwa return 0mengarah pada exit_grouppanggilan alih-alih exit. Ha, saya tidak tahu tentang yang ini! Inilah mengapa stracesangat keren. man exit_groupkemudian menjelaskan:

Panggilan sistem ini setara dengan keluar (2) kecuali bahwa itu tidak hanya mengakhiri utas panggilan, tetapi semua utas dalam grup utas proses panggilan itu.

Dan di sini adalah contoh lain di mana saya mempelajari yang dlopenmenggunakan sistem panggilan : /unix/226524/what-system-call-is-used-to-load-libraries-in-linux/462710#462710

Diuji di Ubuntu 16.04, GCC 6.4.0, kernel Linux 4.4.0.


2

Berikut adalah beberapa contoh bagaimana saya menggunakan strace untuk menggali situs web. Semoga ini bisa membantu.

Periksa waktu untuk byte pertama seperti:

time php index.php > timeTrace.txt

Lihat persentase tindakan yang melakukan apa. Banyak lstatdan fstatbisa menjadi indikasi bahwa sudah waktunya untuk menghapus cache:

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

Output a trace.txtsehingga Anda dapat melihat dengan tepat panggilan apa yang sedang dibuat.

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

Gunakan ini untuk memeriksa apakah sesuatu mengambil antara .1ke .9detik untuk beban:

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

Lihat file atau direktori yang hilang yang terperangkap di strace. Ini akan menampilkan banyak hal yang melibatkan sistem kami - bit yang relevan hanya melibatkan file pelanggan:

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

1

Saya menyukai beberapa jawaban yang terbaca strace memeriksa bagaimana Anda berinteraksi dengan sistem operasi Anda.

Inilah yang bisa kita lihat. Sistem memanggil. Jika Anda membandingkan stracedan ltraceperbedaannya lebih jelas.

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

Di sisi lain ada ltraceyang melacak fungsi.

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

Meskipun saya telah memeriksa manual beberapa kali, saya belum menemukan asal nama stracetetapi kemungkinan jejak panggilan sistem, karena ini jelas.

Ada tiga catatan yang lebih besar untuk dikatakan strace.

Catatan 1: Kedua fungsi ini stracedan ltracemenggunakan panggilan sistem ptrace. Jadi ptracesystem call secara efektif cara stracekerjanya.

Panggilan sistem ptrace () menyediakan sarana di mana satu proses ("pelacak") dapat mengamati dan mengendalikan pelaksanaan proses lain ("jejak"), dan memeriksa serta mengubah memori jejak dan register. Ini terutama digunakan untuk mengimplementasikan breakpoint debugging dan pelacakan panggilan sistem.

Catatan 2: Ada beberapa parameter yang dapat Anda gunakan strace, karena stracebisa sangat verbose. Saya suka bereksperimen dengan -cyang seperti ringkasan hal-hal. Berdasarkan -cAnda dapat memilih satu panggilan sistem seperti di -e trace=openmana Anda hanya akan melihat panggilan itu. Ini bisa menarik jika Anda memeriksa file apa yang akan dibuka selama perintah yang Anda lacak. Dan tentu saja, Anda dapat menggunakan grepuntuk tujuan yang sama tetapi perhatikan bahwa Anda perlu mengarahkan ulang seperti ini 2>&1 | grep etcuntuk memahami bahwa file konfigurasi direferensikan ketika perintah dikeluarkan.

Catatan 3: Saya menemukan catatan yang sangat penting ini. Anda tidak terbatas pada arsitektur tertentu. straceakan mengejutkan Anda, karena dapat melacak binari dari arsitektur yang berbeda. masukkan deskripsi gambar di sini

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.