የሶፍትዌር ዝርጋታ ማረም በስትራሴ

የሶፍትዌር ዝርጋታ ማረም በስትራሴ

የቀን ስራዬ ባብዛኛው የሶፍትዌር ማሰማራት ነው፣ ይህ ማለት እንደሚከተሉት ያሉ ጥያቄዎችን ለመመለስ በመሞከር ብዙ ጊዜዬን አሳልፋለሁ።

  • ይህ ሶፍትዌር ለገንቢው ይሰራል፣ ግን ለእኔ አይደለም። ለምን?
  • ትላንትና ይህ ሶፍትዌር ለእኔ ሠርቷል, ግን ዛሬ ግን አይሰራም. ለምን?

ይህ ከመደበኛ የሶፍትዌር ማረም ትንሽ ለየት ያለ የማረም አይነት ነው። መደበኛ ማረም ስለ ኮድ አመክንዮ ነው, ነገር ግን የማሰማራት ማረም በኮዱ እና በአካባቢው መካከል ስላለው መስተጋብር ነው. ምንም እንኳን የችግሩ መንስኤ ምክንያታዊ ስህተት ቢሆንም ሁሉም ነገር በአንድ ማሽን ላይ እንጂ በሌላ ማሽን ላይ አለመሆኑ ችግሩ በተወሰነ መልኩ በአካባቢው ላይ ነው.

ስለዚህ እንደ ከተለመዱት የማረሚያ መሳሪያዎች ይልቅ ጂ.ዲ.ቢ. ማሰማራትን ለማረም የተለየ የመሳሪያዎች ስብስብ አለኝ። እና እንደ "ለምንድን ነው ይህ ሶፍትዌር ለእኔ የማይሰራው?" ያለውን ችግር ለመፍታት የምወደው መሳሪያ. ተብሎ ይጠራል ክር.

ክር ምንድን ነው?

ክር ለ “የስርዓት ጥሪ ፍለጋ” መሣሪያ ነው። በመጀመሪያ የተፈጠረው ለሊኑክስ ነው፣ ነገር ግን ተመሳሳይ የማረም ዘዴዎች ለሌሎች ስርዓቶች በመሳሪያዎች ሊደረጉ ይችላሉ (DTrace ወይም ktrace).

መሠረታዊው መተግበሪያ በጣም ቀላል ነው. በማንኛውም ትእዛዝ ማሄድ ብቻ ያስፈልግዎታል እና ሁሉንም የስርዓት ጥሪዎች ይጥላል (ምንም እንኳን መጀመሪያ እርስዎ እራስዎ መጫን ይኖርብዎታል) ክር):

$ 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 መደበኛ ቤተ-መጽሐፍት የተግባር ጥሪን ይዟል ፃፍ ()ለስርዓቱ ጥሪ ሁሉንም የስነ-ህንፃ-ተኮር ኮድ የያዘ ጻፈ.

የሶፍትዌር ዝርጋታ ማረም በስትራሴ

ባጭሩ በመተግበሪያ እና በአከባቢው (በኮምፒዩተር ሲስተሞች) መካከል የሚደረግ ማንኛውም መስተጋብር በስርዓት ጥሪዎች ይከናወናል። ስለዚህ ሶፍትዌሮች በአንድ ማሽን ላይ ሲሰሩ ነገር ግን በሌላ ማሽን ላይ ሲሰራ, የስርዓት ጥሪ መከታተያ ውጤቶችን መመልከት ጥሩ ይሆናል. በይበልጥ፣ የስርዓት ጥሪ ፈለግን በመጠቀም ሊተነተኑ የሚችሉ የተለመዱ ነጥቦች ዝርዝር እዚህ አለ።

  • ኮንሶል I/O
  • አውታረ መረብ I/O
  • የፋይል ስርዓት መዳረሻ እና ፋይል I/O
  • የሂደቱን ክር የህይወት ዘመን ማስተዳደር
  • ዝቅተኛ-ደረጃ ማህደረ ትውስታ አስተዳደር
  • ለተወሰኑ የመሣሪያ ነጂዎች መዳረሻ

