اسٽريس سان ڊيبگنگ سافٽ ويئر جي جوڙجڪ

اسٽريس سان ڊيبگنگ سافٽ ويئر جي جوڙجڪ

منهنجي ڏينهن جي نوڪري گهڻو ڪري سافٽ ويئر جي جوڙجڪ آهي، جنهن جو مطلب آهي ته آئون گهڻو وقت گذاريندو آهيان سوالن جا جواب ڏيڻ جي ڪوشش ڪندي جهڙوڪ:

  • هي سافٽ ويئر ڊولپر لاءِ ڪم ڪري ٿو، پر مون لاءِ نه. ڇو؟
  • ڪالهه هن سافٽ ويئر مون لاء ڪم ڪيو، پر اڄ اهو ناهي. ڇو؟

هي هڪ قسم جي ڊيبگنگ آهي جيڪا باقاعده سافٽ ويئر ڊيبگنگ کان ٿورو مختلف آهي. باقاعده ڊيبگنگ ڪوڊ جي منطق جي باري ۾ آهي، پر ڊيبگنگ ڊيبنگ ڪوڊ ۽ ماحول جي وچ ۾ رابطي جي باري ۾ آهي. جيتوڻيڪ مسئلي جي پاڙ هڪ منطقي غلطي آهي، حقيقت اها آهي ته هر شيء هڪ مشين تي ڪم ڪري ٿي ۽ ٻئي تي نه، مطلب ته مسئلو ڪنهن نه ڪنهن ماحول ۾ آهي.

تنهنڪري عام ڊيبگنگ اوزار جي بدران جي ڊي بي مون وٽ اوزارن جو هڪ مختلف سيٽ آهي ڊيبگنگ ڊيپلائيشن لاءِ. ۽ مسئلو حل ڪرڻ لاءِ منهنجو پسنديده اوزار جهڙوڪ ”هي سافٽ ويئر مون لاءِ ڪم ڇو نٿو ڪري؟ سڏيو ڀا .و.

اسٽريس ڇا آهي؟

