
የዕለት ተዕለት ሥራዬ በአብዛኛው የሶፍትዌር ስርዓቶችን ማሰማራት ነው፣ ይህ ማለት እንደዚህ ያሉ ጥያቄዎችን ለመመለስ ብዙ ጊዜ አጠፋለሁ ማለት ነው፡
- የገንቢው ሶፍትዌር ይሰራል፣ ግን እኔ አላደርገውም። ለምን?
- ይህ ሶፍትዌር ትናንት ለእኔ ሰርቶልኛል፣ ግን ዛሬ አይደለም። ለምን?
ይህ ከመደበኛ የሶፍትዌር ማረም ትንሽ የተለየ የማረም አይነት ነው። መደበኛ ማረም በኮዱ አመክንዮ ላይ ያተኩራል፣ የማሰማራት ማረም ደግሞ በኮዱ እና በአካባቢው መካከል ባለው መስተጋብር ላይ ያተኩራል። የችግሩ ዋና መንስኤ አመክንዮአዊ ስህተት ቢሆንም፣ ሁሉም ነገር በአንድ ማሽን ላይ እንጂ በሌላ ማሽን ላይ አለመሥራቱ ችግሩ በሆነ መንገድ ከአካባቢው ጋር የተያያዘ መሆኑን ያሳያል።
ስለዚህ እንደ የተለመዱ የማረሚያ መሳሪያዎች ከመጠቀም ይልቅ ጂ.ዲ.ቢ. ለማረም የተለያዩ የመሳሪያዎች ስብስብ አለኝ። እና "ይህ ሶፍትዌር ለምን ለእኔ አይሰራም?" የሚለውን ችግር ለመፍታት የምወደው መሳሪያ ይባላል። ክር.
ስትሬስ ምንድን ነው?
— ለ "የስርዓት ጥሪ ክትትል" መሳሪያ ነው። መጀመሪያ የተፈጠረው በ Linuxነገር ግን ተመሳሳይ የማረም ዘዴዎች ለሌሎች ስርዓቶች መሳሪያዎች ሊደረጉ ይችላሉ ( ወይም ).
መሰረታዊ አጠቃቀሙ በጣም ቀላል ነው። ከማንኛውም ትዕዛዝ ጋር ትራስን ብቻ ያሂዱ፣ እና ሁሉንም የስርዓት ጥሪዎች ያስወግዳል (ምንም እንኳን መጀመሪያ መጫን ሊኖርብዎ ይችላል)። ክር):
$ strace echo Hello
...Snip lots of stuff...
write(1, "Hellon", 6) = 6
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++እነዚህ የስርዓት ጥሪዎች ምንድናቸው? እንደ ኦፕሬቲንግ ሲስተም ኪነል ኤፒአይ ናቸው። በአንድ ወቅት ሶፍትዌሩ ወደሚያሄድበት ሃርድዌር ቀጥተኛ መዳረሻ ነበረው። ለምሳሌ፣ በማያ ገጹ ላይ የሆነ ነገር ማሳየት ካስፈለገው፣ ለቪዲዮ መሳሪያዎች ወደቦች ወይም በማህደረ ትውስታ ካርታ የተደረደሩ መዝገቦችን ያጣምራል። ባለብዙ ተግባር የኮምፒውተር ስርዓቶች ተወዳጅ ሲሆኑ፣ የተለያዩ አፕሊኬሽኖች ለሃርድዌር ሲወዳደሩ ትርምስ ነገሰ። በአንድ መተግበሪያ ውስጥ ያሉ ሳንካዎች ሌሎቹን ሊያበላሹ ይችላሉ፣ ሙሉውን ስርዓት ካልሆነ በስተቀር። ከዚያ፣ የመብት ሁነታዎች (ወይም "የቀለበት ጥበቃ") ወደ ሲፒዩ ገቡ። ኪነሉ በጣም የተከበረ ሆነ፡ ለሃርድዌር ሙሉ መዳረሻ ነበረው፣ ይህም ብዙም መብት የሌላቸውን አፕሊኬሽኖች ፈጠረ፣ ከዚያም ከሃርድዌር ጋር ለመገናኘት ከከርነል መዳረሻ መጠየቅ ነበረበት - በስርዓት ጥሪዎች።
በሁለትዮሽ ደረጃ፣ የስርዓት ጥሪ ከቀላል የተግባር ጥሪ ትንሽ የተለየ ነው፣ ነገር ግን አብዛኛዎቹ ፕሮግራሞች በመደበኛ ቤተ-መጽሐፍት ውስጥ መጠቅለያ ይጠቀማሉ። ማለትም፣ የPOSIX C መደበኛ ቤተ-መጽሐፍት የተግባር ጥሪ ይዟል። ጻፍ()ለስርዓቱ ጥሪ ሁሉንም በሥነ-ሕንፃ ላይ የተመሰረተ ኮድ የያዘ ጻፈ.