ስቴክ መጠቀም መቼ ነው?

በንድፈ ሀሳብ፣ ክር በተጠቃሚ ቦታ ውስጥ ከማንኛውም ፕሮግራም ጋር ጥቅም ላይ ይውላል, ምክንያቱም በተጠቃሚ ቦታ ውስጥ ያለ ማንኛውም ፕሮግራም የስርዓት ጥሪዎችን ማድረግ አለበት. በተቀናበረ ዝቅተኛ ደረጃ ፕሮግራሞች በብቃት ይሰራል ነገር ግን ተጨማሪውን ጫጫታ እና አስተርጓሚውን መቁረጥ ከቻሉ እንደ Python ካሉ ከፍተኛ ቋንቋዎች ጋር ይሰራል።

በክብሩ ሁሉ ክር በአንድ ማሽን ላይ በደንብ የሚሰራውን ሶፍትዌር በማረም ወቅት እራሱን ያሳያል፣ ነገር ግን በድንገት በሌላ ማሽን ላይ መስራት አቁሟል፣ ስለፋይሎች፣ ፍቃዶች ግልጽ ያልሆኑ መልዕክቶችን በማውጣቱ ወይም አንዳንድ ትዕዛዞችን ወይም ሌላ ነገርን ለማስፈጸም ያልተሳኩ ሙከራዎችን ያደርጋል... ያሳዝናል፣ ግን አላደረገም። እንደ የምስክር ወረቀት ማረጋገጫ ስህተቶች ካሉ ከከፍተኛ ደረጃ ችግሮች ጋር በደንብ ያጣምሩ። ብዙውን ጊዜ ይህ ጥምረት ይጠይቃል ክርአንዳንድ ጊዜ ltrace እና ከፍተኛ ደረጃ ያላቸው መሳሪያዎች (እንደ የትእዛዝ መስመር መሳሪያ 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, አስተካክል, ብር እንደ ዝቅተኛ ደረጃ ማህደረ ትውስታን መፈለግ እና ተለዋዋጭ ቤተ-ፍርግሞችን ማሳየት ላሉ ነገሮች።) በእውነቱ ውጤቱን በማረም ወቅት ክር ከመጨረሻው ማንበብ ይሻላል። ከዚህ በታች ፈተና ይኖራል ጻፈ, ይህም የስህተት መልእክት ያሳያል. ከላይ እንመለከታለን እና የመጀመሪያውን የተሳሳተ የስርዓት ጥሪ - ጥሪውን እናያለን ክፍት, ይህም ስህተት ይጥላል ENOENT ("ፋይል ወይም ማውጫ አልተገኘም") ለመክፈት በመሞከር ላይ /etc/foo/config.json. የማዋቀሪያው ፋይል መሆን ያለበት እዚህ ነው።

ይህ ምሳሌ ብቻ ነበር, ግን እኔ የምጠቀምበትን ጊዜ 90% እላለሁ ክር, ከዚህ የበለጠ አስቸጋሪ ነገር የለም. ከዚህ በታች የተሟላ የደረጃ በደረጃ ማረም መመሪያ አለ፡-

  • ከፕሮግራሙ ስለተፈጠረ የስርዓት-y ስህተት ግልጽ ባልሆነ መልእክት ምክንያት ተበሳጩ
  • ፕሮግራሙን እንደገና ያስጀምሩት። ክር
  • በክትትል ውጤቶች ውስጥ የስህተት መልዕክቱን ያግኙ
  • የመጀመሪያውን ያልተሳካ የስርዓት ጥሪ እስክትነካ ድረስ ከፍ አድርግ

በደረጃ 4 ላይ ያለው የስርዓት ጥሪ ስህተት የሆነውን ነገር የመግለጽ እድሉ ሰፊ ነው።

ፍንጭ

ይበልጥ የተወሳሰበ ማረም ምሳሌን ከማሳየቴ በፊት ውጤታማ አጠቃቀም ጥቂት ዘዴዎችን አሳይሃለሁ ክር:

ሰው ጓደኛህ ነው።

በብዙ * nix ስርዓቶች፣ ወደ ከርነል የሚደረጉ የስርዓት ጥሪዎች ዝርዝር በመሮጥ ማግኘት ይቻላል። ሰው syscals. የመሳሰሉ ነገሮችን ታያለህ ብር(2), ይህም ማለት በመሮጥ ተጨማሪ መረጃ ማግኘት ይቻላል ሰው 2 ብር.

አነስተኛ ማሰሪያ; ሰው 2 ሹካ ለሼል ገጹን ያሳየኛል ሹካ () в ጂኤንዩ ሊቢሲ, እሱም እንደሚታየው, በመደወል የሚተገበረው ክሎን(). የትርጓሜ ቃላት ይደውሉ ራፍ በመጠቀም ፕሮግራም ከጻፉ ያው ይቀራል ሹካ (), እና ዱካ አሂድ - ምንም ጥሪዎች አላገኘሁም። ራፍበእነርሱ ምትክ ይኖራል ክሎን(). እንደነዚህ ያሉት ራኮች ምንጩን ከውጤቱ ጋር ማወዳደር ከጀመሩ ብቻ ግራ ያጋቡዎታል ክር.

ውጤቱን ወደ ፋይል ለማስቀመጥ -o ይጠቀሙ

ክር ሰፋ ያለ ውፅዓት ማመንጨት ስለሚችል ብዙውን ጊዜ የመከታተያ ውጤቶችን በተለየ ፋይሎች ውስጥ ማከማቸት ጠቃሚ ነው (ከላይ እንደ ምሳሌው)። ይህ ደግሞ ከውጤት ጋር ግራ የሚያጋባ የፕሮግራም ውጤትን ለማስወገድ ይረዳል ክር በኮንሶል ውስጥ.

ተጨማሪ የመከራከሪያ ነጥብ ለማየት -s ይጠቀሙ

የስህተት መልዕክቱ ሁለተኛ አጋማሽ ከላይ ባለው ምሳሌ ፈለግ ላይ እንደማይታይ አስተውለህ ይሆናል። ምክንያቱም ነው። ክር ነባሪ የመጀመሪያውን 32 ባይት የሕብረቁምፊ ነጋሪ እሴት ያሳያል። ተጨማሪ ማየት ከፈለጉ, የሆነ ነገር ያክሉ -ክስ 128 ወደ ጥሪው ክር.

-y ፋይሎችን፣ ሶኬቶችን ወዘተ መከታተልን ቀላል ያደርገዋል።

"All is file" ማለት *nix ሲስተሞች የፋይል ገላጭዎችን በመጠቀም ሁሉንም አይ/ኦ ያከናውናሉ፣ ያ በፋይል ወይም በኔትወርክ ወይም በኢንተርፕሮሴስ ቧንቧዎች ላይ ተፈጻሚ ይሆናል። ይህ ለፕሮግራም አወጣጥ ምቹ ነው፣ ነገር ግን የተለመዱ ሲያዩ ምን እየተከሰተ እንዳለ ለመከታተል አስቸጋሪ ያደርገዋል ያንብቡ и ጻፈ በስርዓቱ የጥሪ መከታተያ ውጤቶች ውስጥ።

ኦፕሬተር በማከል -у፣ ታስገድዳለህ ክር በውጤቱ ውስጥ ያለውን እያንዳንዱን ፋይል ገላጭ የሚጠቁመውን ማስታወሻ ይግለጹ።

ከ -p** ጋር ቀድሞውኑ ከሚሰራ ሂደት ጋር ያያይዙ

ከታች ካለው ምሳሌ እንደሚመለከቱት, አንዳንድ ጊዜ ቀድሞውኑ እየሰራ ያለውን ፕሮግራም መፈለግ ያስፈልግዎታል. እንደ ሂደት 1337 እየሄደ እንደሆነ ከታወቀ (ከውጤቱ ውስጥ ይበሉ ps), ከዚያ እንደሚከተለው መከታተል ይችላሉ-

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

