د سټریس سره د سافټویر ډیبګ کول

د سټریس سره د سافټویر ډیبګ کول

زما د ورځې دنده اکثرا د سافټویر ګمارنه ده، پدې معنی چې زه د پوښتنو ځوابولو لپاره ډیر وخت تیروم لکه:

  • دا سافټویر د پراختیا کونکي لپاره کار کوي، مګر زما لپاره نه. ولې؟
  • پرون دا سافټویر زما لپاره کار کاوه، مګر نن دا نه کوي. ولې؟

دا د ډیبګ کولو یو ډول دی چې د منظم سافټویر ډیبګ کولو څخه یو څه توپیر لري. منظم ډیبګ کول د کوډ په منطق پورې اړه لري، مګر د ځای پرځای کول د کوډ او چاپیریال ترمنځ د تعامل په اړه دي. حتی که د ستونزې ریښه یوه منطقي تېروتنه وي، دا حقیقت چې هر څه په یو ماشین کې کار کوي او په بل کې نه دا پدې مانا ده چې ستونزه یو څه په چاپیریال کې ده.

نو د معمول ډیبګ کولو وسیلو پرځای لکه gdb زه د ډیبګ کولو ګمارلو لپاره د وسیلو مختلف سیټ لرم. او د ستونزې سره د معاملې لپاره زما غوره وسیله لکه "ولې دا سافټویر زما لپاره کار نه کوي؟" بلل شوی پارچه.

سټریس څه شی دی؟

