
Minu pĂ”hitöö on peamiselt tarkvarasĂŒsteemide juurutamine, seega kulutan palju aega sellistele kĂŒsimustele vastamisele:
- Arendajal see tarkvara töötab, aga mul ei toimi. Miks?
- Eile töötas see tarkvara mul, aga tÀna ei tööta. Miks?
See on teatud tĂŒĂŒpi silumine, mis erineb tavalisest tarkvarasilumisest. Tavaline silumine keskendub koodi loogikale, samas kui juurutamise silumine kĂ€sitleb koodi ja keskkonna interaktsiooni. Isegi kui probleemi juureks on loogiline viga, tĂ€hendab fakt, et ĂŒhes masinas kĂ”ik töötab, aga teises mitte, et probleem on mingil moel keskkonnas.
SeetĂ”ttu on mul tavapĂ€raste silumisvahendite asemel gdb teine tööriistakomplekt juurutamise silumiseks. Ja minu lemmikvahend kĂŒsimuse "Miks see tarkvara mul ei tööta?" lahendamiseks on strace.
Mis on strace?
â see on sĂŒsteemikutsungite jĂ€lgimise tööriist. Algul loodi see Linuxile, kuid samu silumise nippe saab teha ka teiste sĂŒsteemide tööriistadega ( vĂ”i ).
Peamine kasutus on vĂ€ga lihtne. Tuleb lihtsalt kĂ€ivitada strace koos mĂ”ne kĂ€suga ja see saadab dump'i kĂ”ikidest sĂŒsteemikutsungitest (kuid esmalt tuleb tĂ”enĂ€oliselt ise strace paigaldada) 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 +++Mis on need sĂŒsteemikutsungid? Need on midagi nagu operatsioonisĂŒsteemi tuuma API. Amatöörina oli tarkvaral otsene juurdepÀÀs "riistvarale", millel see töötas. Kui nĂ€iteks oli vaja midagi ekraanile kuvada, siis mĂ€ngiti sadamatega vĂ”i videoseadmete mĂ€lu registeritega. Kui mitmeĂŒlesanne arvutisĂŒsteemid said populaarseks, siis tekkis kaos, kuna erinevad rakendused vĂ”itlesid "riistvara" nimel. Ăhe rakenduse vead vĂ”isid rivistada kĂ”ik teised rakendused vĂ”i isegi kogu sĂŒsteemi. Siis said CPU-s privileegireĆŸiimid (vĂ”i "ringkaitse"). KĂ”ige privileege saanud oli tuum: see sai tĂ€isjuurdepÀÀsu "riistvarale", luues vĂ€hem privileege saanud rakendusi, kes pidid tuumalt juurdepÀÀsu kĂŒsima, et suhelda "riistvaraga" â lĂ€bi sĂŒsteemikutsungite.
Binaarsetasemel erineb sĂŒsteemikĂ”ne veidi lihtsast funktsioonikĂ”nest, kuid enamik programme kasutab standardbiblioteegi ĂŒmbrikku. St. POSIX C standardbiblioteegis on sĂŒsteemikĂ”ne funktsioon. write(), mis sisaldab kogu arhitektuurist sĂ”ltuvat koodi sĂŒsteemikĂ”ne jaoks. kirjutama.