የስር መብቶች ሊያስፈልግህ ይችላል።

የህጻናትን ሂደት ለመከታተል -f ይጠቀሙ

ክር በነባሪነት አንድ ሂደት ብቻ ይከታተላል። ይህ ሂደት የሕፃን ሂደቶችን የሚፈጥር ከሆነ፣ የልጅ ሂደትን ለመራባት የስርዓት ጥሪ ሊታይ ይችላል፣ ነገር ግን የልጁ ሂደት የስርዓት ጥሪዎች አይታዩም።

ስህተቱ በልጆች ሂደት ውስጥ ነው ብለው ካሰቡ መግለጫውን ይጠቀሙ -fይህ ፈልጎ ማግኘት ያስችላል። የዚህ አሉታዊ ጎን ውጤቱ የበለጠ ግራ የሚያጋባ መሆኑ ነው። መቼ ክር አንድ ሂደት ወይም አንድ ክር ይከታተላል፣ አንድ ነጠላ የጥሪ ክስተቶችን ያሳያል። ብዙ ሂደቶችን በአንድ ጊዜ ሲከታተል፣ በመልዕክት ሲቋረጥ የጥሪ መጀመሪያ ሊያዩ ይችላሉ። , ከዚያ - ለሌሎች የማስፈጸሚያ ቅርንጫፎች ጥሪዎች ስብስብ, እና ከዚያ ብቻ - የመጀመሪያው መጨረሻ <…foocal ከቀጠለ>. ወይም ሁሉንም የመከታተያ ውጤቶችን ወደ ተለያዩ ፋይሎች ይከፋፍሏቸው፣ እንዲሁም ኦፕሬተሩን ይጠቀሙ -ፍ (ዝርዝሮች በ አመራር ላይ ክር).

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

በመጨረሻው አካባቢ የስህተት መልእክት አለ። ጻፈበዚህ ጊዜ ግን የሆነ ነገር የተለየ ነው። በመጀመሪያ ፣ ምንም ተዛማጅ የስርዓት ጥሪ ስህተት የለም ፣ ብዙውን ጊዜ ከዚህ በፊት ይከሰታል። በሁለተኛ ደረጃ, የሆነ ቦታ አንድ ሰው አስቀድሞ የስህተት መልእክቱን እንዳነበበ ግልጽ ነው. እውነተኛው ችግር ሌላ ቦታ ይመስላል, እና ብክሮንታብ በቀላሉ መልእክቱን መልሶ ያጫውታል።

ብትመለከቱት ሰው 2 ማንበብ, የመጀመሪያው ነጋሪ እሴት (3) የፋይል ገላጭ መሆኑን ማየት ይችላሉ, ይህም * nix ለሁሉም የ I/O ሂደት ይጠቀማል. የፋይል ገላጭ 3 የሚወክለውን እንዴት ማወቅ እችላለሁ? በዚህ ሁኔታ, መሮጥ ይችላሉ ክር ከዋኝ ጋር -у (ከላይ ያለውን ይመልከቱ) እና በራስ-ሰር ይነግርዎታል፣ ነገር ግን እነዚህን መሰል ነገሮች ለማወቅ፣ እንዴት ማንበብ እና የክትትል ውጤቶችን መተንተን እንደሚቻል ማወቅ ጠቃሚ ነው።