ڀا .و "سسٽم ڪال ٽريڪنگ" لاءِ هڪ اوزار آهي. اهو اصل ۾ لينڪس لاءِ ٺاهيو ويو هو، پر ساڳي ڊيبگنگ ٽرڪن کي ٻين سسٽم لاءِ اوزارن سان ڪري سگهجي ٿو (ڊي ٽريس يا 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 +++

اهي سسٽم ڪالون ڇا آهن؟ هي آپريٽنگ سسٽم ڪنيل لاءِ هڪ API وانگر آهي. هڪ دفعي هڪ دفعي، سافٽ ويئر جي هارڊويئر تائين سڌو رسائي هئي ان تي هلندو هو. جيڪڏهن، مثال طور، ان کي اسڪرين تي ڪجهه ڊسپلي ڪرڻ جي ضرورت آهي، اهو ويڊيو ڊوائيسز لاء بندرگاهن يا ميموري ميپ ٿيل رجسٽر سان ادا ڪيو. جڏهن ملٽي ٽاسڪنگ ڪمپيوٽر سسٽم مشهور ٿي ويا، افراتفري حڪمراني ڪئي جيئن مختلف ايپليڪيشنون هارڊويئر تي وڙهندا. ھڪڙي ايپليڪيشن ۾ نقص ٻين کي ھيٺ آڻي سگھي ٿو، جيڪڏھن نه سڄي سسٽم. پوءِ استحقاق جا طريقا (يا ”رنگ تحفظ“) سي پي يو ۾ ظاهر ٿيا. ڪرنل سڀ کان وڌيڪ مراعات يافته بڻجي ويو: هن هارڊويئر تائين مڪمل رسائي حاصل ڪئي، گهٽ امتيازي ايپليڪيشنون پيدا ڪيون جيڪي اڳ ۾ ئي سسٽم ڪالن ذريعي هارڊويئر سان رابطو ڪرڻ لاء ڪرنل کان رسائي جي درخواست ڪن ٿيون.

بائنري سطح تي، هڪ سسٽم ڪال هڪ سادي فنڪشن ڪال کان ٿورو مختلف آهي، پر اڪثر پروگرام معياري لائبريري ۾ هڪ لفافي استعمال ڪندا آهن. اهي. POSIX C معياري لائبريري هڪ فنڪشن ڪال تي مشتمل آهي لکو ()، جنهن ۾ سسٽم ڪال لاءِ سڀني آرڪيٽيڪچر-مخصوص ڪوڊ شامل آهن لکڻ.

اسٽريس سان ڊيبگنگ سافٽ ويئر جي جوڙجڪ

مختصر ۾، ايپليڪيشن ۽ ان جي ماحول جي وچ ۾ ڪو به رابطو (ڪمپيوٽر سسٽم) سسٽم ڪالن ذريعي ڪيو ويندو آهي. تنهن ڪري، جڏهن سافٽ ويئر هڪ مشين تي ڪم ڪري ٿو پر ٻئي تي نه، اهو سسٽم ڪال ٽريڪنگ نتيجن کي ڏسڻ لاء سٺو هوندو. وڌيڪ خاص طور تي، هتي عام پوائنٽن جي هڪ فهرست آهي جيڪو تجزيو ڪري سگهجي ٿو سسٽم ڪال ٽريس استعمال ڪندي:

  • ڪنسول I/O
  • نيٽ ورڪ I/O
  • فائل سسٽم تائين رسائي ۽ فائل I/O
  • ھڪڙي عمل واري سلسلي جي زندگي گذارڻ جو انتظام
  • گھٽ-سطح ياداشت جو انتظام
  • مخصوص ڊوائيس ڊرائيور تائين رسائي

جڏهن اسٽريس استعمال ڪرڻ لاء؟

نظريي ۾، ڀا .و يوزر اسپيس ۾ ڪنهن به پروگرام سان استعمال ڪيو ويو آهي، ڇاڪاڻ ته صارف جي جاء تي ڪنهن به پروگرام کي سسٽم ڪال ڪرڻ گهرجي. اهو مرتب ڪيل، گهٽ-سطح جي پروگرامن سان وڌيڪ ڪارائتو ڪم ڪري ٿو، پر اهو پڻ اعليٰ سطحي ٻولين جهڙوڪ پٿون سان ڪم ڪري ٿو، جيڪڏهن توهان رن ٽائم ۽ مترجم کان اضافي شور کي ختم ڪري سگهو ٿا.

ان جي تمام جلال ۾ ڀا .و سافٽ ويئر جي ڊيبگنگ دوران پاڻ کي ظاهر ڪري ٿو جيڪو هڪ مشين تي سٺو ڪم ڪري ٿو، پر اوچتو ٻئي تي ڪم ڪرڻ بند ڪري ٿو، فائلن، اجازتن، يا ڪجهه حڪمن تي عمل ڪرڻ جي ناڪام ڪوششن بابت غير واضح پيغام پيدا ڪرڻ يا ٻيو ڪجهه ... اهو افسوس جي ڳالهه آهي، پر اهو ناهي. اعليٰ سطحي مسئلن جهڙوڪ سرٽيفڪيٽ جي تصديق جي غلطين سان گڏ گڏوگڏ. عام طور تي اهو هڪ ميلاپ جي ضرورت آهي ڀا .وڪڏهن ltrace ۽ اعليٰ سطح جا اوزار (جهڙوڪ ڪمانڊ لائن ٽول کليل سرٽيفڪيٽ کي ڊيبگ ڪرڻ لاء).

اسان مثال طور هڪ اسٽائل سرور استعمال ڪنداسين، پر سسٽم ڪال ٽريڪنگ اڪثر ڪري سگهجي ٿو وڌيڪ پيچيده ڊيپلائيمينٽ پليٽ فارمن تي. توهان کي صرف صحيح اوزار چونڊڻ جي ضرورت آهي.

سادي ڊيبگنگ مثال

اچو ته چوندا آھيو توھان کي هلائڻ چاھيو ٿا شاندار سرور ايپليڪيشن foo، ۽ اھو اھو آھي جيڪو توھان ختم ڪيو:

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

بظاهر اهو ڳولي نه سگهيو آهي ترتيب واري فائيل جيڪا توهان لکيو آهي. اهو ٿي سگهي ٿو ڇاڪاڻ ته ڪڏهن ڪڏهن جڏهن پيڪيج مينيجرز هڪ ايپليڪيشن کي گڏ ڪن ٿا، اهي متوقع فائل جي جڳهن کي ختم ڪن ٿا. ۽ جيڪڏهن توهان هڪ تقسيم لاءِ انسٽاليشن گائيڊ جي پيروي ڪريو ٿا، ٻئي ۾ توهان فائلون ڳوليندا آهيو مڪمل طور تي مختلف جتي توهان توقع ڪئي هئي. مسئلو ڪجهه سيڪنڊن ۾ حل ٿي سگهي ٿو جيڪڏهن غلطي پيغام ٻڌايو ته ترتيب واري فائل کي ڪٿي ڳولڻ لاء، پر اهو ناهي. پوء ڪٿي ڏسڻ لاء؟

جيڪڏهن توهان وٽ سورس ڪوڊ تائين رسائي آهي، توهان ان کي پڙهي سگهو ٿا ۽ سڀ ڪجهه ڳولي سگهو ٿا. هڪ سٺو بيڪ اپ منصوبو، پر تيز ترين حل ناهي. توهان هڪ قدم-جي-قدم debugger وانگر آسودو ڪري سگهو ٿا جي ڊي بي ۽ ڏسو ته پروگرام ڇا ڪندو آهي، پر اهو هڪ اوزار استعمال ڪرڻ تمام گهڻو اثرائتو آهي جيڪو خاص طور تي ماحول سان رابطي کي ڏيکارڻ لاءِ ٺهيل آهي: ڀا .و.

ٿڪل ڀا .و بيڪار لڳي سگھي ٿو، پر سٺي خبر اها آهي ته ان مان گھڻا محفوظ طور تي نظر انداز ڪري سگھجن ٿا. اهو اڪثر ڪري استعمال ڪرڻ لاء مفيد آهي -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, mprotect, ڪوئل شين لاءِ جيئن گهٽ-سطح جي ميموري کي ڳولڻ ۽ متحرڪ لائبريريون ڏيکارڻ.) دراصل، آئوٽ پٽ کي ڊيبگ ڪرڻ دوران ڀا .و اهو بهتر آهي ته آخر کان پڙهو. اتي هيٺ هڪ چئلينج ٿيندو لکڻ، جيڪو هڪ غلطي پيغام ڏيکاري ٿو. اسان مٿي ڏسون ٿا ۽ پهريون غلط سسٽم ڪال ڏسو - ڪال کليل، جيڪو غلطي ڪري ٿو ENOENT ("فائل يا ڊاريڪٽري نه ملي") کولڻ جي ڪوشش ڪندي /etc/foo/config.json. ھي آھي جتي ٺاھڻ واري فائل ھجڻ گھرجي.

