Dadfygio defnydd meddalwedd gyda strace

Dadfygio defnydd meddalwedd gyda strace

Fy swydd bob dydd yn bennaf yw defnyddio meddalwedd, sy'n golygu fy mod yn treulio llawer o amser yn ceisio ateb cwestiynau fel:

  • Mae'r meddalwedd hwn yn gweithio i'r datblygwr, ond nid i mi. Pam?
  • Ddoe fe weithiodd y feddalwedd hon i mi, ond heddiw nid yw'n gweithio. Pam?

Mae hwn yn fath o ddadfygio sydd ychydig yn wahanol i ddadfygio meddalwedd rheolaidd. Mae dadfygio rheolaidd yn ymwneud â rhesymeg y cod, ond mae dadfygio defnydd yn ymwneud â'r rhyngweithio rhwng y cod a'r amgylchedd. Hyd yn oed os mai gwall rhesymegol yw gwraidd y broblem, mae'r ffaith bod popeth yn gweithio ar un peiriant ac nid ar un arall yn golygu bod y broblem rywsut yn yr amgylchedd.

Felly yn lle'r offer debugging arferol fel gdb Mae gen i set wahanol o offer ar gyfer defnyddio dadfygio. A fy hoff offeryn ar gyfer delio â'r broblem fel "Pam nad yw'r feddalwedd hon yn gweithio i mi?" a elwir rhediad.

Beth yw strace?

rhediad yn arf ar gyfer “system call tracing”. Fe'i crëwyd yn wreiddiol ar gyfer Linux, ond gellir gwneud yr un triciau dadfygio gydag offer ar gyfer systemau eraill (DTrace neu ktras).

Mae'r cais sylfaenol yn syml iawn. Does ond angen i chi redeg yn syth gydag unrhyw orchymyn a bydd yn gadael pob galwad system (er yn gyntaf mae'n debyg y bydd yn rhaid i chi ei osod eich hun rhediad):

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

Beth yw'r galwadau system hyn? Mae hyn yn rhywbeth fel API ar gyfer cnewyllyn y system weithredu. Un tro, roedd gan feddalwedd fynediad uniongyrchol i'r caledwedd yr oedd yn rhedeg arno. Er enghraifft, os oedd angen iddo arddangos rhywbeth ar y sgrin, chwaraeodd gyda phorthladdoedd neu gofrestrau cof-mapio ar gyfer dyfeisiau fideo. Pan ddaeth systemau cyfrifiadurol amldasgio yn boblogaidd, teyrnasodd anhrefn wrth i wahanol gymwysiadau frwydro dros y caledwedd. Gallai gwallau mewn un rhaglen ddod â rhai eraill i lawr, os nad y system gyfan. Yna ymddangosodd moddau braint (neu “amddiffyniad cylch”) yn y CPU. Daeth y cnewyllyn yn fwyaf breintiedig: cafodd fynediad llawn i'r caledwedd, gan silio cymwysiadau llai breintiedig a oedd eisoes yn gorfod gofyn am fynediad o'r cnewyllyn i ryngweithio â'r caledwedd trwy alwadau system.

Ar y lefel ddeuaidd, mae galwad system ychydig yn wahanol i alwad swyddogaeth syml, ond mae'r rhan fwyaf o raglenni'n defnyddio deunydd lapio yn y llyfrgell safonol. Y rhai. mae llyfrgell safonol POSIX C yn cynnwys galwad ffwythiant ysgrifennu(), sy'n cynnwys yr holl god pensaernïaeth-benodol ar gyfer yr alwad system ysgrifennu.

Dadfygio defnydd meddalwedd gyda strace

Yn fyr, mae unrhyw ryngweithio rhwng cymhwysiad a'i amgylchedd (systemau cyfrifiadurol) yn cael ei wneud trwy alwadau system. Felly, pan fydd meddalwedd yn gweithio ar un peiriant ond nid ar un arall, byddai'n dda edrych ar ganlyniadau olrhain galwadau'r system. Yn fwy penodol, dyma restr o bwyntiau nodweddiadol y gellir eu dadansoddi gan ddefnyddio olrhain galwad system:

  • Consol I/O
  • Rhwydwaith I/O
  • Mynediad i'r system ffeiliau a ffeil I/O
  • Rheoli oes edefyn proses
  • Rheoli cof lefel isel
  • Mynediad at yrwyr dyfeisiau penodol