پارچه د "سیسټم کال تعقیب" لپاره وسیله ده. دا په اصل کې د لینکس لپاره رامینځته شوی و ، مګر ورته د ډیبګ کولو چلونه د نورو سیسټمونو لپاره وسیلو سره ترسره کیدی شي (ټيټراس او یا 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 په څیر یو څه دی. یو وخت، سافټویر هغه هارډویر ته مستقیم لاسرسی درلود چې دا یې پرمخ وړي. که ، د مثال په توګه ، دا په سکرین کې یو څه ښودلو ته اړتیا لري ، دا د ویډیو وسیلو لپاره د بندرونو یا حافظې نقشه شوي راجسټرونو سره لوبیدلی. کله چې د ملټي ټاسک کولو کمپیوټر سیسټمونه مشهور شول، ګډوډي واکمنه شوه ځکه چې د هارډویر په اړه مختلف غوښتنلیکونه جنګیدل. په یوه غوښتنلیک کې تېروتنې کولی شي نور راټیټ کړي، که نه ټول سیسټم. بیا د امتیاز حالت (یا "د حلقوي محافظت") په CPU کې څرګند شو. کرنل خورا امتیاز ترلاسه کړ: دې هارډویر ته بشپړ لاسرسی ترلاسه کړ ، لږ امتیاز لرونکي غوښتنلیکونه رامینځته کول چې دمخه یې د سیسټم تلیفونونو له لارې هارډویر سره د تعامل لپاره د کرنل څخه د لاسرسي غوښتنه کړې وه.

په بائنری کچه، د سیسټم کال د ساده فنکشن کال څخه یو څه توپیر لري، مګر ډیری پروګرامونه په معیاري کتابتون کې یو ریپر کاروي. هغوی. د POSIX C معیاري کتابتون د فنکشن کال لري ولیکئ ()، کوم چې د سیسټم کال لپاره ټول معمارۍ ځانګړي کوډ لري ولیکي.

د سټریس سره د سافټویر ډیبګ کول

په لنډه توګه، د غوښتنلیک او د هغه چاپیریال (کمپیوټر سیسټمونو) ترمنځ هر ډول تعامل د سیسټم کالونو له لارې ترسره کیږي. له همدې امله، کله چې سافټویر په یو ماشین کار کوي مګر په بل کې نه، نو دا به ښه وي چې د سیسټم کال تعقیب پایلې وګورئ. په ځانګړې توګه، دلته د ځانګړو ټکو لیست دی چې د سیسټم کال ټریس په کارولو سره تحلیل کیدی شي:

  • کنسول I/O
  • شبکه I/O
  • د فایل سیسټم لاسرسی او فایل I/O
  • د پروسې تار د ژوند موده اداره کول
  • د ټیټې کچې حافظې مدیریت
  • د ځانګړو وسیلو چلوونکو ته لاسرسی

کله سټریس وکاروئ؟

په تیوري کې، پارچه د کارونکي ځای کې د هر برنامه سره کارول کیږي ، ځکه چې د کارونکي ځای کې هر برنامه باید سیسټم تلیفونونه وکړي. دا د تالیف شوي ، ټیټ کچې برنامو سره خورا مؤثره کار کوي ، مګر دا د Python په څیر د لوړې کچې ژبو سره هم کار کوي که تاسو کولی شئ د رن ټایم او ژباړونکي څخه اضافي شور کم کړئ.

په دې ټول شان کې پارچه د سافټویر د ډیبګ کولو پرمهال ځان څرګندوي چې په یوه ماشین کې ښه کار کوي، مګر ناڅاپه په بل ماشین کار کول ودروي، د فایلونو، اجازې، یا د ځینو حکمونو یا بل څه د اجرا کولو ناکامه هڅې په اړه مبهم پیغامونه تولیدوي ... دا د افسوس خبره ده، مګر دا نه کیږي. د لوړې کچې ستونزو لکه د سند تصدیق کولو غلطۍ سره خورا ښه ترکیب. معمولا دا ترکیب ته اړتیا لري پارچهځینې ​​وختونه ltrace او د لوړې کچې وسیلې (لکه د کمانډ لاین وسیله پرانيستی د سند ډیبګ کولو لپاره).

موږ به د مثال په توګه یو واحد سرور وکاروو، مګر د سیسټم کال تعقیب اکثرا په ډیرو پیچلو ګمارلو پلیټ فارمونو کې ترسره کیدی شي. تاسو یوازې اړتیا لرئ سم وسایل غوره کړئ.

د ډیبګ کولو ساده مثال

راځئ چې ووایو تاسو غواړئ د حیرانتیا سرور غوښتنلیک foo چل کړئ، او دا هغه څه دي چې تاسو یې پای ته رسوئ:

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

په ښکاره ډول دا نشي کولی د ترتیب کولو فایل ونه موندل شي چې تاسو یې لیکلي. دا پیښیږي ځکه چې کله ناکله کله چې د بسته بندۍ مدیران یو غوښتنلیک تالیف کوي ، دوی د متوقع فایل ځایونه له پامه غورځوي. او که تاسو د یوې توزیع لپاره د نصب کولو لارښود تعقیب کړئ ، په بل کې تاسو فایلونه له هغه ځای څخه په بشپړ ډول توپیر ومومئ چیرې چې تاسو تمه درلوده. ستونزه په څو ثانیو کې حل کیدی شي که چیرې د خطا پیغام وویل چې چیرې د تنظیم کولو فایل ته ګورئ ، مګر دا نده. نو چیرته وګورو؟

که تاسو سرچینې کوډ ته لاسرسی لرئ، تاسو کولی شئ هغه ولولئ او هرڅه ومومئ. یو ښه بیک اپ پلان ، مګر ترټولو ګړندی حل ندی. تاسو کولی شئ د ګام په ګام ډیبګر ته لاره هواره کړئ لکه gdb او وګورئ چې برنامه څه کوي، مګر دا د یوې وسیلې کارول خورا اغیزمن دي چې په ځانګړي ډول د چاپیریال سره د تعامل ښودلو لپاره ډیزاین شوي: پارچه.

پایلې پارچه کیدای شي بې ځایه ښکاري، مګر ښه خبر دا دی چې ډیری یې په خوندي توګه له پامه غورځول کیدی شي. دا ډیری وختونه ګټور دي چې د -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, mpprotect, برک د شیانو لپاره لکه د ټیټې کچې حافظې کشف کول او د متحرک کتابتونونو ښودل.) په حقیقت کې د محصول د ډیبګ کولو پرمهال پارچه دا غوره ده چې له پای څخه ولولئ. لاندې به یوه ننګونه وي ولیکي، کوم چې د خطا پیغام ښیې. موږ پورته ګورو او لومړی غلط سیسټم کال - کال ګورو خلاص، کوم چې تېروتنه کوي ENOENT ("دوتنه یا لارښود ونه موندل شو") د خلاصولو هڅه کوي /etc/foo/config.json. دا هغه ځای دی چې د ترتیب کولو فایل باید وي.

دا یوازې یو مثال و، مګر زه به ووایم چې 90٪ هغه وخت چې زه یې کاروم پارچه، د دې څخه ډیر څه کول خورا ستونزمن ندي. لاندې یو بشپړ ګام په ګام د ډیبګ کولو لارښود دی:

  • د برنامه څخه د سیسټم - y غلطۍ په اړه د مبهم پیغام له امله خپه شئ
  • سره برنامه بیا پیل کړئ پارچه
  • د ټریس پایلو کې د خطا پیغام ومومئ
  • لوړ ته لاړ شئ تر هغه چې تاسو د لومړي ناکام سیسټم زنګ ووهئ