اهو صرف هڪ مثال هو، پر مان چوندس 90٪ وقت جو آئون استعمال ڪريان ٿو ڀا .وهن کان وڌيڪ ڏکيو ڪم ٻيو ڪجهه به ناهي. هيٺ هڪ مڪمل قدم قدم ڊيبگنگ گائيڊ آهي:

  • پروگرام مان سسٽم-y جي غلطي بابت هڪ مبهم پيغام جي ڪري پريشان ٿيو
  • سان پروگرام ٻيهر شروع ڪريو ڀا .و
  • ڳولھيو نقص پيغام جي نتيجن ۾
  • مٿي وڃو جيستائين توهان پهرين ناڪام سسٽم ڪال کي مارايو

اهو تمام گهڻو امڪان آهي ته سسٽم ڪال قدم 4 ۾ ظاهر ڪندو ته ڇا غلط ٿيو.

اشارو

توھان کي وڌيڪ پيچيده ڊيبگنگ جو ھڪڙو مثال ڏيکارڻ کان اڳ، مان توھان کي ڏيکاريندس ڪجھ ترڪيبون موثر استعمال لاءِ ڀا .و:

انسان توهان جو دوست آهي

ڪيترن ئي *نڪس سسٽم تي، سسٽم ڪالن جي مڪمل فهرست ڪنييل کي هلائڻ سان حاصل ڪري سگهجي ٿي انسان syscalls. توهان اهڙيون شيون ڏسندا برڪ (2)، جنهن جو مطلب آهي وڌيڪ معلومات هلائڻ سان حاصل ڪري سگهجي ٿي انسان 2 brk.