ባጭሩ፣ በአንድ መተግበሪያ እና በአካባቢያቸው (የኮምፒውተር ስርዓቶች) መካከል ያለው ማንኛውም መስተጋብር የሚከሰተው በስርዓት ጥሪዎች ነው። ስለዚህ፣ ሶፍትዌር በአንድ ማሽን ላይ ሲሰራ በሌላ ማሽን ላይ ግን በማይሰራበት ጊዜ፣ የስርዓት ጥሪ ዱካ ውጤቶችን መመልከት ጥሩ ሀሳብ ነው። በተለይም፣ የስርዓት ጥሪ ዱካን በመጠቀም ሊተነተኑ የሚችሉ የተለመዱ ክስተቶች ዝርዝር እነሆ፡
- የኮንሶል ግብዓት/ውጤት
- የአውታረ መረብ ግ/ኦ
- የፋይል ስርዓት መዳረሻ እና የፋይል ግ/ኦ
- የሂደት/ክር የዕድሜ ልክ አስተዳደር
- ዝቅተኛ ደረጃ የማህደረ ትውስታ አስተዳደር
- ለልዩ መሳሪያዎች አሽከርካሪዎች መዳረሻ
ስቴሬስን መቼ መጠቀም ይቻላል?
በንድፈ ሀሳብ፣ ክር ማንኛውም የተጠቃሚ-ቦታ ፕሮግራም የስርዓት ጥሪዎችን ማድረግ ስላለበት ከማንኛውም የተጠቃሚ-ቦታ ፕሮግራም ጋር ጥቅም ላይ ይውላል። ከተጠናከሩ ዝቅተኛ ደረጃ ፕሮግራሞች ጋር የበለጠ በብቃት ይሰራል፣ ነገር ግን ከአሂድ ጊዜ እና ከአስተርጓሚ የሚመጣውን ተጨማሪ ድምጽ ማለፍ ከቻሉ እንደ ፓይዘን ካሉ ከፍተኛ ደረጃ ቋንቋዎች ጋርም ይሰራል።
በክብሯ ሁሉ ክር በአንድ ማሽን ላይ በጥሩ ሁኔታ የሚሰራ ሶፍትዌርን ሲያርም ራሱን ያሳያል፣ ነገር ግን በድንገት በሌላ ማሽን ላይ መስራት ያቆማል፣ ስለ ፋይሎች፣ ፈቃዶች ወይም ትዕዛዞችን ለማስፈጸም ያልተሳኩ ሙከራዎች ወዘተ ግልጽ ያልሆኑ መልዕክቶችን ያመነጫል። እንደ አለመታደል ሆኖ፣ እንደ የምስክር ወረቀት ማረጋገጫ ስህተቶች ባሉ ከፍተኛ ደረጃ ላይ ባሉ ችግሮች ላይ በጥሩ ሁኔታ አይሰራም። በተለምዶ፣ የ ክር, አንዳንድ ጊዜ እና ከፍተኛ ደረጃ ያላቸው መሳሪያዎች (እንደ የትእዛዝ መስመር መሳሪያ ያሉ) openssl የምስክር ወረቀቱን ለማረም)።
እንደ ምሳሌ አንድን የተለየ አገልጋይ እንጠቀማለን፣ ነገር ግን የስርዓት ጥሪ መከታተያ ብዙውን ጊዜ ይበልጥ ውስብስብ በሆኑ የማሰማሪያ መድረኮች ላይ ሊከናወን ይችላል። የሚያስፈልግዎ ትክክለኛዎቹን መሳሪያዎች ማግኘት ብቻ ነው።
ቀላል የማረሚያ ምሳሌ
እስቲ አንድ አስደናቂ የአገልጋይ መተግበሪያ foo ማስኬድ ይፈልጋሉ እንበል፣ እና የሚከተለውን ያገኛሉ፡
$ foo
Error opening configuration file: No such file or directoryበግልጽ እንደሚታየው፣ የጻፉትን የውቅር ፋይል ማግኘት አልቻለም። ይህ የሆነበት አንዳንድ ጊዜ የጥቅል አስተዳዳሪዎች አንድን መተግበሪያ ሲያጠናቅቁ የሚጠበቁትን የፋይል ቦታዎች ስለሚሽሩ ነው። እና ለአንድ ስርጭት የመጫኛ መመሪያውን ሊከተሉ ቢችሉም፣ ፋይሎቹን ሙሉ በሙሉ በሌላ ቦታ ላይ ሊያገኙዋቸው ይችላሉ። የስህተት መልዕክቱ የውቅር ፋይሉን የት እንደሚፈልጉ ቢነግርዎትም ችግሩ በጥቂት ሰከንዶች ውስጥ ሊፈታ ይችላል፣ ግን አይፈልግም። ታዲያ የት መፈለግ አለብዎት?
የምንጭ ኮዱን መዳረሻ ካሎት፣ ማንበብ እና ሁሉንም ነገር መረዳት ይችላሉ። ጥሩ የመጠባበቂያ እቅድ ነው፣ ግን ፈጣኑ መፍትሄ አይደለም። እንደ ደረጃ በደረጃ ማረም ያሉ የደረጃ በደረጃ ማረም መጠቀም ይችላሉ። ጂ.ዲ.ቢ. ፕሮግራሙ ምን እንደሚሰራ ይመልከቱ፣ ነገር ግን በተለይ ከአካባቢው ጋር ያለውን መስተጋብር ለማሳየት የተነደፈ መሳሪያ መጠቀም የበለጠ ውጤታማ ነው፡ ክር.
መደምደሚያ ክር ይህ አላስፈላጊ ሊመስል ይችላል፣ ነገር ግን መልካም ዜናው አብዛኛው ደህንነቱ በተጠበቀ ሁኔታ ችላ ሊባል የሚችል መሆኑ ነው። የመከታተያ ውጤቶቹን ወደተለየ ፋይል ለማስቀመጥ የ-o ኦፕሬተርን መጠቀም ብዙ ጊዜ ጠቃሚ ነው፡
$ 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 +++የውጤቱ የመጀመሪያ ገጽ በግምት ክር - ይህ ብዙውን ጊዜ ለመጀመር ዝቅተኛ ደረጃ ዝግጅት ነው። (ብዙ ጥሪዎች mmap, አስተካክል, ብር እንደ ዝቅተኛ ደረጃ የማህደረ ትውስታ ማወቂያ እና ተለዋዋጭ የቤተ-መጽሐፍት ካርታ ስራ ላሉ ነገሮች።) እንደ እውነቱ ከሆነ፣ በማረም ጊዜ፣ ውጤቱ ክር ከመጨረሻው ማንበብ ይሻላል። ከታች በኩል ፈተና ይኖራል። ጻፈየስህተት መልእክት ያሳያል። ከላይ ስንመለከት፣ የመጀመሪያውን የተሳሳተ የስርዓት ጥሪ እናያለን - ጥሪው ኦፔንት፣ ስህተት እየሰጠ ኢኖንት (ፋይል ወይም ማውጫ አልተገኘም) ለመክፈት እየሞከረ /etc/foo/config.jsonየውቅር ፋይሉ መሆን ያለበት እዚህ ነው።
ይህ አንድ ምሳሌ ብቻ ነበር፣ ግን እኔ የምጠቀምበትን ጊዜ 90% ማለት እችላለሁ። ክርከዚህ የበለጠ የተወሳሰበ ነገር የለም። ከዚህ በታች የተሟላ ደረጃ በደረጃ የማረም መመሪያ አለ፡
- ከፕሮግራም በሚመጣ ግልጽ ያልሆነ የስርዓት ስህተት መልእክት መበሳጨት
- ፕሮግራሙን እንደገና ያስጀምሩ በ ክር
- በመከታተያ ውጤቶች ውስጥ የስህተት መልዕክቱን ያግኙ
- የመጀመሪያውን ያልተሳካ የስርዓት ጥሪ እስኪነኩ ድረስ ከፍ ይበሉ
በደረጃ 4 ላይ ያለው የስርዓት ጥሪ ምን እንደተሳሳተ የሚያሳይ ሊሆን ይችላል።
ፍንጭ
የበለጠ ውስብስብ የሆነ የስህተት ማስተካከያ ምሳሌ ከማሳየቴ በፊት፣ ውጤታማ አጠቃቀምን በተመለከተ ጥቂት ዘዴዎችን እነግርዎታለሁ። ክር:
ሰውዬው ጓደኛህ ነው
በብዙ *nix ሲስተሞች ላይ፣ ወደ ከርነል የሚደረጉ የስርዓት ጥሪዎች ሙሉ ዝርዝር በማስኬድ ማግኘት ይቻላል። ሰው ሲስካልስእንደዚህ አይነት ነገሮችን ታያለህ ብሩክ(2)ይህም ማለት በማስኬድ ተጨማሪ መረጃ ማግኘት ይቻላል ማለት ነው ማን 2 ብርክ.
ትናንሽ ዘንጎች; ሰው 2 ሹካ የሼሉን ገጽ ያሳየኛል ሹካ () в የጂኤንዩ ሊብሲይህም በመደወል የሚተገበር መሆኑ ታውቋል ክሎን(). ትርጉሞችን ይደውሉ ራፍ የሚጠቀም ፕሮግራም ከጻፉ ተመሳሳይ ሆኖ ይቆያል ሹካ ()እና ዱካ አሂድ - ምንም ጥሪዎችን አላገኘሁም ራፍበእነሱ ምትክ ይሆናል ክሎን()ይህ ዓይነቱ ወጥመድ የሚያደናግርዎት የምንጭ ኮዱን ከውጤቱ ጋር ማወዳደር ሲጀምሩ ብቻ ነው። ክር.
ውጤቱን ወደ ፋይል ለማስቀመጥ -o ይጠቀሙ።
ክር ሰፊ ውጤት ሊያመነጭ ስለሚችል፣ የመከታተያ ውጤቶቹን በተለያዩ ፋይሎች ውስጥ ማከማቸት ብዙውን ጊዜ ጠቃሚ ነው (ከላይ ባለው ምሳሌ ላይ እንደሚታየው)። ይህ የፕሮግራም ውጤትን ከውጤቱ ጋር እንዳያጋጭም ይረዳል። ክር በኮንሶል ውስጥ።
ተጨማሪ የክርክር ውሂብ ለማየት -s ይጠቀሙ።
የስህተት መልዕክቱ ሁለተኛ አጋማሽ ከላይ ባለው የትራክባክ ምሳሌ ላይ እንደማይታይ አስተውለው ይሆናል። ይህ የሆነበት ምክንያት ክር በነባሪነት፣ የሕብረቁምፊውን ክርክር የመጀመሪያዎቹን 32 ባይት ብቻ ያሳያል። ተጨማሪ ማየት ከፈለጉ፣ እንደዚህ ያለ ነገር ያክሉ -128 ወደ ፈተናው ክር.
-የፋይል ሶኬቶችን ወዘተ መከታተል ቀላል ያደርገዋል።
"ሁሉም ፋይል" ማለት *nix ስርዓቶች የፋይል ገላጭዎችን በመጠቀም ሁሉንም I/O ያከናውናሉ ማለት ነው፣ ለፋይል፣ ለኔትወርክ ወይም ለኢንተርፕሮሰሰር ቧንቧዎች። ይህ ለፕሮግራሚንግ ምቹ ነው፣ ነገር ግን የተጋራውን ሲያዩ ምን እየተከናወነ እንዳለ ለማየት አስቸጋሪ ያደርገዋል። ያንብቡ и ጻፈ በስርዓት ጥሪ መከታተያ ውጤቶች ውስጥ።
ኦፕሬተሩን በማከል -y, ታስገድዳለህ ክር በውጤቱ ውስጥ ያለውን እያንዳንዱን የፋይል ገላጭ ምን እንደሚያመለክት ማስታወሻ በመስጠት ያብራሩ።
-p** በመጠቀም አስቀድሞ ከሚሰራ ሂደት ጋር ያያይዙ
ከታች ካለው ምሳሌ እንደሚታየው፣ አንዳንድ ጊዜ እየሄደ ያለ ፕሮግራም መከታተል ያስፈልግዎታል። እንደ ሂደት 1337 (ለምሳሌ፣ ከውጤቱ) እየሄደ መሆኑን ካወቁ ps)፣ ከዚያ እንደሚከተለው መከታተል ይችላሉ፡
$ strace -p 1337
...system call trace output...የ root መዳረሻ ሊያስፈልግዎ ይችላል።
የሕፃናትን ሂደቶች ለመከታተል -f ይጠቀሙ
ክር በነባሪነት አንድ ሂደት ብቻ ነው የሚከታተለው። ይህ ሂደት የሕፃናት ሂደቶችን የሚፈጥር ከሆነ፣ የልጁ ሂደት እንዲፈጠር የስርዓት ጥሪውን ማየት ይችላሉ፣ ነገር ግን የልጁ ሂደት የስርዓት ጥሪዎች አይታዩም።
ስህተቱ በልጅ ሂደት ውስጥ ነው ብለው ካሰቡ፣ ኦፕሬተሩን ይጠቀሙ -fይህ ዱካውን እንዲከታተል ያስችለዋል። ጉዳቱ ውጤቱ የበለጠ ግራ የሚያጋባዎት መሆኑ ነው። መቼ ክር አንድን ሂደት ወይም ክር ሲከታተል፣ የጥሪ ክስተቶችን አንድ ጊዜ ፍሰት ያሳያል። በአንድ ጊዜ ብዙ ሂደቶችን ሲከታተል፣ በመልዕክት የተቋረጠ ጥሪ መጀመሪያ ሊያዩ ይችላሉ። ከዚያም ለሌሎች የአፈፃፀም ቅርንጫፎች ብዙ ጥሪዎች ይነሳሉ፣ እና ከዚያ በኋላ የመጀመሪያው መጨረሻ ብቻ ነው <… ፉካል ከቆመበት ቀጥሏል>ወይም ኦፕሬተሩን በመጠቀም ሁሉንም የመከታተያ ውጤቶች ወደ ተለያዩ ፋይሎች ይከፋፍሉ -ፍ (ዝርዝሮች በ ላይ ክር).
ዱካውን በ-e ያጣሩ
እንደምታየው፣ የመከታተያው ውጤት የሁሉም ሊሆኑ የሚችሉ የስርዓት ጥሪዎች ትክክለኛ ክምር ነው። -e ዱካውን ማጣራት ይችላሉ (ይመልከቱ) ላይ ክር) ዋነኛው ጥቅሙ ከማጣሪያ ጋር ዱካ ማስኬድ ሙሉ ዱካ ከማድረግ እና ከዚያ በኋላ ፈጣን መሆኑ ነው። grepእውነቱን ለመናገር፣ በጭራሽ ግድ የለኝም ማለት ይቻላል።
ሁሉም ስህተቶች መጥፎ አይደሉም
ቀላል እና የተለመደ ምሳሌ አንድን ፋይል በበርካታ ቦታዎች በአንድ ጊዜ የሚፈልግ ፕሮግራም ነው፣ ለምሳሌ፣ የሚተገበር ፋይል የያዘውን የሪሳይክል ቢን ማውጫ የሚፈልግ ሼል፡
$ 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
...እንደ "ከስህተት መልእክት በፊት የመጨረሻው ያልተሳካ ጥያቄ" ያሉ ሂዩሪስቲክስ ተዛማጅ ስህተቶችን ለማግኘት ጥሩ ናቸው። ሆኖም ግን፣ ከመጨረሻው መጀመር ምክንያታዊ ነው።
የሲ ፕሮግራሚንግ መመሪያዎች የስርዓት ጥሪዎችን ለመረዳት ጥሩ መንገድ ናቸው።
መደበኛ የC ቤተ-መጽሐፍት ጥሪዎች የስርዓት ጥሪዎች አይደሉም፣ ይልቁንም ከላይ ቀጭን ንብርብር ናቸው። ስለዚህ፣ በC ውስጥ እንዴት እና ምን ማድረግ እንዳለቦት መሰረታዊ ግንዛቤ ካለዎት፣ የስርዓት ጥሪ ዱካ ውጤቶችን ለመረዳት ቀላል ሆኖ ያገኙታል። ለምሳሌ፣ የአውታረ መረብ ስርዓት ጥሪዎችን ማረም ላይ ችግር እያጋጠመዎት ከሆነ፣ ተመሳሳይ ክላሲክ ይመልከቱ። .
ይበልጥ ውስብስብ የሆነ የማረሚያ ምሳሌ
ቀላል የማረም ምሳሌ አብነት አብሬ ስሰራ በአብዛኛው የምጋፈጠው ነገር እንደሆነ አስቀድሜ ተናግሬያለሁ። ክርሆኖም ግን፣ አንዳንድ ጊዜ እውነተኛ ምርመራ ያስፈልጋል፣ ስለዚህ የበለጠ ውስብስብ የሆነ የስህተት ማረም ችግር እውነተኛ ምሳሌ ይኸውና።
— የተግባር መርሐግብር አስያዥ፣ የ *nix ዴሞን ሌላ ትግበራ በመርሃግብሩበአገልጋዩ ላይ ተጭኗል፣ ነገር ግን አንድ ሰው የጊዜ ሰሌዳውን ለማረም ሲሞክር፣ ይህ ይከሰታል፡
# crontab -e -u logs
bcrontab: Fatal: Could not create temporary fileእሺ እንግዲህ፣ ብሪክሮን የተወሰነ ፋይል ለመጻፍ ሞክሯል፣ ግን አልሰራም፣ እና ለምን እንደሆነ አልተናገረም። እስቲ እንፈታው። ክር:
# 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 +++እስከመጨረሻው ድረስ የስህተት መልእክት አለ ጻፈግን በዚህ ጊዜ አንዳንድ የተለዩ ነገሮች አሉ። በመጀመሪያ፣ ከዚህ በፊት የሚከሰት ምንም ተዛማጅ የስርዓት ጥሪ ስህተት የለም። ሁለተኛ፣ የሆነ ቦታ የሆነ ሰው የስህተት መልዕክቱን እንዳነበበ ግልጽ ነው። ትክክለኛው ችግር ሌላ ቦታ ያለ ይመስላል፣ እና bcrontab መልእክቱን በቀላሉ ያጫውታል።
የምትመለከት ከሆነ ሰው 2 አንብብየመጀመሪያው ክርክር (3) *nix ለሁሉም የI/O ሂደት የሚጠቀምበት የፋይል ገላጭ መሆኑን ማየት ይችላሉ። የፋይል ገላጭ 3 ምን እንደሚወክል እንዴት ማወቅ ይችላሉ? በዚህ ጉዳይ ላይ፣ ማስኬድ ይችላሉ ክር ከኦፕሬተሩ ጋር -y (ከላይ ይመልከቱ)፣ እና በራስ-ሰር ይነግርዎታል፣ ሆኖም ግን፣ እንደዚህ ያሉ ነገሮችን ለማወቅ፣ የመከታተያ ውጤቶችን እንዴት ማንበብ እና መተንተን እንደሚቻል ማወቅ ጠቃሚ ነው።
የፋይል ገላጭ ምንጭ ከብዙ የስርዓት ጥሪዎች አንዱ ሊሆን ይችላል (ሁሉም የሚወሰነው ገላጭው ለምን እንደሆነ - ኮንሶል፣ የአውታረ መረብ ሶኬት፣ ፋይሉ ራሱ ወይም ሌላ ነገር) ላይ ነው። ያም ሆነ ይህ፣ 3 የሚመልሱ ጥሪዎችን እንፈልጋለን (ማለትም፣ በትራኩ ውጤቶች ውስጥ "= 3" እንፈልጋለን)። በዚህ ውጤት ውስጥ ሁለት አሉ፡ ኦፔንት ከላይኛው ጫፍ እና ሶኬት በመሃል ላይ። ኦፔንት ፋይሉን ይከፍታል፣ ግን ገጠመ(3) ከዚያም እንደገና እየተዘጋ መሆኑን ያሳያል። (ይሄ፡ የፋይል ገላጭዎች ሲከፈቱ እና ሲዘጉ እንደገና ጥቅም ላይ ሊውሉ ይችላሉ።) ጥሪው ሶኬት() ተስማሚ ነው ምክንያቱም ከዚህ በፊት የመጨረሻው ስለሆነ አንብብ(), እና bcrontab የሆነ ነገር በሶኬት በኩል እየደረሰበት እንደሆነ ታወቀ። የሚቀጥለው መስመር የፋይል ገላጭው ከ ጋር የተያያዘ መሆኑን ያሳያል። የዩኒክስ ዶሜይን ሶኬት በመንገድ ላይ /var/run/bcron-spool.
ስለዚህ፣ የተያያዘውን ሂደት ማግኘት አለብን የዩኒክስ ሶኬት በሌላ በኩል፣ ለዚህ ዓላማ የሚሆኑ ጥቂት ጥሩ ዘዴዎች አሉ፣ እና ሁለቱም የአገልጋይ ማሰማራትን ለማረም ጠቃሚ ናቸው። የመጀመሪያው መጠቀም ነው። netstat ወይም አዲስ ss (የሶኬት ሁኔታ)። ሁለቱም ትዕዛዞች የስርዓቱን ንቁ የአውታረ መረብ ግንኙነቶች ያሳያሉ እና ኦፕሬተሩን ይወስዳሉ -l የማዳመጥ ሶኬቶችን እንዲሁም ኦፕሬተሩን ለመግለጽ -p ከሶኬት ጋር የተገናኙ ፕሮግራሞችን እንደ ደንበኞች ለማሳየት። (ብዙ ተጨማሪ ጠቃሚ አማራጮች አሉ፣ ነገር ግን እነዚህ ሁለቱ ለዚህ ተግባር በቂ ናቸው።)
# ss -pl | grep /var/run/bcron-spool
u_str LISTEN 0 128 /var/run/bcron-spool 1466637 * 0 users:(("unixserver",pid=20629,fd=3))ይህ ማለት አድማጩ ቡድኑ ነው ማለት ነው inixserverከሂደት መለያ ቁጥር 20629 ጋር እየሄደ ነው። (እና፣ በአጋጣሚ፣ የፋይል ገላጭ 3ን እንደ ሶኬት ይጠቀማል።)
ተመሳሳይ መረጃ ለማግኘት ሁለተኛው በጣም ጠቃሚ መሣሪያ ይባላል lsofበስርዓቱ ላይ ያሉትን ሁሉንም የተከፈቱ ፋይሎች (ወይም የፋይል ገላጭዎችን) ይዘረዝራል። በአማራጭ፣ ስለ አንድ የተወሰነ ፋይል መረጃ ማግኘት ይችላሉ፦
# 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ሂደት 20629 ረጅም ዕድሜ ያለው አገልጋይ ነው፣ ስለዚህ ከእሱ ጋር ማያያዝ ይችላሉ ክር አይነት ነገርን በመጠቀም strace -o /tmp/trace -p 20629የክሮን ስራን በሌላ ተርሚናል ላይ ካስተካከሉት፣ ከተከሰተው ስህተት ጋር የመከታተያ ውጤት ያገኛሉ። ውጤቱ እነሆ፡
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(የመጨረሻው) ተቀበል() (በክትትል ወቅት አይጠናቀቅም።) እንደገና፣ በሚያሳዝን ሁኔታ፣ ይህ ውጤት የምንፈልገውን ስህተት አልያዘም። ወደ ሶኬት የሚልካቸው ወይም የሚቀበሏቸውን መልዕክቶች አናይም። በምትኩ፣ ንጹህ የሂደት ቁጥጥር ብቻ ነው (ፊደል, ዋይት4, ሲግችልድ ወዘተ) ይህ ሂደት የልጅ ሂደትን ይፈጥራል፣ ይህም እርስዎ እንደሚገምቱት እውነተኛውን ስራ ይሰራል። እና መከታተል ከፈለጉ ወደ ጥሪው ያክሉት። strace -fበአዲሱ ውጤት ውስጥ ከስትሬስ ጋር የስህተት መልእክት ስንፈልግ የምናገኘው እነሆ -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 +++እሺ፣ ያ የሆነ ነገር ነው። ሂደት 21470 በመንገዱ ላይ ፋይል ለመፍጠር ሲሞክር "መዳረሻ ተከልክሏል" የሚል ስህተት ያገኛል። tmp/spool.21470.1573692319.854640 (ከአሁኑ የስራ ማውጫ ጋር በተያያዘ)። የአሁኑን የስራ ማውጫ በቀላሉ ብናውቅ ኖሮ፣ ሙሉውን መንገድ እናውቃለን እና ሂደቱ ለምን ጊዜያዊ ፋይሉን እዚያ መፍጠር እንደማይችል ማወቅ እንችላለን። እንደ አለመታደል ሆኖ፣ ሂደቱ ቀድሞውኑ አልቋል፣ ስለዚህ በቀላሉ መጠቀም አንችልም lsof -p 21470 የአሁኑን ማውጫ ለማግኘት፣ ነገር ግን በተቃራኒው አቅጣጫ መስራት ይችላሉ - ማውጫውን የሚቀይሩ የPID 21470 የስርዓት ጥሪዎችን ይፈልጉ። (ምንም ከሌለ፣ PID 21470 ከወላጅ ወርሶታል፣ እና ይህ አስቀድሞ ነው lsof-p ማወቅ አልችልም።) ይህ የስርዓት ጥሪ chdir (ይህም ዘመናዊ የመስመር ላይ የፍለጋ ፕሮግራሞችን በመጠቀም ለማወቅ ቀላል ነው)። እና ወደ አገልጋይ 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 +++(ከጠፋህ፣ የቀደመውን ጽሑፌን ማንበብ ትፈልግ ይሆናል። .) ስለዚህ፣ የአገልጋይ PID 20629 በዱካ ላይ ፋይል የመፍጠር ፈቃድ አልነበረውም። /var/spool/cron/tmp/spool.21470.1573692319.854640ይህ በአብዛኛው የሚከሰተው በክላሲክ የፋይል ስርዓት ፈቃድ ቅንብሮች ምክንያት ነው። እስቲ እንፈትሽ፦
# 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ውሻው የተቀበረው እዚያ ነው! አገልጋዩ እንደ ተጠቃሚ ክሮን ይሰራል፣ ነገር ግን ወደ ማውጫው የመጻፍ ፈቃድ ያለው ሩት ብቻ ነው። /var/spool/cron/tmp/ቀላል ትዕዛዝ chown ክሮን /var/spool/cron/tmp/ ያስገድዳል ብሪክሮን በአግባቡ ይስሩ። (ችግሩ ይህ ካልሆነ፣ ቀጣዩ በጣም ጥርጣሬ ያለው የSE ከርነል ደህንነት ሞጁል ነው።Linux ወይም AppArmor፣ ስለዚህ የከርነል መልእክት ምዝግብ ማስታወሻውን እፈትሻለሁ በ dmesg.)
ԸՆԴՀԱՆՈՒՐ ԳԻՆ
ለጀማሪ፣ የሲስካል ዱካ ውጤት በጣም ከባድ ሊሆን ይችላል፣ ነገር ግን አጠቃላይ የተለመዱ የማሰማራት ችግሮችን ለማረም ፈጣን መንገድ መሆኑን እንዳሳየሁ ተስፋ አደርጋለሁ። ባለብዙ ሂደትን ለማረም መሞከርን አስቡት። ብሪክሮንደረጃ በደረጃ ማረምን በመጠቀም።
በስርዓት ጥሪ ሰንሰለቱ ላይ የክትትል ውጤቶችን መቀልበስ ክህሎት ይጠይቃል፣ ነገር ግን እንደገለጽኩት፣ ሁልጊዜ ማለት ይቻላል፣ መጠቀም ክርየትራክባክ ውጤቱን ብቻ ነው የማገኘው እና ከመጨረሻው ጀምሮ ስህተቶችን እፈልጋለሁ። ያም ሆነ ይህ፣ ክር ብዙ ጊዜ ይቆጥብልኛል። ላንተም ጠቃሚ እንደሚሆን ተስፋ አደርጋለሁ።
ምንጭ: hab.com