دا خورا احتمال لري چې په 4 مرحله کې د سیسټم زنګ به څرګنده کړي چې څه غلط شوي.

اشارې

مخکې لدې چې تاسو ته د ډیر پیچلي ډیبګ کولو مثال وښیم ، زه به تاسو ته د مؤثره کارونې لپاره یو څو چلونه وښیم پارچه:

سړی ستاسو ملګری دی

په ډیری * نکس سیسټمونو کې، د کرنل ته د سیسټم زنګونو بشپړ لیست په چلولو سره ترلاسه کیدی شي سړی سیسکال کوي. تاسو به داسې شیان وګورئ لکه brk(2)، پدې معنی چې نور معلومات د چلولو له لارې ترلاسه کیدی شي سړی 2 brk.

کوچنی ریک: سړی 2 فورک ماته د شیل لپاره پاڼه ښیې فورک () в GNU libc، کوم چې دا معلومه شوه چې د زنګ وهلو په واسطه پلي کیږي کلون(). سیمانټیک غږ کړئ رنګ همداسې پاتې کیږي که تاسو په کارولو سره یو برنامه ولیکئ فورک ()، او ټریس چل کړئ - زه به هیڅ تلیفون ونه موندلم رنګد دوی پرځای به وي کلون(). دا ډول ریکونه یوازې تاسو مغشوشوي که تاسو د محصول سره سرچینې پرتله کول پیل کړئ پارچه.

په فایل کې د محصول خوندي کولو لپاره -o وکاروئ

پارچه کولی شي پراخه محصول تولید کړي، نو دا ډیری وختونه ګټور دي چې د ټریس پایلې په جلا فایلونو کې ذخیره کړئ (لکه څنګه چې پورته مثال کې). دا هم مرسته کوي چې د برنامه تولید سره د ګډوډۍ مخه ونیسي پارچه په کنسول کې.

د نورو دلیلونو ډیټا لیدو لپاره -s وکاروئ

تاسو شاید لیدلي وي چې د غلطۍ پیغام دویمه نیمه د پورته مثال ټریس کې نه ښودل شوې. دا ځکه پارچه ډیفالټ یوازې د تار دلیل لومړی 32 بایټونه ښیې. که تاسو غواړئ نور وګورئ، یو څه اضافه کړئ لکه - 128 زنګ ته پارچه.

-y د فایلونو ، ساکټونو او نورو تعقیب اسانه کوي.

"ټول فایل دی" معنی دا ده چې * نکس سیسټم ټول I/O د فایل ډیسکریپټرونو په کارولو سره ترسره کوي ، که دا په فایل یا شبکه یا د انټر پروسس پایپونو باندې پلي کیږي. دا د پروګرام کولو لپاره مناسب دی، مګر دا ستونزمن کوي ​​​​چې د هغه څه تعقیب وساتي چې واقعا څه پیښیږي کله چې تاسو عام وګورئ پاتې برخه и ولیکي په سیسټم کې د کال ټریس پایلې.

د یو آپریټر اضافه کولو سره -هو، تاسو به مجبور کړئ پارچه په محصول کې د هر فایل تشریح کونکي ته د هغه یادښت سره تشریح کړئ چې دا ورته اشاره کوي.

د -p** سره دمخه روان پروسې سره ضمیمه کړئ

لکه څنګه چې تاسو به د لاندې مثال څخه وګورئ، ځینې وختونه تاسو اړتیا لرئ یو برنامه تعقیب کړئ چې دمخه روان وي. که دا معلومه شي چې دا د پروسې 1337 په توګه پرمخ ځي (ووایه، د محصول څخه ps)، بیا تاسو کولی شئ دا په لاندې ډول تعقیب کړئ:

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

تاسو ممکن د ریښو حقونو ته اړتیا ولرئ.

د ماشومانو پروسې څارلو لپاره -f وکاروئ

پارچه په ډیفالټ کې، دا یوازې یوه پروسه تعقیبوي. که دا پروسه د ماشوم پروسې رامینځته کړي، نو د ماشوم پروسې سپون کولو لپاره د سیسټم کال لیدل کیدی شي، مګر د ماشوم پروسې سیسټم کالونه به نه ښکاره شي.

