Debugging Software Deployment mat Strace

Debugging Software Deployment mat Strace

Meng Dag Aarbecht ass meeschtens Software Deployment, dat heescht datt ech vill Zäit verbréngen fir Froen ze beäntweren wéi:

  • Dës Software funktionnéiert fir den Entwéckler, awer net fir mech. Firwat?
  • Gëschter huet dës Software fir mech geschafft, awer haut ass et net. Firwat?

Dëst ass eng Aart Debugging déi liicht anescht ass wéi normal Software Debugging. Regelméisseg Debugging ass iwwer d'Logik vum Code, awer Deployment Debugging ass iwwer d'Interaktioun tëscht dem Code an der Ëmwelt. Och wann d'Wurzel vum Problem e logesche Feeler ass, ass de Fakt datt alles op enger Maschinn funktionnéiert an net op enger anerer heescht datt de Problem iergendwéi an der Ëmwelt ass.

Also amplaz vun den üblechen Debugging Tools wéi gdb Ech hunn eng aner Set vun Tools fir Debugging Deployment. A mäi Liiblingsinstrument fir mam Problem ze këmmeren wéi "Firwat funktionnéiert dës Software net fir mech?" genannt Strecken.

Wat ass strace?

Strecken ass en Tool fir "System Call Tracing". Et gouf ursprénglech fir Linux erstallt, awer déiselwecht Debugging Tricks kënne mat Tools fir aner Systemer gemaach ginn (DTrace oder ktrace).

D'Basisapplikatioun ass ganz einfach. Dir musst just Strace mat all Kommando lafen an et dumpt all System Uriff (och wann Dir als éischt et wahrscheinlech selwer installéiere musst Strecken):

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

Wat sinn dës System Appellen? Dëst ass eppes wéi eng API fir de Kernel vum Betribssystem. Eemol hat d'Software direkten Zougang zu der Hardware op där se leeft. Wann et zum Beispill eppes um Bildschierm ugewisen huet, huet et mat Ports oder Memory-mapéiert Registere fir Videoapparater gespillt. Wéi Multitasking Computersystemer populär ginn ass, huet de Chaos regéiert wéi verschidden Uwendungen iwwer d'Hardware gekämpft hunn. Feeler an enger Applikatioun kéinten anerer erofbréngen, wann net de ganze System. Duerno erschéngen Privileg Modi (oder "Ringschutz") an der CPU. De Kernel gouf am meeschte privilegiéierten: et krut voll Zougang zu der Hardware, spawning manner privilegiéiert Uwendungen, déi schonn Zougang vum Kernel missen ufroen fir mat der Hardware duerch Systemruffen ze interagéieren.

Um binäre Niveau ass e Systemruff liicht anescht wéi en einfachen Funktiounsruff, awer déi meescht Programmer benotzen e Wrapper an der Standardbibliothéik. Déi. der POSIX C Standard Bibliothéik enthält eng Funktioun Opruff schreiwen (), deen all den Architekturspezifesche Code fir de Systemruff enthält schreiwen.

Debugging Software Deployment mat Strace

Kuerz gesot, all Interaktioun tëscht enger Applikatioun a senger Ëmwelt (Computersystemer) gëtt duerch Systemappellen duerchgefouert. Dofir, wann d'Software op enger Maschinn funktionnéiert awer net op enger anerer, wier et gutt fir d'Resultater vun de Systemruffen ze kucken. Méi spezifesch, hei ass eng Lëscht vun typesche Punkten déi analyséiert kënne ginn mat engem System Call Trace:

  • Konsol I/O
  • Netz I/O
  • Dateisystem Zougang an Datei I / O
  • Gestioun vun der Liewensdauer vun engem Prozess thread
  • Niddereg-Niveau Erënnerung Gestioun
  • Zougang zu spezifeschen Apparat Chauffeuren

Wéini benotzt Strace?

An der Theorie, Strecken benotzt mat all Programm am Benotzerraum, well all Programm am Benotzerraum muss Systemruffe maachen. Et funktionnéiert méi effizient mat kompiléierten Low-Level Programmer, awer et funktionnéiert och mat High-Level Sprooche wéi Python wann Dir den zousätzleche Geräischer vun der Runtime an Dolmetscher duerchschneiden kann.

