Debugging panyebaran piranti lunak kanthi strace

Debugging panyebaran piranti lunak kanthi strace

Pakaryan dinaku biasane nyebarake piranti lunak, tegese aku nggunakake akeh wektu kanggo nyoba mangsuli pitakon kaya:

  • Piranti lunak iki bisa digunakake kanggo pangembang, nanging ora kanggo aku. Kenging punapa?
  • Wingi piranti lunak iki bisa digunakake kanggo kula, nanging dina iki ora. Kenging punapa?

Iki minangka jinis debugging sing rada beda karo debugging piranti lunak biasa. Debugging reguler yaiku babagan logika kode, nanging debugging penyebaran babagan interaksi antarane kode lan lingkungan. Malah yen oyod saka masalah iku kesalahan logis, kasunyatan sing kabeh dianggo ing siji mesin lan ora ing liyane tegese masalah iku piye wae ing lingkungan.

Dadi tinimbang alat debugging biasanipun kaya gdb Aku duwe macem-macem alat kanggo panyebaran debugging. Lan alat favoritku kanggo ngatasi masalah kaya "Napa piranti lunak iki ora bisa digunakake kanggo aku?" diarani strace.

Apa iku strace?

strace iku alat kanggo "telpon sistem nelusuri". Iki asline digawe kanggo Linux, nanging trik debugging sing padha bisa ditindakake nganggo alat kanggo sistem liyane (DTrace utawa ktration).

Aplikasi dhasar banget prasaja. Sampeyan mung kudu mbukak strace karo printah lan bakal mbucal kabeh telpon sistem (sanajan pisanan sampeyan kudu nginstal dhewe. strace):

$ strace echo Hello
...Snip lots of stuff...
write(1, "Hellon", 6)                  = 6
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++

Apa sing diarani sistem kasebut? Iki kaya API kanggo kernel sistem operasi. Ing jaman biyen, piranti lunak duwe akses langsung menyang piranti keras sing digunakake. Yen, contone, iku perlu kanggo nampilake soko ing layar, diputer karo bandar utawa ndhaftar memori-dipetake kanggo piranti video. Nalika sistem komputer mbukak akeh tugas dadi populer, kekacauan mrentah amarga macem-macem aplikasi nglawan hardware. Kesalahan ing siji aplikasi bisa nyebabake wong liya, yen ora kabeh sistem. Banjur mode hak istimewa (utawa "proteksi dering") katon ing CPU. Kernel dadi paling istimewa: entuk akses lengkap menyang hardware, ngasilake aplikasi sing kurang duwe hak istimewa sing kudu njaluk akses saka kernel kanggo sesambungan karo hardware liwat panggilan sistem.

Ing tingkat binar, telpon sistem rada beda karo telpon fungsi sing prasaja, nanging umume program nggunakake pambungkus ing perpustakaan standar. Sing. perpustakaan standar POSIX C ngemot telpon fungsi nulis (), sing ngemot kabeh kode khusus arsitektur kanggo telpon sistem nulis.

Debugging panyebaran piranti lunak kanthi strace

Singkate, interaksi apa wae antarane aplikasi lan lingkungane (sistem komputer) ditindakake liwat panggilan sistem. Mulane, nalika piranti lunak bisa digunakake ing siji mesin nanging ora ing liyane, iku bakal apik kanggo katon ing asil nelusuri telpon sistem. Luwih khusus, ing ngisor iki minangka dhaptar poin khas sing bisa dianalisis nggunakake jejak panggilan sistem:

  • Konsol I/O
  • Jaringan I/O
  • Akses sistem file lan file I/O
  • Ngatur umur thread proses
  • Manajemen memori tingkat rendah
  • Akses menyang driver piranti tartamtu

Nalika nggunakake strace?