የፋይል ገላጭ ምንጭ ከብዙ የስርዓት ጥሪዎች ውስጥ አንዱ ሊሆን ይችላል (ሁሉም ገላጭ ለሆነው - ኮንሶል ፣ የአውታረ መረብ ሶኬት ፣ ፋይሉ ራሱ ወይም ሌላ ነገር ላይ የተመሠረተ ነው) ፣ ግን እንደዚያ ሊሆን ይችላል ፣ እኛ እንፈልጋለን። ጥሪዎች 3 በመመለስ (ማለትም በክትትል ውጤቶች ውስጥ "= 3" እንፈልጋለን)። በዚህ ውጤት ውስጥ 2ቱ አሉ- ክፍት በጣም ላይ እና ሶኬት መሃል ላይ. ክፍት ፋይሉን ይከፍታል ግን ገጠመ(3) ከዚያም እንደገና እንደሚዘጋ ያሳያል. (Rake: ፋይል ገላጭዎች ሲከፈቱ እና ሲዘጉ እንደገና ጥቅም ላይ ሊውሉ ይችላሉ). ይደውሉ ሶኬት() ተስማሚ ነው ምክንያቱም ከዚህ በፊት የመጨረሻው ነው አንብብ (), እና ብሮንቶብ በሶኬት በኩል ከአንድ ነገር ጋር አብሮ ይሰራል. የሚቀጥለው መስመር የፋይል ገላጭ ከ ጋር የተያያዘ መሆኑን ያሳያል ዩኒክስ ጎራ ሶኬት በመንገድ ላይ /var/ሩጫ/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

(የመጨረሻ ተቀበል() ፍለጋ ሲደረግ አይጠናቀቅም።) እንደገና፣ በሚያሳዝን ሁኔታ፣ ይህ ውጤት የምንፈልገውን ስህተት አልያዘም። bcrontag ወደ ሶኬት የሚልክ ወይም የሚቀበል ምንም አይነት መልእክት አናይም። ይልቁንስ የሂደቱን ቁጥጥር ያጠናቅቁ (ፊደል, መጠበቅ4, SIGCHLD ወዘተ) ይህ ሂደት የልጅ ሂደትን ይፈጥራል, እርስዎ እንደሚገምቱት, እውነተኛውን ስራ ይሰራል. እና የእርሷን መንገድ ለመያዝ ከፈለጉ, ወደ ጥሪው ያክሉት 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 ሊታወቅ አይችልም.) ይህ የስርዓት ጥሪ ነው ክዲር (በዘመናዊ የመስመር ላይ የፍለጋ ፕሮግራሞች እርዳታ ለማወቅ ቀላል ነው). እና በክትትል ውጤቶቹ ላይ በመመስረት የተገላቢጦሽ ፍለጋዎች ውጤት እዚህ አለ ፣ እስከ 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 +++

(ከጠፋህ የቀድሞ ጽሁፌን ማንበብ ትፈልግ ይሆናል። ስለ * nix ሂደት አስተዳደር እና ዛጎሎች.) ስለዚህ አገልጋዩ 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/ ያስገድዳል ብክሮን በትክክል መስራት. (ችግሩ ያ ካልሆነ የሚቀጥለው ተጠርጣሪ እንደ SELinux ወይም AppArmor ያለ የከርነል ሴኪዩሪቲ ሞጁል ነው፣ስለዚህ የከርነል መልእክት ምዝግብ ማስታወሻን አረጋግጣለሁ። dmesg.)

ԸՆԴՀԱՆՈՒՐ ԳԻՆ

የስርዓት ጥሪ ዱካዎች ለጀማሪዎች ከአቅም በላይ ሊሆኑ ይችላሉ፣ነገር ግን አጠቃላይ አጠቃላይ የማሰማራት ችግሮችን ለማረም ፈጣኑ መንገድ መሆናቸውን እንዳሳየኝ ተስፋ አደርጋለሁ። ብዙ ሂደትን ለማረም እንደሞከርክ አስብ ብክሮንደረጃ-በ-ደረጃ አራሚ በመጠቀም.

በስርአቱ የጥሪ ሰንሰለቱ ላይ ያለውን ውጤት ወደ ኋላ መተንተን ክህሎትን ይጠይቃል፣ነገር ግን እንዳልኩት ሁልጊዜ ማለት ይቻላል መጠቀም ክር, ውጤቱን ብቻ አገኛለሁ እና ከመጨረሻው ጀምሮ ስህተቶችን እፈልጋለሁ. ለማንኛውም ክር በማረም ላይ ብዙ ጊዜ ለመቆጠብ ይረዳኛል. ለእርስዎም ጠቃሚ እንደሚሆን ተስፋ አደርጋለሁ.

ምንጭ: hab.com

አስተያየት ያክሉ