ننڍو ريڪ: انسان 2 ڪانٽو مون کي شيل لاء صفحو ڏيکاري ٿو ڪانٽو () в GNU libc، جيڪو، اهو نڪتو، ڪال ڪندي لاڳو ڪيو ويو آهي کلون (). سڏ سيمينٽڪس ڪٽڪ ساڳيو رهي ٿو جيڪڏهن توهان استعمال ڪندي هڪ پروگرام لکندا آهيو ڪانٽو (), and run a trace - مون کي ڪا به ڪال نه ملندي ڪٽڪ، ان جي بدران اتي هوندو کلون (). اهڙيون ريڪون صرف توهان کي پريشان ڪن ٿيون جيڪڏهن توهان پيداوار سان ذريعن جو مقابلو ڪرڻ شروع ڪيو ڀا .و.

آئوٽ کي فائل ۾ محفوظ ڪرڻ لاءِ -o استعمال ڪريو

ڀا .و وسيع پيداوار پيدا ڪري سگھن ٿا، تنهنڪري اهو اڪثر ڪري ڪارائتو آهي ته مختلف فائلن ۾ ٽريڪ نتيجن کي ذخيرو ڪرڻ لاء (جيئن مٿي ڏنل مثال ۾). هي پڻ مدد ڪري ٿو پريشان ٿيڻ کان بچڻ لاءِ پروگرام آئوٽ پٽ سان ڀا .و ڪنسول ۾.

استعمال ڪريو -s وڌيڪ دليل ڊيٽا ڏسڻ لاء

توهان شايد محسوس ڪيو هوندو ته غلطي پيغام جو ٻيو اڌ مٿي ڏنل مثال ۾ نه ڏيکاريل آهي. ان ڪري آهي ڀا .و ڊفالٽ صرف اسٽرنگ دليل جي پهرين 32 بائيٽ ڏيکاري ٿو. جيڪڏھن توھان وڌيڪ ڏسڻ چاھيو ٿا، ڪجھ شامل ڪريو جھڙوڪ -اس ايڪسڪسڪس سڏ ڏانهن ڀا .و.

-y فائلن، ساکٽس وغيره کي ٽريڪ ڪرڻ آسان بڻائي ٿو.

"سڀ فائل آهي" مطلب ته * نڪس سسٽم سڀ I/O ڪندا آهن فائل ڊسڪٽر استعمال ڪندي، ڇا اهو فائل يا نيٽ ورڪ يا انٽرپروسيس پائپ تي لاڳو ٿئي ٿو. اهو پروگرامنگ لاءِ آسان آهي، پر ان کي ٽريڪ ڪرڻ ڏکيو بڻائي ٿو ته واقعي ڇا ٿي رهيو آهي جڏهن توهان عام ڏسندا آهيو پڙهڻ и لکڻ سسٽم ڪال ٽريس نتيجن ۾.

هڪ آپريٽر شامل ڪندي ، توهان مجبور ڪندا ڀا .و ھر ھڪڙي فائل جي وضاحت ڪندڙ کي ٻاھر ۾ ھڪڙي نوٽ سان بيان ڪريو جيڪو اھو اشارو ڪري ٿو.