Ing teori, strace digunakake karo program apa wae ing ruang pangguna, amarga program apa wae ing ruang pangguna kudu nggawe panggilan sistem. Kerjane luwih efisien karo program tingkat rendah sing disusun, nanging uga bisa digunakake karo basa tingkat dhuwur kaya Python yen sampeyan bisa ngilangi gangguan tambahan saka runtime lan interpreter.

Ing kabeh kamulyan strace manifests dhewe sak debugging saka piranti lunak sing dianggo uga ing siji mesin, nanging dumadakan mandheg nggarap liyane, mrodhuksi pesen samar-samar babagan file, ijin, utawa nyoba gagal kanggo nglakokaké sawetara printah utawa liyane ... Sayange, nanging ora. gabungke kanthi apik karo masalah tingkat dhuwur kayata kesalahan verifikasi sertifikat. Biasane iki mbutuhake kombinasi stracekadang nglacak lan alat tingkat sing luwih dhuwur (kayata alat baris perintah openssl kanggo debug sertifikat).

Kita bakal nggunakake server mandiri minangka conto, nanging pelacakan panggilan sistem asring bisa ditindakake ing platform penyebaran sing luwih rumit. Sampeyan mung kudu milih alat sing bener.

Tuladha debugging prasaja

Ayo dadi ngomong sampeyan pengin mbukak aplikasi server apik tenan foo, lan iki apa sampeyan mungkasi karo:

$ foo
Error opening configuration file: No such file or directory

Ketoke ora bisa nemokake file konfigurasi sing sampeyan tulis. Iki kedadeyan amarga kadhangkala nalika manajer paket ngumpulake aplikasi, dheweke ngilangi lokasi file sing dikarepake. Lan yen sampeyan tindakake pandhuan instalasi kanggo siji distribusi, ing liyane sampeyan nemokake file temen beda saka ngendi sampeyan samesthine. Masalah bisa ditanggulangi ing sawetara detik yen pesen kesalahan marang ngendi kanggo nggoleki file konfigurasi, nanging ora. Dadi ngendi kanggo katon?

Yen sampeyan duwe akses menyang kode sumber, sampeyan bisa maca lan ngerteni kabeh. A rencana serep apik, nanging ora solusi paling cepet. Sampeyan bisa Resor kanggo langkah-langkah dening-debugger kaya gdb lan ndeleng apa sing ditindakake program kasebut, nanging luwih efektif nggunakake alat sing dirancang khusus kanggo nuduhake interaksi karo lingkungan: strace.

kesimpulan strace koyone keluwih, nanging kabar apik sing paling bisa digatèkaké aman. Asring migunani kanggo nggunakake operator -o kanggo nyimpen asil tilak menyang file sing kapisah:

$ strace -o /tmp/trace foo
Error opening configuration file: No such file or directory
$ cat /tmp/trace
execve("foo", ["foo"], 0x7ffce98dc010 /* 16 vars */) = 0
brk(NULL)                               = 0x56363b3fb000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=25186, ...}) = 0
mmap(NULL, 25186, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f2f12cf1000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "177ELF2113 3 > 1 260A2 "..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1824496, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2f12cef000
mmap(NULL, 1837056, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f2f12b2e000
mprotect(0x7f2f12b50000, 1658880, PROT_NONE) = 0
mmap(0x7f2f12b50000, 1343488, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7f2f12b50000
mmap(0x7f2f12c98000, 311296, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16a000) = 0x7f2f12c98000
mmap(0x7f2f12ce5000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b6000) = 0x7f2f12ce5000
mmap(0x7f2f12ceb000, 14336, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f2f12ceb000
close(3)                                = 0
arch_prctl(ARCH_SET_FS, 0x7f2f12cf0500) = 0
mprotect(0x7f2f12ce5000, 16384, PROT_READ) = 0
mprotect(0x56363b08b000, 4096, PROT_READ) = 0
mprotect(0x7f2f12d1f000, 4096, PROT_READ) = 0
munmap(0x7f2f12cf1000, 25186)           = 0
openat(AT_FDCWD, "/etc/foo/config.json", O_RDONLY) = -1 ENOENT (No such file or directory)
dup(2)                                  = 3
fcntl(3, F_GETFL)                       = 0x2 (flags O_RDWR)
brk(NULL)                               = 0x56363b3fb000
brk(0x56363b41c000)                     = 0x56363b41c000
fstat(3, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x8), ...}) = 0
write(3, "Error opening configuration file"..., 60) = 60
close(3)                                = 0
exit_group(1)                           = ?
+++ exited with 1 +++

Kira-kira kabeh kaca pisanan output strace - Iki biasane persiapan tingkat rendah kanggo diluncurake. (Akeh telpon mmap, mproteksi, brk kanggo iku kaya ndeteksi memori tingkat kurang lan nampilake perpustakaan dinamis.) Bener, sak debugging output strace Luwih becik maca saka pungkasan. Bakal ana tantangan ing ngisor iki nulis, sing nampilake pesen kesalahan. Kita katon ing ndhuwur lan ndeleng telpon sistem sing salah pisanan - telpon mbukak, kang mbalang kesalahan ENOENT ("file utawa direktori ora ditemokake") nyoba mbukak /etc/foo/config.json. Iki ngendi file konfigurasi kudu.

Iki mung conto, nanging aku bakal ngomong 90% wektu sing digunakake strace, ora ana sing luwih angel ditindakake tinimbang iki. Ing ngisor iki minangka pandhuan debugging langkah-langkah lengkap:

  • Kesel amarga pesen sing ora jelas babagan kesalahan sistem-y saka program
  • Wiwiti maneh program karo strace
  • Golek pesen kesalahan ing asil tilak
  • Pindhah luwih dhuwur nganti sampeyan mencet telpon sistem gagal pisanan

Kemungkinan banget yen telpon sistem ing langkah 4 bakal mbukak apa sing salah.

Tips

Sadurunge nuduhake conto debugging sing luwih rumit, aku bakal nuduhake sawetara trik supaya bisa digunakake kanthi efektif strace:

wong iku kancamu

Ing akeh sistem *nix, dhaptar lengkap panggilan sistem menyang kernel bisa dipikolehi kanthi mlaku wong syscalls. Sampeyan bakal weruh kaya brk(2), sing tegese informasi luwih akeh bisa dipikolehi kanthi mlaku wong 2 brk.

Rega cilik: wong 2 garpu nuduhake kula kaca kanggo cangkang garpu () в GNU libc, kang, iku dadi metu, dipun ginakaken dening nelpon kloning(). Telpon semantik Garpu tetep padha yen sampeyan nulis program nggunakake garpu (), lan mbukak tilak - Aku ora bakal nemokake sembarang telpon Garpu, tinimbang wong-wong mau bakal ana kloning(). Rakes kuwi mung bingung yen sampeyan miwiti mbandhingaké sumber karo output strace.

Gunakake -o kanggo nyimpen output menyang file

strace bisa generate output ekstensif, supaya asring migunani kanggo nyimpen asil tilak ing file kapisah (minangka ing conto ing ndhuwur). Iki uga mbantu supaya output program bingung karo output strace ing console.

Gunakake -s kanggo ndeleng data argumen liyane

Sampeyan bisa uga wis ngeweruhi sing separo kapindho pesen kesalahan ora ditampilake ing conto tilak ndhuwur. Iku amarga strace standar mung nuduhake 32 bait pisanan saka argumen string. Yen sampeyan pengin ndeleng liyane, nambah kaya -s 128 menyang telpon strace.

-y nggampangake kanggo trek file, soket, etc.

"Kabeh iku file" tegese * sistem nix nindakake kabeh I / O nggunakake deskriptor file, apa sing ditrapake kanggo file utawa jaringan utawa interprocess pipe. Iki trep kanggo program, nanging nggawe angel nglacak apa sing kedadeyan nalika sampeyan ndeleng umum maca и nulis ing asil tilak telpon sistem.

Kanthi nambahake operator ya, sampeyan bakal meksa strace annotate saben deskriptor file ing output kanthi cathetan apa sing dituju.

Pasang menyang proses sing wis mlaku nganggo -p**

Nalika sampeyan bakal weruh saka conto ing ngisor iki, kadhangkala sampeyan kudu nglacak program sing wis mlaku. Yen dingerteni yen lagi mlaku minangka proses 1337 (ujare, saka output ps), banjur sampeyan bisa nglacak kaya iki:

$ strace -p 1337
...system call trace output...

Sampeyan bisa uga mbutuhake hak root.

Gunakake -f kanggo ngawasi proses anak

strace Kanthi gawan, mung nglacak siji proses. Yen proses iki ngasilake proses anak, mula sistem panggilan kanggo ngasilake proses anak bisa dideleng, nanging panggilan sistem proses anak ora bakal ditampilake.

Yen sampeyan mikir kesalahan ana ing proses anak, gunakake statement kasebut -f, iki bakal ngaktifake nelusuri. Kakurangan iki yaiku output bakal luwih mbingungake sampeyan. kapan strace nglacak siji proses utawa siji thread, nuduhake stream siji acara telpon. Nalika nglacak sawetara proses bebarengan, sampeyan bisa ndeleng wiwitan telpon diselani dening pesen , banjur - akeh panggilan kanggo cabang eksekusi liyane, lan mung banjur - pungkasan sing pisanan <…foocall diterusake>. Utawa pamisah kabeh asil tilak menyang file beda, uga nggunakake operator -ff (detail ing kepemimpinan ing strace).

Nyaring jejak nggunakake -e

Nalika sampeyan bisa ndeleng, asil tilak tumpukan nyata kabeh telpon sistem bisa. Gendéra -e Sampeyan bisa nyaring jejak (ndeleng nuntun ing strace). Ing kauntungan utama iku luwih cepet kanggo mbukak tilak saring saka nindakake tilak lengkap banjur grep`ing. Kanggo jujur, aku meh ora peduli.

Ora kabeh kesalahan iku ala

Conto sing prasaja lan umum yaiku program sing nggoleki file ing sawetara panggonan bebarengan, kaya cangkang sing nggoleki direktori sing ngemot file sing bisa dieksekusi:

$ strace sh -c uname
...
stat("/home/user/bin/uname", 0x7ffceb817820) = -1 ENOENT (No such file or directory)
stat("/usr/local/bin/uname", 0x7ffceb817820) = -1 ENOENT (No such file or directory)
stat("/usr/bin/uname", {st_mode=S_IFREG|0755, st_size=39584, ...}) = 0
...

Heuristik kaya "panyuwunan gagal pungkasan sadurunge nglaporake kesalahan" apik kanggo nemokake kesalahan sing cocog. Apa wae, iku logis kanggo miwiti saka pungkasan banget.

Tutorial pemrograman C bisa mbantu sampeyan ngerti panggilan sistem.

Panggilan standar menyang perpustakaan C dudu panggilan sistem, nanging mung lapisan permukaan sing tipis. Dadi, yen sampeyan ngerti sethithik babagan carane lan apa sing kudu ditindakake ing C, bakal luwih gampang sampeyan ngerti asil tilak panggilan sistem. Contone, sampeyan duwe masalah debugging telpon kanggo sistem jaringan, katon ing klasik padha Bija's Guide to Network Programming.

Conto debugging sing luwih rumit

Aku wis ngandika sing conto debugging prasaja minangka conto saka apa aku biasane kudu menehi hasil karo nalika nggarap strace. Nanging, kadhangkala investigasi nyata dibutuhake, mula iki conto nyata babagan debugging sing luwih maju.

bcron - panjadwal pangolahan tugas, implementasine liyane saka * daemon nix cron. Iki wis diinstal ing server, nanging nalika ana sing nyoba ngowahi jadwal, iki kedadeyan:

# crontab -e -u logs
bcrontab: Fatal: Could not create temporary file

Oke, tegese bcron nyoba kanggo nulis file tartamtu, nanging ora bisa metu, lan ora bakal ngakeni apa. Uncovering strace:

# strace -o /tmp/trace crontab -e -u logs
bcrontab: Fatal: Could not create temporary file
# cat /tmp/trace
...
openat(AT_FDCWD, "bcrontab.14779.1573691864.847933", O_RDONLY) = 3
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f82049b4000
read(3, "#Ansible: logsaggn20 14 * * * lo"..., 8192) = 150
read(3, "", 8192)                       = 0
munmap(0x7f82049b4000, 8192)            = 0
close(3)                                = 0
socket(AF_UNIX, SOCK_STREAM, 0)         = 3
connect(3, {sa_family=AF_UNIX, sun_path="/var/run/bcron-spool"}, 110) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f82049b4000
write(3, "156:Slogs #Ansible: logsaggn20 1"..., 161) = 161
read(3, "32:ZCould not create temporary f"..., 8192) = 36
munmap(0x7f82049b4000, 8192)            = 0
close(3)                                = 0
write(2, "bcrontab: Fatal: Could not creat"..., 49) = 49
unlink("bcrontab.14779.1573691864.847933") = 0
exit_group(111)                         = ?
+++ exited with 111 +++

Ana pesen kesalahan ing pungkasan nulis, nanging wektu iki ana sing beda. Kaping pisanan, ora ana kesalahan panggilan sistem sing relevan, sing biasane kedadeyan sadurunge. Kapindho, jelas manawa ana wong sing wis maca pesen kesalahan. Iku katon kaya masalah nyata nang endi wae liya, lan bcontab mung muter maneh pesen.

Yen sampeyan ndeleng wong 2 maca, sampeyan bisa ndeleng manawa argumen pisanan (3) minangka deskriptor file, sing *nix digunakake kanggo kabeh pangolahan I / O. Kepiye carane ngerteni apa sing diwakili dening deskriptor file 3? Ing kasus tartamtu, sampeyan bisa mbukak strace karo operator ya (ndeleng ndhuwur) lan kanthi otomatis bakal menehi pitutur marang kowe, nanging kanggo mangerteni barang kaya iki, migunani kanggo ngerti carane maca lan ngurai asil tilak.

Sumber deskriptor file bisa dadi salah siji saka akeh panggilan sistem (kabeh gumantung saka apa deskriptor kasebut - konsol, soket jaringan, file kasebut dhewe, utawa liya-liyane), nanging apa wae, kita nggoleki. nelpon dening bali 3 (i.e. .. kita goleki "= 3" ing asil nelusuri). Ing asil iki ana 2: mbukak ing ndhuwur banget lan soket Ing tengah. mbukak mbukak file nanging cedhak(3) banjur bakal nuduhake yen ditutup maneh. (Rake: deskriptor file bisa digunakake maneh nalika dibukak lan ditutup). Telpon soket () cocok amarga iku sing pungkasan sadurunge waca (), lan dadi metu sing bcontab bisa karo soko liwat soket. Baris sabanjure nuduhake yen deskriptor file digandhengake karo soket domain unix sadawane dalan /var/run/bcron-spool.

Dadi, kita kudu nemokake proses sing ana gandhengane soket unix ing sisih liyane. Ana sawetara trik sing apik kanggo tujuan iki, loro-lorone migunani kanggo debugging panyebaran server. Kapisan yaiku nggunakake netstat utawa luwih anyar ss (status soket). Loro-lorone printah nuduhake sambungan jaringan aktif sistem lan njupuk statement -l kanggo njlèntrèhaké soket ngrungokake, uga operator -p kanggo nampilake program sing disambungake menyang soket minangka klien. (Ana akeh opsi sing luwih migunani, nanging loro iki cukup kanggo tugas iki.)

# ss -pl | grep /var/run/bcron-spool
u_str LISTEN 0   128   /var/run/bcron-spool 1466637   * 0   users:(("unixserver",pid=20629,fd=3))

Iki nuduhake yen pamireng minangka prentah ikixserver, mlaku karo ID proses 20629. (Lan, kebetulan, nggunakake deskriptor file 3 minangka soket.)

Piranti liya sing migunani banget kanggo nemokake informasi sing padha diarani lsof. Iki nampilake kabeh file sing mbukak (utawa deskriptor file) ing sistem. Utawa sampeyan bisa entuk informasi babagan siji file tartamtu:

# lsof /var/run/bcron-spool
COMMAND   PID   USER  FD  TYPE  DEVICE              SIZE/OFF  NODE    NAME
unixserve 20629 cron  3u  unix  0x000000005ac4bd83  0t0       1466637 /var/run/bcron-spool type=STREAM

Proses 20629 minangka server sing umure dawa, supaya sampeyan bisa masang strace nggunakake soko kaya strace -o /tmp/trace -p 20629. Yen sampeyan ngowahi proyek cron ing terminal liyane, sampeyan bakal nampa output tilak karo kesalahan. Lan iki asile:

accept(3, NULL, NULL)                   = 4
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7faa47c44810) = 21181
close(4)                                = 0
accept(3, NULL, NULL)                   = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=21181, si_uid=998, si_status=0, si_utime=0, si_stime=0} ---
wait4(0, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG|WSTOPPED, NULL) = 21181
wait4(0, 0x7ffe6bc36764, WNOHANG|WSTOPPED, NULL) = -1 ECHILD (No child processes)
rt_sigaction(SIGCHLD, {sa_handler=0x55d244bdb690, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7faa47ab9840}, {sa_handler=0x55d244bdb690, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7faa47ab9840}, 8) = 0
rt_sigreturn({mask=[]})                 = 43
accept(3, NULL, NULL)                   = 4
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7faa47c44810) = 21200
close(4)                                = 0
accept(3, NULL, NULL)                   = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=21200, si_uid=998, si_status=111, si_utime=0, si_stime=0} ---
wait4(0, [{WIFEXITED(s) && WEXITSTATUS(s) == 111}], WNOHANG|WSTOPPED, NULL) = 21200
wait4(0, 0x7ffe6bc36764, WNOHANG|WSTOPPED, NULL) = -1 ECHILD (No child processes)
rt_sigaction(SIGCHLD, {sa_handler=0x55d244bdb690, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7faa47ab9840}, {sa_handler=0x55d244bdb690, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7faa47ab9840}, 8) = 0
rt_sigreturn({mask=[]})                 = 43
accept(3, NULL, NULL

(Pungkasan nampa () ora bakal rampung nalika nelusuri.) Maneh, sayangé, asil iki ora ngemot kesalahan kita looking for. Kita ora weruh pesen sing bcontag dikirim utawa ditampa saka soket. Nanging, kontrol proses lengkap (Klone, ngenteni4, SIGCHLD etc.) Proses iki spawns proses anak, kang, sampeyan bisa guess, nindakake karya nyata. Lan yen sampeyan perlu kanggo nyekel dheweke Trail, nambah menyang telpon strata -f. Iki sing bakal kita temokake nalika nelusuri pesen kesalahan ing asil anyar kanthi strace -f -o /tmp/trace -p 20629:

21470 openat(AT_FDCWD, "tmp/spool.21470.1573692319.854640", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 EACCES (Permission denied) 
21470 write(1, "32:ZCould not create temporary f"..., 36) = 36
21470 write(2, "bcron-spool[21470]: Fatal: logs:"..., 84) = 84
21470 unlink("tmp/spool.21470.1573692319.854640") = -1 ENOENT (No such file or directory)
21470 exit_group(111)                   = ?
21470 +++ exited with 111 +++

Saiki, iku soko. Proses 21470 nampa kesalahan "akses ditolak" nalika nyoba nggawe file ing path tmp/spool.21470.1573692319.854640 (gegandhengan karo direktori kerja saiki). Yen kita mung ngerti direktori kerja saiki, kita uga bakal ngerti path lengkap lan bisa ngerti sebabe proses kasebut ora bisa nggawe file sementara. Sayange, proses kasebut wis metu, dadi sampeyan ora bisa nggunakake lsof -p 21470 kanggo nemokake direktori saiki, nanging sampeyan bisa kerja ing arah ngelawan - goleki PID 21470 sistem telpon sing ngganti direktori. (Yen ora ana, PID 21470 kudu diwenehi warisan saka wong tuwa, lan iki wis liwat lsof -p ora bisa ketemu metu.) Telpon sistem iki chdir (sing gampang ditemokake kanthi bantuan mesin telusur online modern). Lan iki minangka asil panelusuran mbalikke adhedhasar asil tilak, kabeh menyang server PID 20629:

20629 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7faa47c44810) = 21470
...
21470 execve("/usr/sbin/bcron-spool", ["bcron-spool"], 0x55d2460807e0 /* 27 vars */) = 0
...
21470 chdir("/var/spool/cron")          = 0
...
21470 openat(AT_FDCWD, "tmp/spool.21470.1573692319.854640", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 EACCES (Permission denied) 
21470 write(1, "32:ZCould not create temporary f"..., 36) = 36
21470 write(2, "bcron-spool[21470]: Fatal: logs:"..., 84) = 84
21470 unlink("tmp/spool.21470.1573692319.854640") = -1 ENOENT (No such file or directory)
21470 exit_group(111)                   = ?
21470 +++ exited with 111 +++

(Yen sampeyan ilang, sampeyan bisa uga pengin maca kiriman sadurunge babagan * manajemen proses nix lan cangkang.) Dadi, server PID 20629 ora nampa ijin kanggo nggawe file ing path /var/spool/cron/tmp/spool.21470.1573692319.854640. Paling kamungkinan, alesan iki yaiku setelan ijin sistem file klasik. Ayo priksa:

# ls -ld /var/spool/cron/tmp/
drwxr-xr-x 2 root root 4096 Nov  6 05:33 /var/spool/cron/tmp/
# ps u -p 20629
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
cron     20629  0.0  0.0   2276   752 ?        Ss   Nov14   0:00 unixserver -U /var/run/bcron-spool -- bcron-spool

Ing kono asu dikubur! Server lumaku minangka cron pangguna, nanging mung ROOT duwe ijin kanggo nulis menyang direktori /var/spool/cron/tmp/. Prentah prasaja chown cron /var/spool/cron/tmp/ bakal meksa bcron bisa kanthi bener. (Yen ora dadi masalah, mula tersangka sing paling mungkin yaiku modul keamanan kernel kaya SELinux utawa AppArmor, mula aku bakal mriksa log pesen kernel nganggo dmesg.)

Total

Tilak telpon sistem bisa dadi akeh banget kanggo pamula, nanging Mugi aku wis ditampilake sing cara cepet debug kabeh kelas masalah penyebaran prajurit umum. Mbayangno nyoba debug multiprocess bcronnggunakake debugger step-by-step.

Parsing tilak asil sakdurunge bebarengan chain telpon sistem mbutuhake skill, nanging aku ngandika, meh tansah, nggunakake strace, Aku mung njaluk asil tilak lan katon kanggo kasalahan miwiti saka mburi. Oalah, strace mbantu kula nyimpen akèh wektu ing debugging. Muga-muga bisa migunani kanggo sampeyan uga.

Source: www.habr.com

Add a comment