An all senger Pruecht Strecken manifestéiert sech beim Debugging vu Software déi gutt op enger Maschinn funktionnéiert, awer op eemol ophält op enger anerer ze schaffen, vague Messagen iwwer Dateien, Permissiounen oder net erfollegräich Versich fir e puer Kommandoen auszeféieren oder soss eppes ze produzéieren ... Et ass schued, awer et geet net kombinéiere sou gutt mat héije Probleemer wéi Zertifikatverifikatiounsfehler. Normalerweis erfuerdert dëst eng Kombinatioun Streckenheiansdo ltraz a méi héijen Niveau Tools (wéi de Kommandozeil Tool openssl fir den Zertifika ze debuggen).

Mir benotzen e Standalone Server als Beispill, awer System Call Tracing kann dacks op méi komplexen Deploymentplattformen gemaach ginn. Dir musst just déi richteg Tools wielen.

Einfach Debugging Beispill

Loosst eis soen datt Dir déi erstaunlech Serverapplikatioun foo wëllt lafen, an dëst ass wat Dir um Enn kënnt:

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

Anscheinend konnt et d'Konfiguratiounsdatei net fannen, déi Dir geschriwwen hutt. Dëst geschitt well heiansdo wann Packagemanager eng Applikatioun kompiléieren, iwwerschreiden se déi erwaart Dateiplazen. A wann Dir den Installatiounsguide fir eng Verdeelung befollegt, an enger anerer fannt Dir Dateien komplett anescht wéi wou Dir erwaart hutt. De Problem kéint an e puer Sekonnen geléist ginn, wann d'Fehlermeldung sot, wou d'Konfiguratiounsdatei ze sichen, awer et ass net. Also wou ze kucken?

Wann Dir Zougang zum Quellcode hutt, kënnt Dir et liesen an alles erausfannen. E gudde Backupplang, awer net déi séierst Léisung. Dir kënnt op e step-by-step Debugger wéi gdb a kuckt wat de Programm mécht, awer et ass vill méi effektiv en Tool ze benotzen dat speziell entwéckelt ass fir Interaktioun mat der Ëmwelt ze weisen: Strecken.

Konklusioun Strecken kann iwwerflësseg schéngen, mä déi gutt Noriicht ass, datt déi meescht vun et sécher ignoréiert ginn. Et ass dacks nëtzlech den -o Bedreiwer ze benotzen fir Spuerresultater op eng separat Datei ze späicheren:

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