-p** سان اڳ ۾ ئي هلندڙ عمل سان ڳنڍيو

جيئن توهان هيٺ ڏنل مثال مان ڏسندا، ڪڏهن ڪڏهن توهان کي هڪ پروگرام جو پتو لڳائڻ جي ضرورت آهي جيڪو اڳ ۾ ئي هلندڙ آهي. جيڪڏهن اهو معلوم ٿئي ٿو ته اهو عمل 1337 جي طور تي هلندو آهي (چئو، ٻاڦ مان ps)، پوء توھان ان کي ھن طرح ڳولي سگھو ٿا:

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

توھان کي شايد روٽ حقن جي ضرورت آھي.

استعمال ڪريو -f ٻار جي عمل جي نگراني ڪرڻ لاء

ڀا .و ڊفالٽ طور، اهو صرف هڪ عمل کي ڇڪيندو آهي. جيڪڏهن اهو عمل چائلڊ پروسيس کي اسپن ڪري ٿو، ته پوءِ چائلڊ پروسيس کي سپون ڪرڻ لاءِ سسٽم ڪال ڏسي سگهجي ٿو، پر چائلڊ پروسيس جي سسٽم ڪالز کي ظاهر نه ڪيو ويندو.

جيڪڏهن توهان سوچيو ته غلطي ٻار جي عمل ۾ آهي، بيان استعمال ڪريو -f، اهو ان جي ٽريڪنگ کي چالو ڪندو. هن جو نقصان اهو آهي ته پيداوار توهان کي اڃا به وڌيڪ پريشان ڪندو. جڏهن ڀا .و ھڪڙي عمل يا ھڪڙي سلسلي کي ڇڪيندو آھي، اھو ڏيکاري ٿو ھڪڙي وهڪرو ڪال واقعن جو. جڏهن اهو هڪ ئي وقت ۾ ڪيترن ئي عملن کي نشانو بڻائيندو آهي، توهان ڏسي سگهو ٿا ڪال جي شروعات هڪ پيغام ذريعي مداخلت ڪئي ، پوء - ٻين عملدرآمد شاخن لاء ڪالن جو هڪ گروپ، ۽ صرف پوء - پهرين جي آخر ۾ <…foocal resumed>. يا سڀني سراغ جا نتيجا مختلف فائلن ۾ ورهايو، پڻ آپريٽر استعمال ڪندي -ff (تفصيل ۾ قيادت تي ڀا .و).

استعمال ڪندي نشانن کي فلٽر ڪريو -e

جئين توهان ڏسي سگهو ٿا، سراغ جو نتيجو سڀني ممڪن سسٽم ڪالن جو حقيقي انبار آهي. جھنڊو -e توھان نشان کي فلٽر ڪري سگھو ٿا (ڏسو رهنمائي ڪندڙ تي ڀا .و). بنيادي فائدو اهو آهي ته فلٽر ٿيل ٽريس کي هلائڻ لاءِ مڪمل ٽريس ڪرڻ کان وڌيڪ تيز آهي ۽ پوءِ نڀاڳوتي. ايماندار ٿيڻ لاء، مون کي تقريبن هميشه پرواه ناهي.

سڀ غلطيون خراب نه آهن

ھڪڙو سادو ۽ عام مثال ھڪڙو پروگرام آھي ھڪڙي فائل کي ھڪڙي وقت ۾ ڪيترن ئي هنڌن تي ڳولي رھيا آھن، جھڙوڪ شيل ھڪڙي ڊاريڪٽري کي ڳولي رھيا آھن جنھن ۾ ھڪڙي قابل عمل فائل شامل آھي:

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

Heuristics جهڙوڪ "غلطي جي رپورٽ ڪرڻ کان اڳ آخري ناڪام درخواست" لاڳاپيل غلطيون ڳولڻ ۾ سٺو آهن. جيئن ته اهو ٿي سگهي ٿو، اهو منطقي آهي ته آخر کان شروع ڪرڻ.