Pryd i ddefnyddio strace?

Mewn theori, rhediad a ddefnyddir gydag unrhyw raglen yn y gofod defnyddiwr, oherwydd mae'n rhaid i unrhyw raglen yn y gofod defnyddiwr wneud galwadau system. Mae'n gweithio'n fwy effeithlon gyda rhaglenni cryno, lefel isel, ond mae hefyd yn gweithio gydag ieithoedd lefel uchel fel Python os gallwch chi dorri trwy'r sŵn ychwanegol o'r amser rhedeg a'r cyfieithydd.

Yn ei holl ogoniant rhediad yn amlygu ei hun wrth ddadfygio meddalwedd sy'n gweithio'n dda ar un peiriant, ond yn sydyn yn stopio gweithio ar beiriant arall, gan gynhyrchu negeseuon annelwig am ffeiliau, caniatâd, neu ymdrechion aflwyddiannus i weithredu rhai gorchmynion neu rywbeth arall... Mae'n drueni, ond nid yw'n cyfuno cystal â phroblemau lefel uchel fel gwallau dilysu tystysgrifau. Fel arfer mae hyn yn gofyn am gyfuniad rhediadweithiau ltras ac offer lefel uwch (fel yr offeryn llinell orchymyn OpenSSL i ddadfygio'r dystysgrif).

Byddwn yn defnyddio gweinydd annibynnol fel enghraifft, ond yn aml gellir olrhain galwadau system ar lwyfannau lleoli mwy cymhleth. Does ond angen i chi ddewis yr offer cywir.

Enghraifft debugging syml

Gadewch i ni ddweud eich bod am redeg y rhaglen gweinydd anhygoel foo, a dyma beth sydd gennych yn y pen draw:

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

Mae'n debyg na allai ddod o hyd i'r ffeil ffurfweddu a ysgrifennwyd gennych. Mae hyn yn digwydd oherwydd weithiau pan fydd rheolwyr pecyn yn llunio cais, maent yn diystyru'r lleoliadau ffeil disgwyliedig. Ac os dilynwch y canllaw gosod ar gyfer un dosbarthiad, mewn un arall fe welwch ffeiliau hollol wahanol i'r hyn yr oeddech yn ei ddisgwyl. Gellid datrys y broblem mewn ychydig eiliadau pe bai'r neges gwall yn dweud ble i chwilio am y ffeil ffurfweddu, ond nid yw'n dweud hynny. Felly ble i edrych?

Os oes gennych chi fynediad i'r cod ffynhonnell, gallwch ei ddarllen a darganfod popeth. Cynllun wrth gefn da, ond nid yr ateb cyflymaf. Gallwch droi at ddadfygiwr cam-wrth-gam fel gdb a gweld beth mae'r rhaglen yn ei wneud, ond mae'n llawer mwy effeithiol defnyddio offeryn sydd wedi'i ddylunio'n benodol i ddangos rhyngweithio â'r amgylchedd: rhediad.

Allbwn rhediad gall ymddangos yn ddiangen, ond y newyddion da yw y gellir anwybyddu'r rhan fwyaf ohono'n ddiogel. Mae'n aml yn ddefnyddiol defnyddio'r gweithredwr -o i arbed canlyniadau olrhain i ffeil ar wahân:

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

Tua thudalen gyntaf gyfan yr allbwn rhediad - Mae hwn fel arfer yn baratoad lefel isel ar gyfer lansio. (Llawer o alwadau mmap, mprotect, cwilsyn ar gyfer pethau fel canfod cof lefel isel ac arddangos llyfrgelloedd deinamig.) Mewn gwirionedd, yn ystod dadfygio'r allbwn rhediad Gwell darllen o'r diwedd. Bydd her isod ysgrifennu, sy'n dangos neges gwall. Edrychwn uchod a gweld yr alwad system wallus gyntaf - yr alwad agorat, sy'n taflu gwall ENOENT (“ffeil neu gyfeiriadur heb ei ganfod”) yn ceisio agor /etc/foo/config.json. Dyma lle dylai'r ffeil ffurfweddu fod.

Enghraifft yn unig oedd hyn, ond byddwn yn dweud 90% o'r amser rwy'n ei ddefnyddio rhediad, nid oes dim llawer mwy anodd i'w wneud na hyn. Isod mae canllaw dadfygio cam wrth gam cyflawn:

  • Cynhyrfu oherwydd neges annelwig am wall system-y o raglen
  • Ailgychwynnwch y rhaglen gyda rhediad
  • Dewch o hyd i'r neges gwall yn y canlyniadau olrhain
  • Ewch yn uwch nes i chi daro'r alwad system gyntaf a fethwyd

Mae'n debygol iawn y bydd y system galw i mewn cam 4 yn datgelu beth aeth o'i le.

Awgrymiadau

Cyn dangos enghraifft i chi o ddadfygio mwy cymhleth, byddaf yn dangos ychydig o driciau i chi ar gyfer defnydd effeithiol rhediad:

dyn yw eich ffrind

Ar lawer o systemau *nix, gellir cael rhestr gyflawn o alwadau system i'r cnewyllyn trwy redeg syscalls dyn. Byddwch yn gweld pethau fel brk(2), sy'n golygu y gellir cael mwy o wybodaeth trwy redeg dyn 2 brk.

Rhaca bach: dyn 2 fforch yn dangos y dudalen ar gyfer y plisgyn i mi fforc () в GNU libc, sydd, mae'n troi allan, yn cael ei weithredu trwy alw clôn (). Semanteg galwadau fforc aros yr un fath os ydych yn ysgrifennu rhaglen gan ddefnyddio fforc (), a rhedeg olrhain - ni fyddaf yn dod o hyd i unrhyw alwadau fforc, yn lle hwynt fe fydd clôn (). Dim ond os byddwch chi'n dechrau cymharu'r ffynhonnell â'r allbwn y mae cribiniau o'r fath yn eich drysu rhediad.

Defnyddiwch -o i arbed yr allbwn i ffeil

rhediad yn gallu cynhyrchu allbwn helaeth, felly mae'n aml yn ddefnyddiol storio canlyniadau olrhain mewn ffeiliau ar wahân (fel yn yr enghraifft uchod). Mae hyn hefyd yn helpu i osgoi drysu rhwng allbwn rhaglenni ac allbwn rhediad yn y consol.

Defnyddiwch -s i weld mwy o ddata dadl

Efallai eich bod wedi sylwi nad yw ail hanner y neges gwall yn cael ei ddangos yn yr olrhain enghreifftiol uchod. Mae'n oherwydd rhediad Mae rhagosodiad yn dangos dim ond 32 beit cyntaf y ddadl llinynnol. Os ydych chi eisiau gweld mwy, ychwanegwch rywbeth tebyg -s 128 i'r alwad rhediad.

-y yn ei gwneud hi'n haws olrhain ffeiliau, socedi, ac ati.

Mae "All is file" yn golygu bod systemau *nix yn gwneud yr holl I/O gan ddefnyddio disgrifyddion ffeil, boed hynny'n berthnasol i ffeil neu rwydwaith neu bibellau rhyngbrosesu. Mae hyn yn gyfleus ar gyfer rhaglennu, ond mae'n ei gwneud hi'n anodd cadw golwg ar yr hyn sy'n digwydd mewn gwirionedd pan welwch chi gyffredin darllen и ysgrifennu yn y system canlyniadau olrhain galwadau.

Trwy ychwanegu gweithredwr ie, byddwch yn gorfodi rhediad anodi pob disgrifydd ffeil yn yr allbwn gyda nodyn o'r hyn y mae'n pwyntio ato.

Atodwch broses sydd eisoes yn rhedeg gyda -p**

Fel y gwelwch o'r enghraifft isod, weithiau mae angen ichi olrhain rhaglen sydd eisoes yn rhedeg. Os yw'n hysbys ei fod yn rhedeg fel proses 1337 (dyweder, o'r allbwn ps), yna gallwch chi ei olrhain fel hyn:

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

Efallai y bydd angen hawliau gwraidd arnoch.

Defnyddiwch -f i fonitro prosesau plant

rhediad Yn ddiofyn, dim ond un broses y mae'n ei olrhain. Os yw'r broses hon yn silio prosesau plentyn, yna gellir gweld yr alwad system i silio'r broses plentyn, ond ni fydd galwadau system y broses plentyn yn cael eu harddangos.

Os ydych chi'n meddwl bod y gwall mewn proses plentyn, defnyddiwch y datganiad -f, bydd hyn yn galluogi ei olrhain. Yr anfantais i hyn yw y bydd yr allbwn yn eich drysu hyd yn oed yn fwy. Pryd rhediad yn olrhain un broses neu un edefyn, mae'n dangos un ffrwd o ddigwyddiadau galw. Pan fydd yn olrhain prosesau lluosog ar unwaith, efallai y byddwch yn gweld dechrau galwad yn cael ei dorri gan neges , yna - criw o alwadau am ganghennau gweithredu eraill, a dim ond wedyn - diwedd yr un cyntaf <…foocall ailddechrau>. Neu rhannwch yr holl ganlyniadau olrhain yn ffeiliau gwahanol, gan ddefnyddio'r gweithredwr hefyd -ff (manylion yn arweinyddiaeth ar rhediad).

Hidlo olion gan ddefnyddio -e

Fel y gwelwch, mae canlyniad yr olrhain yn bentwr go iawn o'r holl alwadau system posibl. Baner -e Gallwch hidlo'r olrhain (gweler arweinyddiaeth ar rhediad). Y brif fantais yw ei bod yn gyflymach rhedeg olrhain wedi'i hidlo na gwneud olrhain llawn ac yna grep`yn. A dweud y gwir, does dim ots gen i bron bob amser.

Nid yw pob camgymeriad yn ddrwg

Enghraifft syml a chyffredin yw rhaglen sy'n chwilio am ffeil mewn sawl man ar unwaith, fel cragen yn chwilio am gyfeiriadur sy'n cynnwys ffeil gweithredadwy:

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

Mae heuristics fel “cais diwethaf a fethwyd cyn adrodd am wall” yn dda am ddod o hyd i wallau perthnasol. Boed hynny fel y bo, mae'n rhesymegol dechrau o'r diwedd.

Gall sesiynau tiwtorial rhaglennu C eich helpu i ddeall galwadau system.

Nid yw galwadau safonol i lyfrgelloedd C yn alwadau system, ond dim ond haen wyneb denau. Felly, os ydych chi'n deall o leiaf ychydig sut a beth i'w wneud yn C, bydd yn haws i chi ddeall canlyniadau olrhain galwadau'r system. Er enghraifft, rydych chi'n cael trafferth debugging galwadau i systemau rhwydwaith, edrychwch ar yr un clasurol Canllaw Bija i Raglennu Rhwydwaith.

Enghraifft debugging fwy cymhleth

Dywedais eisoes fod yr enghraifft o ddadfygio syml yn enghraifft o’r hyn y mae’n rhaid i mi ymdrin ag ef yn bennaf wrth weithio ag ef rhediad. Fodd bynnag, weithiau mae angen ymchwiliad go iawn, felly dyma enghraifft go iawn o ddadfygio mwy datblygedig.

bcron - trefnydd prosesu tasgau, gweithrediad arall o'r ellyll *nix cron. Mae wedi'i osod ar y gweinydd, ond pan fydd rhywun yn ceisio golygu'r amserlen, dyma beth sy'n digwydd:

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

Iawn, mae hynny'n golygu bcron ceisio ysgrifennu ffeil benodol, ond ni weithiodd allan, ac ni fydd yn cyfaddef pam. Dadorchuddio rhediad:

# 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 +++

Mae neges gwall yn agos at y diwedd ysgrifennu, ond y tro hwn mae rhywbeth yn wahanol. Yn gyntaf, nid oes gwall galwad system perthnasol, sydd fel arfer yn digwydd cyn hyn. Yn ail, mae'n amlwg bod rhywun eisoes wedi darllen y neges gwall yn rhywle. Mae'n edrych fel bod y broblem wirioneddol yn rhywle arall, a bcrontab yn syml yn chwarae'r neges yn ôl.

Os edrychwch ar dyn 2 darllen, gallwch weld bod y ddadl gyntaf (3) yn ddisgrifydd ffeil, y mae * nix yn ei ddefnyddio ar gyfer yr holl brosesu I/O. Sut mae darganfod beth mae disgrifydd ffeil 3 yn ei gynrychioli? Yn yr achos penodol hwn, gallwch chi redeg rhediad gyda gweithredwr ie (gweler uchod) a bydd yn dweud wrthych yn awtomatig, ond i ddarganfod pethau fel hyn, mae'n ddefnyddiol gwybod sut i ddarllen a dosrannu canlyniadau olrhain.

Gall ffynhonnell disgrifydd ffeil fod yn un o lawer o alwadau system (mae'r cyfan yn dibynnu ar beth yw pwrpas y disgrifydd - consol, soced rhwydwaith, y ffeil ei hun, neu rywbeth arall), ond boed hynny fel y gall, rydym yn edrych amdano galwadau trwy ddychwelyd 3 (h.y. e. rydym yn edrych am “= 3” yn y canlyniadau olrhain). Yn y canlyniad hwn mae 2 ohonynt: agorat ar y brig iawn a soced Yn y canol. agorat yn agor y ffeil ond cauBydd (3) wedyn yn dangos ei fod yn cau eto. (Rake: gellir ailddefnyddio disgrifyddion ffeiliau pan gânt eu hagor a'u cau). Galwch soced () addas oherwydd dyma'r un olaf o'r blaen darllen (), ac y mae yn troi allan fod bcrontab yn gweithio gyda rhywbeth trwy soced. Mae'r llinell nesaf yn dangos bod y disgrifydd ffeil yn gysylltiedig â soced parth unix ar y ffordd /var/run/bcron-spool.

Felly, mae angen inni ddod o hyd i'r broses sy'n gysylltiedig â hi soced unix ar yr ochr arall. Mae yna ychydig o driciau taclus at y diben hwn, ac mae'r ddau ohonynt yn ddefnyddiol ar gyfer dadfygio gosodiadau gweinydd. Y cyntaf yw defnyddio netstat neu'n fwy newydd ss (statws soced). Mae'r ddau orchymyn yn dangos cysylltiadau rhwydwaith gweithredol y system ac yn cymryd y datganiad -l i ddisgrifio socedi gwrando, yn ogystal â'r gweithredwr -p i arddangos rhaglenni sy'n gysylltiedig â'r soced fel cleient. (Mae yna lawer mwy o opsiynau defnyddiol, ond mae'r ddau hyn yn ddigonol ar gyfer y dasg hon.)

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

Mae hyn yn awgrymu mai'r gwrandäwr yw'r gorchymyn inixserver, yn rhedeg gyda phroses ID 20629. (Ac, yn gyd-ddigwyddiadol, mae'n defnyddio disgrifydd ffeil 3 fel y soced.)

Gelwir yr ail offeryn defnyddiol iawn ar gyfer dod o hyd i'r un wybodaeth lsof. Mae'n rhestru'r holl ffeiliau agored (neu ddisgrifyddion ffeil) ar y system. Neu gallwch gael gwybodaeth am un ffeil benodol:

# 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

Mae Proses 20629 yn weinydd hirhoedlog, felly gallwch chi ei gysylltu ag ef rhediad defnyddio rhywbeth fel strace -o /tmp/olrhain -p 20629. Os ydych chi'n golygu swydd cron mewn terfynell arall, byddwch yn derbyn allbwn olrhain gyda gwall. A dyma'r canlyniad:

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

(Diwetha derbyn () Ni fydd yn cael ei gwblhau wrth olrhain.) Unwaith eto, yn anffodus, nid yw'r canlyniad hwn yn cynnwys y gwall yr ydym yn chwilio amdano. Nid ydym yn gweld unrhyw negeseuon y mae bcrontag yn eu hanfon i'r soced nac yn ei dderbyn. Yn lle hynny, cwblhewch reolaeth proses (clonio, aros4, SIGCHLD ac ati) Mae'r broses hon yn silio proses plentyn, sydd, fel y gallech chi ddyfalu, yn gwneud y gwaith go iawn. Ac os oes angen i chi ddal ei llwybr, ychwanegu at yr alwad strap -f. Dyma beth y byddwn yn dod o hyd iddo pan fyddwn yn chwilio am y neges gwall yn y canlyniad newydd gyda strace -f -o /tmp/olrhain -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 +++

Nawr, mae hynny'n rhywbeth. Mae proses 21470 yn derbyn gwall "gwrthodwyd mynediad" wrth geisio creu ffeil wrth y llwybr tmp/spool.21470.1573692319.854640 (yn ymwneud â'r cyfeiriadur gweithio cyfredol). Pe baem ond yn gwybod y cyfeiriadur gweithio presennol, byddem hefyd yn gwybod y llwybr llawn ac yn gallu darganfod pam na all y broses greu ei ffeil dros dro ynddo. Yn anffodus, mae'r broses eisoes wedi dod i ben, felly ni allwch ei ddefnyddio yn unig lsof -p 21470 er mwyn dod o hyd i'r cyfeiriadur cyfredol, ond gallwch weithio i'r cyfeiriad arall - chwiliwch am alwadau system PID 21470 sy'n newid y cyfeiriadur. (Os nad oes rhai, mae’n rhaid bod PID 21470 wedi eu hetifeddu gan ei riant, ac mae hwn eisoes drwyddo lsof -p Ni ellir ei ddarganfod.) Mae'r alwad system hon yn chdir (sy'n hawdd ei ddarganfod gyda chymorth peiriannau chwilio ar-lein modern). A dyma ganlyniad chwiliadau o chwith yn seiliedig ar y canlyniadau olrhain, yr holl ffordd i'r gweinydd 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 +++

(Os ydych chi ar goll, efallai yr hoffech chi ddarllen fy swydd flaenorol am * nix rheoli prosesau a chregyn.) Felly, ni dderbyniodd y gweinydd PID 20629 ganiatâd i greu ffeil wrth y llwybr /var/spool/cron/tmp/spool.21470.1573692319.854640. Yn fwyaf tebygol, y rheswm am hyn yw'r gosodiadau caniatâd system ffeiliau clasurol. Gadewch i ni wirio:

# 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

Dyna lle mae'r ci wedi'i gladdu! Mae'r gweinydd yn rhedeg fel defnyddiwr cron, ond dim ond root sydd â chaniatâd i ysgrifennu i'r cyfeiriadur /var/sbwlio/cron/tmp/. Gorchymyn syml chown cron /var/spool/cron/tmp/ bydd gorfodi bcron gweithio'n gywir. (Os nad dyna oedd y broblem, yna modiwl diogelwch cnewyllyn fel SELinux neu AppArmor yw'r sawl sydd dan amheuaeth nesaf, felly byddwn yn gwirio'r log neges cnewyllyn gyda dmesg.)

Yn gyfan gwbl

Gall olion galwadau system fod yn llethol i ddechreuwr, ond rwy'n gobeithio fy mod wedi dangos eu bod yn ffordd gyflym o ddadfygio dosbarth cyfan o broblemau lleoli cyffredin. Dychmygwch geisio dadfygio amlbroses bcrondefnyddio dadfygiwr cam wrth gam.

Mae dosrannu canlyniadau olrhain yn ôl ar hyd cadwyn alwadau'r system yn gofyn am sgil, ond fel y dywedais, bron bob amser, defnyddio rhediad, Fi jyst yn cael y canlyniad olrhain ac yn edrych am wallau yn dechrau o'r diwedd. Beth bynnag, rhediad yn fy helpu i arbed llawer o amser ar ddadfygio. Rwy'n gobeithio y bydd yn ddefnyddiol i chi hefyd.

Ffynhonnell: hab.com

Ychwanegu sylw