Ongeféier déi ganz éischt Säit vum Output Strecken - Dëst ass normalerweis niddereg-Niveau Virbereedung fir de Start. (Vill Uruff mmap, mprotectéieren, quill fir Saachen wéi Low-Level Memory z'entdecken an dynamesch Bibliothéiken ze weisen.) Eigentlech, wärend der Debugging vum Output Strecken Et ass besser vun Ufank un ze liesen. Et gëtt eng Erausfuerderung ënnert schreiwen, déi eng Fehlermeldung weist. Mir kucken uewen a gesinn den éischte falsche Systemruff - den Uruff opmaachen, deen e Feeler werft ENOENT ("Datei oder Verzeichnis net fonnt") probéiert opzemaachen /etc/foo/config.json. Dëst ass wou d'Konfiguratiounsdatei soll sinn.

Dëst war just e Beispill, awer ech géif soen 90% vun der Zäit déi ech benotzen Strecken, Et gëtt näischt vill méi schwéier ze maachen wéi dëst. Drënner ass e komplette Schrëtt fir Schrëtt Debugging Guide:

  • Gitt opgeregt wéinst engem vague Message iwwer e System-y Feeler vun engem Programm
  • Restart de Programm mat Strecken
  • Fannt d'Fehlermeldung an de Spuerresultater
  • Gitt méi héich bis Dir den éischte gescheiterte Systemruff trefft

Et ass ganz wahrscheinlech datt de Systemruff am Schrëtt 4 wäert verroden wat falsch gaang ass.

Hiweiser

Ier Dir Iech e Beispill vu méi komplexen Debugging weist, weisen ech Iech e puer Tricks fir effektiv Benotzung Strecken:

Mann ass Äre Frënd

Op ville *nix Systemer kann eng komplett Lëscht vu Systemruffen un de Kärel kritt ginn andeems se lafen Mann syscals. Dir wäert Saache gesinn wéi brk(2), dat heescht méi Informatiounen kann duerch Lafen kritt ginn man 2 brk.

Kleng Rake: Mann 2 Gabel weist mir d'Säit fir d'Schuel Forschett() в GNU libc, déi, stellt sech eraus, duerch Uruff ëmgesat gëtt klonen (). Call Semantik Forschett bleift déi selwecht wann Dir e Programm schreift benotzt Forschett(), a lafen eng Spuer - Ech fannen keng Uriff Forschett, amplaz vun hinnen ginn et klonen (). Esou Rakes duercherneen Iech nëmmen wann Dir ufänkt d'Quell mat der Ausgang ze vergläichen Strecken.

Benotzt -o fir d'Ausgab op eng Datei ze späicheren

Strecken kann extensiv Output generéieren, sou datt et dacks nëtzlech ass Spuerresultater a getrennten Dateien ze späicheren (wéi am Beispill hei uewen). Dëst hëlleft och fir duerchernee Programmausgang mat Ausgang ze vermeiden Strecken an der Konsole.

Benotzt -s fir méi Argumentdaten ze gesinn

Dir hutt vläicht gemierkt datt d'zweet Halschent vun der Fehlermeldung net am Beispill Trace uewen ugewise gëtt. Et ass well Strecken Standard weist nëmmen déi éischt 32 Bytes vum String Argument. Wann Dir méi wëllt gesinn, add eppes wéi -s 128 zum Opruff Strecken.

-y mécht et méi einfach Dateien, Sockets, etc.

"All ass Datei" bedeit datt *nix Systemer all I/O benotze mat Dateideskriptoren, egal ob dat fir eng Datei oder e Netzwierk oder Interprocessleitungen gëlt. Dëst ass bequem fir ze programméieren, awer mécht et schwéier ze verfollegen wat wierklech lass ass wann Dir gemeinsam gesitt gelies и schreiwen am System Opruff Spure Resultater.

Andeems Dir en Bedreiwer derbäigesat -y, Dir wäert Kraaft Strecken annotéiert all Dateideskriptor am Ausgang mat enger Notiz op wat et weist.

Befestegt un e scho lafende Prozess mat -p**

Wéi Dir aus dem Beispill hei ënnen gesitt, musst Dir heiansdo e Programm verfollegen dee scho leeft. Wann et bekannt ass datt et als Prozess 1337 leeft (z., vum Ausgang ps), da kënnt Dir et esou verfollegen:

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

Dir braucht vläicht root Rechter.

Benotzt -f fir Kannerprozesser ze iwwerwaachen

Strecken Par défaut verfollegt et nëmmen ee Prozess. Wann dëse Prozess Kand Prozesser spawn, da kann de System Uruff fir d'Kand Prozess ze spawn gesinn, mä de Kand Prozess System Uriff gëtt net ugewisen.

Wann Dir denkt datt de Feeler an engem Kandprozess ass, benotzt d'Ausso -f, dëst wäert seng Tracing erméiglechen. Den Nodeel vun dësem ass datt d'Ausgab Iech nach méi duerchernee wäert. Wéini Strecken verfollegt ee Prozess oder ee Fuedem, et weist en eenzege Stroum vun Uruffevenementer. Wann et verschidde Prozesser gläichzäiteg verfollegt, kënnt Dir den Ufank vun engem Uruff gesinn, deen duerch e Message ënnerbrach gëtt , dann - eng Rëtsch Uriff fir aner Ausféierungszweige, an nëmmen dann - d'Enn vun der éischter <...foocall erëmfonnt>. Oder opgedeelt all Spuerresultater a verschidde Dateien, och mam Bedreiwer -ff (Detailer an Féierung Op der Strecken).

Filter Spure mat -e

Wéi Dir gesitt, ass d'Resultat vun der Spuer e richtege Koup vun all méigleche Systemappellen. Fändel -e Dir kënnt d'Spuer filteren (kuckt Leadership Op der Strecken). Den Haaptvirdeel ass datt et méi séier ass fir eng gefiltert Spuer ze lafen wéi eng voll Spuer ze maachen an dann grep`an. Fir éierlech ze sinn, ass mir bal ëmmer egal.

Net all Feeler si schlecht

En einfacht an allgemeng Beispill ass e Programm deen no enger Datei op e puer Plazen gläichzäiteg sicht, wéi eng Shell déi no engem Verzeechnes sicht deen eng ausführbar Datei enthält:

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

Heuristike wéi "lescht gescheitert Ufro ier Dir e Feeler bericht" si gutt fir relevant Feeler ze fannen. Egal wéi et ass, et ass logesch vun um Enn unzefänken.

C programméiere Tutorials kann Iech hëllefen System Appellen ze verstoen.

Standard Uriff zu C Bibliothéiken sinn net System Appellen, mä nëmmen eng dënn Uewerfläch Layer. Also, wann Dir op d'mannst e bësse versteet wéi a wat am C ze maachen, ass et méi einfach fir Iech d'Resultater vum System Call Spuer ze verstoen. Zum Beispill, hutt Dir Schwieregkeeten Debugging Appellen ze Reseau Systemer, kuckt op déi selwecht Klassiker Bija's Guide to Network Programming.

E méi komplext Debugging Beispill

Ech hu scho gesot datt d'Beispill vum einfachen Debugging e Beispill ass vu wat ech meeschtens ze dinn hunn wann ech mat schaffen Strecken. Wéi och ëmmer, heiansdo ass eng richteg Enquête erfuerderlech, also hei ass e richtegt Beispill vu méi fortgeschratt Debugging.

bcron - Task Veraarbechtung Scheduler, eng aner Implementatioun vum *nix Daemon cron. Et ass um Server installéiert, awer wann iergendeen probéiert den Zäitplang z'änneren, ass dat wat geschitt:

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

Okay, dat heescht bcron probéiert eng bestëmmte Fichier ze schreiwen, mä et huet net geklappt, an hie wäert net zouginn firwat. Entdecken Strecken:

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

Et gëtt eng Fehlermeldung um Enn schreiwen, mä dës Kéier ass eppes anescht. Als éischt gëtt et kee relevante Systemrufffehler, deen normalerweis virun dësem geschitt. Zweetens ass et kloer datt iergendwou iergendeen d'Fehlermeldung scho gelies huet. Et gesäit aus wéi de richtege Problem soss anzwousch ass, an bcrontab spillt einfach de Message zréck.

Wann Dir kuckt Mann 2 liesen, Dir kënnt gesinn datt dat éischt Argument (3) e Dateideskriptor ass, deen *nix fir all I/O Veraarbechtung benotzt. Wéi fannen ech eraus wat Dateidescriptor 3 duerstellt? An dësem bestëmmte Fall kënnt Dir lafen Strecken mat Bedreiwer -y (kuckt uewen) an et wäert Iech automatesch soen, awer fir esou Saachen erauszefannen, ass et nëtzlech ze wësse wéi een d'Spuerresultater liest an parséiert.

D'Quell vun engem Fichier Descriptor kann ee vu ville System Uruff sinn (et hänkt alles dovun of wat den Descriptor fir ass - eng Konsol, en Netzwierk Socket, d'Datei selwer oder soss eppes), awer sief dat wéi et kann, mir sichen no rifft andeems Dir 3 zréckkënnt (dh mir sichen no "= 3" an de Spuerresultater). An dësem Resultat sinn et 2 vun hinnen: opmaachen ganz uewen an Socket An der Mëtt. opmaachen mécht de Fichier op awer zoumaachen(3) wäert dann weisen, datt et nees zougemaach. (Rake: Dateibeschreiwunge kënne weiderbenotzt ginn wann se opgemaach an zougemaach ginn). Call Socket () gëeegent well et déi lescht virdrun ass liesen (), an et stellt sech eraus datt bcrontab mat eppes duerch e Socket funktionnéiert. Déi nächst Zeil weist datt d'Datei Descriptor assoziéiert ass Unix Domain Socket ënnerwee /var/run/bcron-spool.

Also, mir musse de Prozess fannen verbonne mat unix Socket op der anerer Sait. Et ginn e puer ordentleche Tricks fir dësen Zweck, déi allebéid nëtzlech si fir Server Debugging ze debuggéieren. Déi éischt ass ze benotzen Netstat oder méi nei ss (Socket Status). Béid Kommandoen weisen déi aktiv Netzwierkverbindunge vum System an huelen d'Ausso -l fir lauschteren Sockets ze beschreiwen, wéi och de Bedreiwer -p fir Programmer ze weisen, déi mam Socket als Client verbonne sinn. (Et gi vill méi nëtzlech Optiounen, awer dës zwee si genuch fir dës Aufgab.)

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

Dëst hindeit datt den Nolauschterer de Kommando ass inixserver, Lafen mat Prozess ID 20629. (An, zoufälleg, et benotzt Fichier Descriptor 3 als Socket.)

Déi zweet wierklech nëtzlech Tool fir déiselwecht Informatioun ze fannen ass genannt lsof. Et listet all oppene Dateien (oder Dateideskriptoren) um System. Oder Dir kënnt Informatiounen iwwer eng spezifesch Datei kréien:

# 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

Prozess 20629 ass eng laang-gelieft Server, sou kënnt Dir et befestegt Strecken benotzt eppes wéi strace -o /tmp/trace -p 20629. Wann Dir e Cron Job an engem aneren Terminal ännert, kritt Dir e Spuerausgang mat engem Feeler. An hei ass d'Resultat:

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

(Lescht akzeptéieren () gëtt net ofgeschloss wann Tracing.) erëm, leider, dëst Resultat enthält net de Feeler mir sichen. Mir gesi keng Messagen déi bcrontag schéckt oder aus dem Socket kritt. Amplaz, komplett Prozess Kontroll (Klon, waart 4, SIGCHLD etc.) Dëse Prozess spawnt engem Kand Prozess, deen, wéi Dir kéint roden, mécht déi richteg Aarbecht. A wann Dir braucht hir Spur ze fänken, füügt den Uruff un streck -f. Dëst ass wat mir fanne wa mir no der Fehlermeldung am neie Resultat mat Strace sichen -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 +++

Elo, dat ass eppes. Prozess 21470 kritt en "Zougang refuséiert" Feeler wann Dir probéiert e Fichier um Wee ze kreéieren tmp/spool.21470.1573692319.854640 (bezunn op den aktuellen Aarbechtsverzeichnis). Wa mir just den aktuellen Aarbechtsverzeechnes kennen, wäerte mir och de ganze Wee kennen a fäeg sinn erauszefannen firwat de Prozess seng temporär Datei net erstellt. Leider ass de Prozess scho ofgeschloss, sou datt Dir net nëmmen benotze kënnt lsof -p 21470 fir den aktuellen Verzeechnes ze fannen, awer Dir kënnt an der entgéintgesate Richtung schaffen - kuckt no PID 21470 System Uriff déi den Verzeechnes änneren. (Wann et keng sinn, muss de PID 21470 se vu sengem Elterendeel ierwen, an dëst ass schonn duerch lsof -p kann net fonnt ginn.) Dëse System Opruff ass chdir (wat einfach mat der Hëllef vun modernen Online Sichmotoren erauszefannen ass). An hei ass d'Resultat vun ëmgedréint Sich baséiert op de Spuerresultater, de ganze Wee bis op de 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 +++

(Wann Dir verluer sidd, wëllt Dir vläicht mäi fréiere Post liesen iwwer *nix Prozessmanagement a Muschelen.) Also huet de Server PID 20629 keng Erlaabnis kritt fir e Fichier op de Wee ze kreéieren /var/spool/cron/tmp/spool.21470.1573692319.854640. Wahrscheinlech ass de Grond dofir déi klassesch Dateiesystem Erlaabnis Astellungen. Loosst eis kucken:

# 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

Do läit den Hond begruewen! De Server leeft als Benotzer Cron, awer nëmmen root huet d'Erlaabnis fir an de Verzeichnis ze schreiwen /var/spool/cron/tmp/. Einfach Kommando chown cron /var/spool/cron/tmp/ wäert Kraaft bcron richteg schaffen. (Wann dat net de Problem war, dann ass den nächste wahrscheinlechste Verdächtegen e Kernel Sécherheetsmodul wéi SELinux oder AppArmor, also géif ech de Kernel Message Log mat dmesg.)

Total

System Opruff Spure kënnen iwwerwältegend sinn fir en Ufänger, awer ech hoffen, datt ech gewisen hunn datt se e séiere Wee sinn fir eng ganz Klass vu gemeinsamen Détachementproblemer ze debuggen. Stellt Iech vir datt Dir probéiert e Multiprozess ze debuggen bcronmat engem Schrëtt-fir-Schrëtt Debugger.

Parsing Spuer Resultater no hannen laanscht d'System Opruff Kette verlaangt Fäegkeet, mee wéi gesot, bal ëmmer, benotzt Strecken, Ech kréien just d'Spuereresultat a sichen no Fehler ab Enn. Jiddefalls, Strecken hëlleft mir vill Zäit op Debugging spueren. Ech hoffen et wäert Iech och nëtzlech sinn.

Source: will.com

Setzt e Commentaire