سي پروگرامنگ سبق توهان کي سسٽم ڪالن کي سمجهڻ ۾ مدد ڪري سگھن ٿا.

سي لائبريرين کي معياري ڪالون سسٽم ڪالون نه آهن، پر صرف هڪ پتلي سطحي پرت. تنهن ڪري، جيڪڏهن توهان گهٽ ۾ گهٽ سمجهو ٿا ته سي ۾ ڪيئن ۽ ڇا ڪجي، اهو توهان لاء سسٽم ڪال ٽريس جي نتيجن کي سمجهڻ آسان ٿي ويندو. مثال طور، توهان کي نيٽ ورڪ سسٽم ڏانهن ڪال ڊيبگ ڪرڻ ۾ مشڪل آهي، ساڳئي کلاسک کي ڏسو نيٽ ورڪ پروگرامنگ لاءِ بيجا جي گائيڊ.

هڪ وڌيڪ پيچيده ڊيبگنگ مثال

مون اڳ ۾ ئي چيو آهي ته سادي ڊيبگنگ جو مثال هڪ مثال آهي جنهن سان ڪم ڪرڻ وقت مون کي گهڻو ڪري معاملو ڪرڻو پوندو ڀا .و. بهرحال، ڪڏهن ڪڏهن هڪ حقيقي تحقيق جي ضرورت هوندي آهي، تنهنڪري هتي وڌيڪ ترقي يافته ڊيبگنگ جو حقيقي زندگي مثال آهي.

bcron - ٽاسڪ پروسيسنگ شيڊولر، ٻيو عمل درآمد * نڪس ڊيمون کلون. اهو سرور تي نصب ٿيل آهي، پر جڏهن ڪو ماڻهو شيڊول کي تبديل ڪرڻ جي ڪوشش ڪري ٿو، اهو ئي ٿئي ٿو:

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

چڱو، ان جو مطلب bcron هڪ خاص فائل لکڻ جي ڪوشش ڪئي، پر اهو ڪم نه ڪيو، ۽ هو تسليم نه ڪندو ڇو. بي نقاب ڪرڻ ڀا .و:

# 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) هڪ فائيل بيان ڪندڙ آهي، جيڪو * نڪس سڀني I/O پروسيسنگ لاءِ استعمال ڪندو آهي. مان ڪيئن ڳولهي سگهان ٿو ته ڪهڙي فائل ڊسپيڪٽر 3 جي نمائندگي ڪري ٿي؟ هن خاص صورت ۾، توهان هلائي سگهو ٿا ڀا .و آپريٽر سان (مٿي ڏسو) ۽ اھو پاڻمرادو توھان کي ٻڌائيندو، پر ھن جھڙي شيءِ کي معلوم ڪرڻ لاءِ، اھو ڄاڻڻ مفيد آھي ته ڪيئن پڙھجي ۽ نتيجن کي پارس ڪجي.

فائل جي وضاحت ڪندڙ جو ذريعو ڪيترن ئي سسٽم ڪالن مان هڪ ٿي سگهي ٿو (اهو سڀ ان تي منحصر آهي ته وضاحت ڪندڙ ڇا لاءِ آهي - هڪ ڪنسول، هڪ نيٽ ورڪ ساڪٽ، فائل پاڻ، يا ٻيو ڪجهه)، پر جيئن ته اهو ٿي سگهي ٿو، اسان ڳولي رهيا آهيون. ڪالون 3 موٽڻ سان (يعني اسين ڳوليون ٿا "= 3" جي ڳولا جي نتيجن ۾). ھن نتيجي ۾ انھن مان 2 آھن: کليل تمام مٿي ۽ ساکٽ وچ ۾. کليل فائل کوليو پر بند(3) پوء ڏيکاريندو ته اهو ٻيهر بند ٿي ويندو. (ريڪ: فائل بيان ڪندڙ ٻيهر استعمال ڪري سگھجن ٿا جڏهن اهي کوليا ۽ بند ڪيا وڃن). سڏ ساکٽ() مناسب ڇو ته اهو آخري آهي پڙهو ()، ۽ اهو ظاهر ٿئي ٿو ته bcrontab هڪ ساکٽ ذريعي ڪجهه ڪم ڪري ٿو. ايندڙ لڪير ڏيکاري ٿو ته فائل بيان ڪندڙ سان لاڳاپيل آهي يونڪس ڊومين ساکٽ رستي ۾ /var/run/bcron-spool.