که تاسو فکر کوئ چې تېروتنه د ماشوم په پروسه کې ده، بیان وکاروئ -f، دا به د هغې تعقیب وړ کړي. د دې منفي اړخ دا دی چې محصول به تاسو نور هم مغشوش کړي. كله پارچه یوه پروسه یا یوه تار تعقیبوي، دا د کال پیښو یو واحد جریان ښیې. کله چې دا په یوځل کې ډیری پروسې تعقیبوي ، تاسو ممکن د پیغام لخوا مداخله شوي تلیفون پیل وګورئ ، بیا - د نورو اعدام څانګو لپاره د زنګونو یوه ډله ، او یوازې بیا - د لومړي پای پای <…فوکل بیا پیل شو>. یا ټولې ټریس پایلې په مختلف فایلونو ویشئ، د آپریټر په کارولو سره -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
...

هوریستیکونه لکه "د تېروتنې راپور ورکولو دمخه وروستۍ ناکامه غوښتنه" د اړونده غلطیو موندلو کې ښه دي. لکه څنګه چې کیدی شي، دا منطقي ده چې له پای څخه پیل شي.

د C پروګرام کولو درسونه کولی شي تاسو سره د سیسټم تلیفونونو په پوهیدو کې مرسته وکړي.

د C کتابتونونو ته معیاري زنګونه د سیسټم زنګونه ندي، مګر یوازې یو پتلی سطحه پرت دی. نو، که تاسو لږ تر لږه پوه شئ چې څنګه او په C کې څه وکړي، نو دا به ستاسو لپاره د سیسټم کال ټریس پایلو پوهیدل اسانه وي. د مثال په توګه، تاسو د شبکې سیسټمونو ته د تلیفونونو ډیبګ کولو ستونزه لرئ، ورته کلاسیک وګورئ د شبکې برنامه کولو لپاره د بیجا لارښود.

یو ډیر پیچلي ډیبګ کولو مثال

ما دمخه وویل چې د ساده ډیبګ کولو مثال د هغه څه مثال دی چې زه یې د کار کولو پرمهال ورسره معامله کوم پارچه. په هرصورت، ځینې وختونه ریښتینې څیړنې ته اړتیا وي، نو دلته د ډیرو پرمختللو ډیبګ کولو ریښتینې ژوند مثال دی.

bcron - د کاري پروسس کولو مهالویش ، د * نکس ډیمون بل پلي کول cron. دا په سرور کې نصب شوی، مګر کله چې یو څوک د مهال ویش ایډیټ کولو هڅه کوي، دا هغه څه دي چې پیښیږي:

# 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) د فایل توضیح کونکی دی ، کوم چې *nix د ټولو I/O پروسس کولو لپاره کاروي. زه څنګه ومومئ چې د فایل ډیسکریپټر 3 استازیتوب کوي؟ په دې ځانګړي حالت کې، تاسو کولی شئ چل کړئ پارچه د آپریټر سره -هو (پورته وګورئ) او دا به په اوتومات ډول تاسو ته ووایی، مګر د دې په څیر شیان معلومولو لپاره، دا ګټوره ده چې پوه شئ چې څنګه د ټریس پایلې لوستل او تحلیل کړئ.

د فایل توضیح کونکي سرچینه کیدی شي د ډیری سیسټم تلیفونونو څخه یو وي (دا ټول پدې پورې اړه لري چې تشریح کونکی د څه لپاره دی - کنسول ، د شبکې ساکټ ، پخپله فایل ، یا بل څه) ، مګر که دا وي ، موږ یې په لټه کې یو. د 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د پروسس ID 20629 سره روان دی.

د ورته معلوماتو موندلو لپاره دوهم واقعیا ګټور وسیله بلل کیږي 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 نه موندل کیدی شي.) دا سیسټم زنګ دی 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/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، نو زه به د کرنل پیغام لاګ وګورئ dmesg.)

ټول

د سیسټم زنګ نښې د پیل کونکي لپاره خورا لوی کیدی شي ، مګر زه امید لرم چې ما وښودله چې دا د عمومي ګمارلو ستونزو ټولې ټولګي ډیبګ کولو لپاره ګړندۍ لار ده. تصور وکړئ چې د څو پروسیس ډیبګ کولو هڅه وکړئ bcronد ګام په ګام ډیبګر کارول.

د سیسټم زنګونو سلسله شاته د ټریس پایلو تحلیل مهارت ته اړتیا لري ، مګر لکه څنګه چې ما وویل ، نږدې تل ، کارول پارچه، زه یوازې د ټریس پایله ترلاسه کوم او د پای څخه پیل شوي غلطیو ته ګورم. په هرصورت، پارچه زما سره مرسته کوي په ډیبګ کولو کې ډیر وخت خوندي کړم. زه امید لرم چې دا به ستاسو لپاره هم ګټور وي.

سرچینه: www.habr.com

Add a comment