LĂŒhidalt öeldes toimub rakenduse igasugune suhtlemine oma keskkonnaga (arvutisĂŒsteemidega) sĂŒsteemikĂ”nede kaudu. Seega, kui tarkvara töötab ĂŒhel masinal ja mitte teisel, oleks hea vaadata sĂŒsteemikĂ”nede jĂ€lgimise tulemusi. Kui tĂ€psemalt, siis siin on teile loetelu tĂŒĂŒpilistest punktidest, mida saab analĂŒĂŒsida sĂŒsteemikĂ”ne jĂ€lgimise abil:
- Konsoli sisend-vÀljund
- VÔrgu sisend-vÀljund
- FailisĂŒsteemi juurdepÀÀs ja failide sisend-vĂ€ljund
- Protsessi-eluea haldamine
- Madala taseme mÀlu haldamine
- Juhtimisseadmete juurdepÀÀs
Millal kasutada strace'i?
Teoorias strace kasutatakse kĂ”igi kasutajaruumis olevate programmide puhul, kuna iga kasutajaruumis olev programm peab tegema sĂŒsteemikĂ”nesid. See töötab efektiivsemalt kompileeritud madala taseme programmidega, kuid töötab ka kĂ”rgema taseme keeltes nagu Python, kui Ă”nnestub lĂ€bi murda tĂ€iendava mĂŒra kaudu exĂ©cutori ja tĂ”lkija.
Kogu oma hiilguses strace nĂ€itab see ennast tarkvara silumiseks, mis töötab ĂŒhe masinaga hĂ€sti, kuid teisel lĂ”petab töö ootamatult, andes ebamugavaid teadet faile, Ă”igusi vĂ”i ebaĂ”nnestunud katsete kohta teatud kĂ€skude tĂ€itmiseks jms... Kahju, aga see ei sobi nii hĂ€sti kĂ”rgema taseme probleemidega, nagu sertifikaadi kontrollimise vead. Tavaliselt vajab see kombinatsiooni strace, mĂ”nikord ja kĂ”rgema taseme tööriistu (nagu kĂ€surea tööriist openssl sertifikaadi silumiseks).
NĂ€iteks vĂ”tame töö isoleeritud serveris, kuid sĂŒsteemikĂ”nede jĂ€lgimist saab sageli teha ka keerukamatel juurutamisplatvormidel. Lihtsalt peab valima sobiva tööriistad.
Lihtsa silumise nÀidis
Oletame, et soovite kÀivitada fantastilise serverirakenduse foo, aga juhtub selline asi:
$ foo
Konfiguratsioonifaili avamine ebaĂ”nnestus: Sellist faili vĂ”i kausta ei leitudIlmselt ei Ă”nnestunud tal leida teie kirjutatud konfigureerimisfaili. See juhtub, sest mĂ”nikord, kui pakihaldurid rakendust kompileerivad, ĂŒletavad nad oodatud failide asukoha. Ja kui jĂ€rgida paigaldusjuhendit ĂŒhele distributsioonile, leiad teises failid tĂ€iesti oodatust erinevates kohtades. Probleemi saaks lahendada paari sekundiga, kui veateade ĂŒtleks, kust konfigureerimisfaili otsida, aga see ei ĂŒtle. Kust siis otsida?
Kui lÀhtekoodile on juurdepÀÀs, saab seda lugeda ja kÔik vÀlja selgitada. Hea varuplaan, aga mitte kÔige kiirem lahendus. VÔib kasutada samm-sammult tÔrkeotsijat nagu gdb ja vaadata, mida programm teeb, aga palju tÔhusam on kasutada tööriista, mis on spetsiaalselt loodud keskkonna interaktsiooni nÀitamiseks: strace.
KokkuvĂ”te strace vĂ”ib tunduda ĂŒlearune, kuid hea uudis on see, et suure osa sellest vĂ”ib julgelt tĂ€helepanuta jĂ€tta. Tihti on kasulik kasutada operaatorit -o, et salvestada jĂ€lgimistulemused eraldi faili:
$ strace -o /tmp/trace foo
Viga konfiguratsioonifaili avamisel: Ei ole sellist faili vÔi kausta
$ cat /tmp/trace
execve("foo", ["foo"], 0x7ffce98dc010 /* 16 vars */) = 0
brk(NULL) = 0x56363b3fb000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (Ei ole sellist faili vÔi kausta)
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 (Ei ole sellist faili vÔi kausta)
dup(2) = 3
fcntl(3, F_GETFL) = 0x2 (lipud O_RDWR)
brk(NULL) = 0x56363b3fb000
brk(0x56363b41c000) = 0x56363b41c000
fstat(3, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x8), ...}) = 0
write(3, "Viga konfiguratsioonifaili avamisel"..., 60) = 60
close(3) = 0
exit_group(1) = ?
+++ lĂ”petanud 1 +++Umbes kogu esimese lehe vĂ€ljund. strace â see on tavaliselt madala taseme ettevalmistus kĂ€ivitamiseks. (Palju kĂ”nesid mmap, mprotect, brk asjade jaoks, nĂ€iteks madala taseme mĂ€lu avastamine ja dĂŒnaamiliste raamatukogude peegeldamine.) Ăldiselt, silumise ajal on vĂ€ljundid strace parem lugeda kĂ”ige lĂ”pust. Allosas on kĂ”ne kirjutama, mis vĂ€ljendab veateadet. Vaatame ĂŒles ja nĂ€eme esimest ebaĂ”nnestunud sĂŒsteemi kĂ”net â kĂ”ne openat, mis annab vea ENOENT (âfail vĂ”i kaust ei leitudâ), proovides avada /etc/foo/config.json. Siin peaks olema konfiguratsioonifail.
See oli lihtsalt nĂ€ide, kuid ma ĂŒtleksin, et 90% ajast, kui ma kasutan strace, ei ole keerulisemalt midagi muud teha. Allpool on tĂ€ielik samm-sammuline juhend silumiseks:
- Ărge muretsege mitte selge veateate pĂ€rast programmi
- KĂ€ivitage programm uuesti koos strace
- Leidke jÀlgimise tulemustes veateade
- Liigake ĂŒles, kuni jĂ”uate esimese ebaĂ”nnestunud sĂŒsteemi kĂ”nni
On vĂ€ga tĂ”enĂ€oline, et 4. sammu sĂŒsteemi kĂ”ne nĂ€itab, kus asi valesti lĂ€ks.
NÀpunÀited
Enne kui nÀitan keerulisema tÔrkeotsingu nÀidet, jagan teiega mÔningaid nÀpunÀiteid tÔhusaks kasutamiseks. strace:
man â teie sĂ”ber
Paljudel *nix sĂŒsteemidel saab tĂ€isnimekirja sĂŒsteemi kĂ”nede kohta ydra, kĂ€ivitades man syscalls. NĂ€ete selliseid asju nagu brk(2), mis tĂ€hendab, et rohkem teavet saab teada, kĂ€ivitades man 2 brk.
MĂ”ned vĂ€ikesed kĂ€igud: man 2 fork nĂ€itab mulle lehte shelli kohta fork() ja GNU libc, mis, nagu selgub, on rakendatud kĂ”ne abil clone(). KĂ”ne semantika fork jÀÀb samaks, kui kirjutada programm, mis kasutab fork(), ja kĂ€ivitada jĂ€lgimine â ma ei leia kĂ”nesid fork, nende asemel on clone(). Sellised kĂ€igud ajavad segadusse, kui hakata vĂ”rreldama lĂ€htekoodi vĂ€ljundiga. strace.
Kasutage -o, et salvestada vÀljund faili
strace vĂ”ib genereerida ulatusliku vĂ€ljundi, seega on tihti kasulik salvestada jĂ€lgimise tulemused eraldi failidesse (nagu ĂŒlaltoodud nĂ€ites). See aitab ka mitte segada programmi vĂ€ljundit konsooli vĂ€ljundiga. strace Kasutage -s, et vaadata rohkem argumendi andmeid
Olete kindlasti mĂ€rganud, et veateate teises pooles ei ole ĂŒlaltoodud jĂ€lgimise nĂ€ites nĂ€idatud. See on seetĂ”ttu, et
vaikimisi nÀitab vaid esimesed 32 baiti argumentide stringist. Kui soovite nÀha rohkem, lisage midagi nagu strace -s 128 kÔne juurde -u hÔlbustab failide ja socketite jÀlgimist jne. strace.
"KĂ”ik on fail" tĂ€hendab, et *nix sĂŒsteemid teevad kĂ”ik sisendi ja vĂ€ljundi koos failide descriptoritega, olgu need siis failide, vĂ”rguga vĂ”i protsessidevahelised kanalid. See on mugav programmeerimisel, kuid takistab nĂ€gemast, mis tegelikult toimub, kui nĂ€ete ĂŒhtekuuluvust
sĂŒsteemi kĂ”nede jĂ€lgimise tulemustes. lugema ja kirjutama Lisades operaatori
-u , sunniteannotatsioonid olema iga faili deskriptoriga vÀljundis mÀrkustega, millele see viitab. strace Kinnitage juba kÀimasolevale protsessile -p**
Nagu allolev nĂ€ide nĂ€itab, on mĂ”nikord vajalik jĂ€lgida programmi, mis on juba kĂ€imas. Kui teatakse, et see on kĂ€ivitatud protsessina 1337 (ĂŒtleme, ĂŒlesannete pĂ”hjal)
siis on vĂ”imalik selle jĂ€lgimine nii: ps$ strace -p 1337 ...sĂŒsteemikĂ”nede jĂ€lgimise vĂ€ljund...
VÔib-olla on teil vaja superkasutaja Ôigusi.Kasutage -f, et jÀlgida alamprotsesse.
.
strace vaikimisi jĂ€lgib ainult ĂŒhte protsessi. Kui see protsess genereerib alaprotsesse, on vĂ”imalik nĂ€ha sĂŒsteemset kĂ”net alaprotsessi loomisel, kuid alaprotsesside sĂŒsteemseid kĂ”nesid ei kuvata.
Kui arvate, et viga on alaprotsessis, kasutage operaatorit -f, see aktiveerib selle jĂ€lgimise. Miinus on see, et vĂ€ljund segab teid veel rohkem. Kui strace jĂ€lgib ĂŒhte protsessi vĂ”i ĂŒhte haru, nĂ€itab see ĂŒhtset sĂŒndmuste voogu kĂ”nedest. Kui see jĂ€lgib korraga mitut protsessi, vĂ”ite nĂ€ha kĂ”ne algust, mis katkestatakse sĂ”numiga <unfinished âŠ>, seejĂ€rel rida kĂ”nesid teiste tĂ€itmisharude jaoks ja alles siis esimese lĂ”petamine <⊠foocall resumed>. VĂ”i jagage kĂ”ik jĂ€lgimise tulemused erinevatesse failidesse, kasutades ka operaatorit -ff (ĂŒksikasjad â 6TB strace).
Filtreerige jÀlgimist -e abil
Nagu nĂ€ete, on jĂ€lgimise tulemus tĂ”eline hunnik kĂ”igist vĂ”imalikest sĂŒsteemsetest kĂ”nedest. Lippu -e saab jĂ€lgimist filtreerida (vt. 6TB strace). Peamine eelis on see, et jĂ€lgimist kĂ€ivitatakse filtreerimisega kiiremini kui tĂ€islise jĂ€lgimine ja seejĂ€rel grep`-ida. Kui aus olla, siis mulle peaaegu alati ei meeldi.
KÔik vead pole halvad
Lihtne ja levinud nÀide on programm, mis otsib faili kohe mitmes kohas, nÀiteks shell, mis otsib, kus korv- kataloog sisaldab tÀidetavat faili:
$ strace sh -c uname
...
stat("/home/user/bin/uname", 0x7ffceb817820) = -1 ENOENT (Sellist faili vÔi katalooge ei ole)
stat("/usr/local/bin/uname", 0x7ffceb817820) = -1 ENOENT (Sellist faili vÔi katalooge ei ole)
stat("/usr/bin/uname", {st_mode=S_IFREG|0755, st_size=39584, ...}) = 0
...HĂ€id ja halbu nĂ€iteid nagu âviimane ebaĂ”nnestunud pĂ€ring veateate eelâ on koos asjakohaste vigade leidmiseks. Ăldiselt on mĂ”istlik alustada kĂ”ige lĂ”pust.
SĂŒsteemsete kĂ”nede mĂ”istmiseks aitavad hĂ€sti C programmi juhendid
C-teekide standardkĂ”ned ei ole sĂŒsteemsed kĂ”ned, vaid ainult peen kiht. Seega, kui mĂ”istate midagi, kuidas ja mida C-s teha, on teil lihtsam jĂ€lgimise tulemusi mĂ”ista. NĂ€iteks, kui teil on probleeme vĂ”rgusĂŒsteemide kĂ”nede silumisel, vaadake klassikalist .
TÔhusam silumise nÀide
Olen juba maininud, et lihtne tÔrkeotsing on nÀide sellest, millega ma suuremal osal oma tööst tegelema pean. straceKuid mÔnikord on vajalik tÔeline uurimine, nii et siin on teile reaalsem ja keerulisem tÔrkeotsingu nÀide.
on ĂŒlesannete tĂ€itmise ajastaja, veel ĂŒks *nix deemonite teostus. cronSee on serveris paigaldatud, kuid kui keegi ĂŒritab taskuplaane redigeerida, juhtub jĂ€rgmist:
# crontab -e -u logs
bcrontab: Fatal: Could not create temporary fileOlgu, see tĂ€hendab, et bcron ta ĂŒritas kirjutada mingit faili, kuid tal ei Ă”nnestunud, ja ta ei tunnista, miks. Teeme lahti 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 +++Umbes lĂ”pus on tĂ”rketeade, kirjutamakuid seekord on midagi muud. Esiteks ei ole asjakohast sĂŒsteemikĂ”ne viga, mis tavaliselt enne seda esineb. Teiseks, on nĂ€ha, et keegi on juba tĂ”rketeate lugenud. Tundub, et tĂ”eline probleem on kuskil mujal ja bcrontab lihtsalt kordab teate.
Kui vaadata man 2 read, siis saab nĂ€ha, et esimene argument (3) on failihaldur, mida *nix kasutab kĂ”igi sisendi ja vĂ€ljundi töötlemiseks. Kuidas teada saada, mis failihaldur 3 on? Antud konkreetses olukorras saab kĂ€ivitada strace koos operaatoriga , sunnite (vt ĂŒlal), ja see rÀÀgib automaatselt, kuid selliste asjade arvutamiseks on kasulik teada, kuidas lugeda ja analĂŒĂŒsida jĂ€lgimistulemusi.
Failihalduri allikaks vĂ”ib olla ĂŒks paljudest sĂŒsteemikĂ”nedest (olenevalt sellest, milleks see haldur on â kas konsooli, vĂ”rgu soketi, failina vĂ”i millegi muuna jaoks), kuid igal juhul otsime me kĂ”nesid, tagastades 3 (st otsime "= 3" jĂ€lgimistulemustes). Selles tulemustes on neid 2: openat ĂŒleval ja socket keskel. openat Ava fail, kuid sulgeda(3) pĂ€rast seda nĂ€itab, et see suletakse taas. (Karma: failihaldureid saab taaskasutada, kui neid avatakse ja suletakse). KĂ”ne socket() sobib, kuna see on viimane enne read(), ning selgub, et bcrontab töötab millegagi soketi kaudu. JĂ€rgmine rida nĂ€itab, et failihaldur on seotud unix domain socketiga tee kaudu /var/run/bcron-spool.
Seega tuleb leida protsess, mis on seotud unix socketiga teiselt poolt. Selleks on olemas paar peent trikki, ja mĂ”lemad osutuvad kasulikeks serveri paigutuste tĂ”rkeotsingul. Esimene â kasutada netstat vĂ”i uuemat ss (socket status). MĂ”lemad kĂ€sud nĂ€itavad sĂŒsteemi aktiivseid vĂ”rguĂŒhendusi ja vĂ”tavad operaatori Ă”pivad kuulavate socketite kirjeldamiseks, samuti operaatori -p kliendina socketiga ĂŒhendatud programmide kuvamiseks. (Kasuval vĂ”imalusi on palju rohkem, kuid selle ĂŒlesande jaoks on piisavad ka need kaks.)
# ss -pl | grep /var/run/bcron-spool
u_str LISTEN 0 128 /var/run/bcron-spool 1466637 * 0 users:(("unixserver",pid=20629,fd=3))See tÀhendab, et kuulav on kÀsk inixserver, mis tegeleb protsessi ID-ga 20629. (Ja juhuslikult kasutab ta socketina failikirjeldajat 3.)
Teine tĂ”eliselt kasulik tööriist sama teabe leidmiseks on lsof. See loetleb kĂ”ik avatud failid (vĂ”i failikirjeldajad) sĂŒsteemis. Samuti on vĂ”imalik saada teavet ĂŒhe konkreetse faili kohta:
# 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=STREAMProtsess 20629 on pikaajaline server, nii et sellele saab liita strace midagi sellist nagu strace -o /tmp/trace -p 20629. Kui redigeerida cron ĂŒlesannet teises terminalis â saame jĂ€lgimistulemused koos ilmneva veaga. Ja siin on tulemus:
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 (TaaskÀivitamiseks, kui SA_RESTART on seadistatud)
--- 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 (Lasteprotsesse pole)
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 (TaaskÀivitamiseks, kui SA_RESTART on seadistatud)
--- 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 (Lasteprotsesse pole)
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(Viimane accept() ei lĂ”petata jĂ€lgimisel.) Ja kahjuks, see tulemus ei sisalda viga, mida me otsime. Me ei nĂ€e ĂŒhtegi teadet, mida bcrontag oleks socketile saatnud vĂ”i sellelt vastu vĂ”tnud. Nende asemel on pidev protsessi juhtimine (clone, wait4, SIGCHLD ja see on tĂ”si.) See protsess tekitab alamprotsessi, mis, nagu vĂ”ib arvata, teostab tegelikku tööd. Ja kui on vaja selle jĂ€lge leida, lisage vĂ€ljakutsele strace -f. Siit me leiame, kui otsime veateate uutest tulemustest strace'i kaudu -f -o /tmp/trace -p 20629:
21470 openat(AT_FDCWD, "tmp/spool.21470.1573692319.854640", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 EACCES (LigipÀÀs keelatud)
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 (Sellist faili vÔi katalooge ei ole)
21470 exit_group(111) = ?
21470 +++ lahkunud 111 +++NĂ€ete, see on juba midagi. Protsess 21470 saab tĂ”rke "ligipÀÀs keelatud" proovides luua faili aadressil tmp/spool.21470.1573692319.854640 (seoses praeguse töökaustaga). Kui me lihtsalt teaksime praegust töökausta, teaksime ka tĂ€ielikku teed ja saaksime vĂ€lja selgitada, miks protsess ei saa seal oma ajutist faili luua. Kahjuks on protsess juba lĂ”petatud, seega ei saa me lihtsalt kasutada lsof -p 21470 praeguse kausta leidmiseks, kuid saame töötada tagasi â otsida sĂŒsteemi kutsungite PID 21470, mis muudavad kausta. (Kui neid pole, peab PID 21470 olema need vanemalt pĂ€rinud ja see on juba lĂ€bi lsof -p ei ole vĂ”imalik selgitada.) See sĂŒsteemikutsung on chdir (mida on lihtne teada saada, kasutades kaasaegseid otsingumootoreid). Ja siin on tulemused tagasipöördetest vastavalt jĂ€lgimise tulemustele, kuni serveri PID 20629-ni:
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 (LigipÀÀs keelatud)
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 (Sellist faili vÔi katalooge ei ole)
21470 exit_group(111) = ?
21470 +++ lahkunud 111 +++(Kui te kaotate suuna, siis vĂ”ib-olla peaksite lugema minu eelmist postitust .) Nii et server PID 20629 ei saanud luba faili luua aadressil /var/spool/cron/tmp/spool.21470.1573692319.854640. TĂ”enĂ€oliselt on selle pĂ”hjuseks klassikalised failisĂŒsteemi Ă”iguste seadistused. Kontrollime:
# 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-spoolSiin on probleem! Server töötab kasutaja cron'i alt, kuid ainult root'il on Ôigus kirjutada katalooge /var/spool/cron/tmp/. Lihtne kÀsk chown cron /var/spool/cron/tmp/ aitab bcron töötama Ôigesti. (Kui probleem ei olnud selles, siis jÀrgmine kÔige tÔenÀolisem kahtlusalune on tuumaseadmestiku turvamoodul, nÀiteks SELinux vÔi AppArmor, seega peaksin kontrollima kerneliteate logi kasutades dmesg.)
KokkuvÔttes
Algajale vĂ”ib sĂŒsteemikutsungite jĂ€lgimise tulemustes Ă€ra uppuda, kuid loodan, et olen nĂ€idanud, et need on kiire viis, et tĂ”rkeotsinguks laia valikut levinud juurutusprobleeme. Kujutage ette, et ĂŒritate tĂ”rkeotsingut multitegijate vahel bcron, kasutades samm-sammult tĂ”rkeotsijat.
JĂ€lgimiste tulemuste tagasipööramine sĂŒsteemikutsungite ahelas nĂ”uab oskust, kuid nagu juba ĂŒtlesin, peaaegu alati, kasutades strace, lihtsalt saan jĂ€lgimistulemuse ja otsin vigu, alustades lĂ”pust. Igatahes, strace aitab mul tĂ”rkeotsingul tohutult aega sÀÀsta. Loodan, et see on kasulik ka teile.
Allikas: habr.com