تنهن ڪري، اسان سان لاڳاپيل عمل ڳولڻ جي ضرورت آهي يونڪس ساکٽ ٻئي پاسي. ھن مقصد لاءِ ڪجھ صاف چالون آھن، جن مان ٻئي ڪارآمد آھن سرور جي ڊيبگنگ لاءِ. پهريون استعمال ڪرڻ آهي نٽسٽ يا نئون 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, پروسيس ID 20629 سان گڏ.

ساڳئي معلومات ڳولڻ لاء ٻيو واقعي مفيد اوزار سڏيو ويندو آهي لسٽ. اهو سسٽم تي سڀني کليل فائلن (يا فائل بيان ڪندڙ) لسٽ ڪري ٿو. يا توهان هڪ مخصوص فائل بابت معلومات حاصل ڪري سگهو ٿا:

# 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

(آخري قبول ڪريو() مڪمل نه ڪيو ويندو جڏهن tracing.) ٻيهر، بدقسمتي سان، هي نتيجو اهو نه آهي جيڪو اسان ڳولي رهيا آهيون. اسان ڪو به پيغام نه ڏسندا آهيون جيڪي 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 +++

(جيڪڏهن توهان گم ٿي ويا آهيو، توهان شايد منهنجي پوئين پوسٽ پڙهڻ چاهيندا بابت * نڪس پروسيس مينيجمينٽ ۽ شيل.) تنهن ڪري، سرور PID 20629 رستي تي فائل ٺاهڻ جي اجازت حاصل نه ڪئي. /var/sool/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 cron /var/spool/cron/tmp/ مجبور ڪندو bcron صحيح ڪم ڪرڻ. (جيڪڏهن اهو مسئلو نه هو، ته پوءِ ايندڙ سڀ کان وڌيڪ مشڪوڪ هڪ ڪنيل سيڪيورٽي ماڊل آهي جهڙوڪ SELinux يا AppArmor، تنهنڪري مان چيڪ ڪندس ڪرنل پيغام لاگ ان سان ڊيز.)

ڪل

سسٽم ڪال جا نشان هڪ شروعات ڪندڙ لاءِ زبردست ٿي سگهن ٿا، پر مون کي اميد آهي ته مون ڏيکاريو آهي ته اهي هڪ مڪمل ڪلاس کي ڊيبگ ڪرڻ لاءِ تڪڙو رستو آهن عام ڊيپلائيشن جي مسئلن کي. تصور ڪريو ھڪڙي گھڻن پروسيس کي ڊيبگ ڪرڻ جي ڪوشش ڪريو bcronقدم قدم ڊيبگر استعمال ڪندي.

سسٽم ڪال زنجير سان گڏ پوئتي موٽڻ جا نتيجا تجزيا ڪرڻ مهارت جي ضرورت آهي، پر جيئن مون چيو، تقريبا هميشه، استعمال ڪندي ڀا .و، مان صرف سراغ نتيجو حاصل ڪريان ٿو ۽ آخر کان شروع ٿيندڙ غلطيون ڳوليان ٿو. بهرحال، ڀا .و مون کي ڊيبگنگ تي گهڻو وقت بچائڻ ۾ مدد ڪري ٿي. مون کي اميد آهي ته اهو پڻ توهان لاء مفيد ٿيندو.

جو ذريعو: www.habr.com

تبصرو شامل ڪريو