كيف تقتل عمليات Zombie على Linux

نشرت: 2022-01-29
نافذة طرفية على كمبيوتر محمول يعمل بنظام Linux.
فاطماواتي أحمد زينوري / شاترستوك

يمكن للبرامج التي تتم كتابتها بشكل سيئ أو تؤدي أداءً سيئًا أن تترك عمليات الزومبي كامنة داخل جهاز كمبيوتر Linux الخاص بك. اكتشف كيف يتم إنشاء الزومبي ، وكيف يمكنك أخيرًا وضعها للراحة.

كيف تعمل الدول العملية على Linux

يجب أن يتتبع نظام Linux ، بالطبع ، جميع التطبيقات والعفاريت التي تعمل على جهاز الكمبيوتر الخاص بك. تتمثل إحدى طرق القيام بذلك في الحفاظ على جدول العملية. هذه قائمة الهياكل في ذاكرة النواة. كل عملية لها إدخال في هذه القائمة يحتوي على بعض المعلومات عنها.

لا يوجد قدر كبير في كل من هياكل جدول العملية. لديهم معرف العملية ، وبعض عناصر البيانات الأخرى ، ومؤشر كتلة التحكم في العملية (PCB) لتلك العملية.

إنه PCB الذي يحتوي على العديد من التفاصيل التي يحتاجها Linux للبحث عنها أو تعيينها لكل عملية. يتم تحديث ثنائي الفينيل متعدد الكلور أيضًا عند إنشاء عملية ، مع إعطاء وقت المعالجة ، وإتلافها أخيرًا.

يحتوي Linux PCB على أكثر من 95 حقلاً. يتم تعريفه على أنه بنية تسمى task_struct.h ، ويتجاوز طولها 700 سطر. يحتوي ثنائي الفينيل متعدد الكلور على الأنواع التالية من المعلومات:

  • حالة العملية : الحالات موضحة أدناه.
  • رقم العملية : معرفها الفريد داخل نظام التشغيل.
  • عداد البرنامج : عندما يتم منح هذه العملية الوصول إلى وحدة المعالجة المركزية في المرة التالية ، سيستخدم النظام هذا العنوان للعثور على التعليمات التالية للعملية التي يجب تنفيذها.
  • السجلات : قائمة مسجلات وحدة المعالجة المركزية التي تستخدمها هذه العملية. قد تحتوي القائمة على مجمّعات ومسجلات فهرس ومؤشرات مكدس.
  • قائمة الملفات المفتوحة : الملفات المرتبطة بهذه العملية.
  • معلومات جدولة وحدة المعالجة المركزية : تُستخدم لتحديد عدد المرات والمدة التي يتم فيها منح وقت معالجة وحدة المعالجة المركزية لهذه العملية. يجب تسجيل أولوية العملية ، ومؤشرات جدولة قوائم الانتظار ، ومعلمات الجدولة الأخرى في ثنائي الفينيل متعدد الكلور.
  • معلومات إدارة الذاكرة : تفاصيل حول الذاكرة التي تستخدمها هذه العملية ، مثل عناوين البداية والنهاية لذاكرة العملية ، والمؤشرات إلى صفحات الذاكرة.
  • معلومات حالة الإدخال / الإخراج : أي أجهزة إدخال أو إخراج مستخدمة في العملية.

يمكن أن تكون "حالة العملية" أيًا مما يلي:

  • R: عملية قيد التشغيل أو قابلة للتشغيل. التشغيل يعني تلقي دورات وحدة المعالجة المركزية وتنفيذها. عملية قابلة للتشغيل جاهزة للتشغيل وانتظار فتحة وحدة المعالجة المركزية.
  • S: عملية النوم. تنتظر العملية حتى يكتمل إجراء ما ، مثل عملية إدخال أو إخراج ، أو حتى يتوفر مورد.
  • د: العملية في حالة نوم غير متقطع. إنه يستخدم مكالمة نظام حظر ولا يمكنه المتابعة حتى تكتمل مكالمات النظام. على عكس حالة "السكون" ، لن تستجيب العملية في هذه الحالة للإشارات حتى تكتمل مكالمة النظام ويعود التنفيذ إلى العملية.
  • T: تم إنهاء (إيقاف) العملية لأنها تلقت إشارة SIGSTOP . سيستجيب فقط لإشارات SIGKILL أو SIGCONT ، والتي إما تقتل العملية أو تطلب منها الاستمرار ، على التوالي. هذا ما يحدث عند التبديل من مهام المقدمة ( fg ) إلى مهام الخلفية ( bg) .
  • Z: عملية الزومبي. عندما تكتمل العملية ، فإنها لا تختفي فقط. إنها تحرر أي ذاكرة تستخدمها وتزيل نفسها من الذاكرة ، ولكن يبقى إدخالها في جدول العملية وثنائي الفينيل متعدد الكلور. تم تعيين حالتها على EXIT_ZOMBIE ، ويتم إخطار عمليتها الأصلية (بواسطة إشارة SIGCHLD ) بأن العملية الفرعية قد انتهت.

الإعلانات

في حالة الزومبي ، تستدعي العملية الأصل إحدى مجموعات وظائف wait() عند إنشاء العملية الفرعية. ثم ينتظر تغيير الحالة في عملية الطفل. هل تم إيقاف عملية الطفل أو استمرارها أو قتلها بإشارة؟ هل تم إنهاؤه بالمرور عبر الإكمال الطبيعي لشفرته؟

إذا كان تغيير الحالة هو التغيير الذي يعني أن العملية الفرعية قد توقفت عن العمل ، فسيتم قراءة رمز الخروج الخاص بها. بعد ذلك ، يتم إتلاف ثنائي الفينيل متعدد الكلور الخاص بالطفل وإزالة إدخاله في جدول العملية. من الناحية المثالية ، يحدث كل هذا في غمضة عين ، والعمليات في حالة الزومبي لا توجد لفترة طويلة جدًا.

ذات صلة: كيفية تشغيل والتحكم في عمليات الخلفية على Linux

ما الذي يسبب عمليات Zombie على Linux؟

قد لا تستدعي عملية الأصل المكتوبة بشكل سيئ وظيفة wait() عند إنشاء العملية الفرعية. هذا يعني أنه لا يوجد شيء يراقب تغيرات الحالة في عملية الطفل ، وسيتم تجاهل إشارة SIGCHLD . أو ، ربما يكون هناك تطبيق آخر يؤثر على تنفيذ العملية الأصلية ، إما بسبب البرمجة السيئة أو النية الخبيثة.

ومع ذلك ، إذا كانت العملية الأبوية لا تراقب تغيرات الحالة في عملية الطفل ، فلن تحدث التدبير المنزلي المناسب للنظام. لن تتم إزالة ثنائي الفينيل متعدد الكلور والإدخال في جدول العملية عند إنهاء العملية الفرعية. ينتج عن هذا عدم إزالة حالة الزومبي أبدًا من ثنائي الفينيل متعدد الكلور.

تستخدم الزومبي القليل من الذاكرة ، لكنها لا تمثل مشكلة في العادة. الإدخال في جدول العملية صغير ، ولكن حتى إصداره ، لا يمكن إعادة استخدام معرّف العملية. في نظام تشغيل 64 بت ، من غير المحتمل أن يسبب أي مشاكل لأن PCB أكبر بكثير من إدخال جدول العملية.

يمكن أن يؤثر عدد كبير من الزومبي على مقدار الذاكرة الخالية للعمليات الأخرى. إذا كان لديك هذا العدد الكبير من الزومبي ، فستواجه مشكلة خطيرة في التطبيق الأبوي أو خطأ في نظام التشغيل.

كيفية إزالة عمليات الزومبي

لا يمكنك قتل عملية الزومبي لأنها ميتة بالفعل. لن يستجيب لأي إشارات لأنه تمت إزالته من الذاكرة - لا يوجد مكان لإرسال إشارة SIGKILL . يمكنك محاولة إرسال إشارة SIGCHLD إلى العملية الأم ، ولكن إذا لم تنجح عند إنهاء العملية الفرعية ، فمن غير المرجح أن تعمل الآن أيضًا.

الإعلانات

الحل الوحيد الموثوق به هو قتل عملية الوالدين. عند إنهائه ، يتم توارث عملياته الفرعية بواسطة عملية init ، وهي أول عملية يتم تشغيلها في نظام Linux (معرّف العملية الخاص به هو 1).

تقوم عملية init بانتظام بإجراء التنظيف الضروري للزومبي ، لذا لقتلهم ، عليك فقط قتل العملية التي خلقتهم. يعد الأمر top طريقة ملائمة لمعرفة ما إذا كان لديك أي كائنات زومبي.

اكتب ما يلي:

 أعلى 

يحتوي هذا النظام على ثماني عمليات زومبي. يمكننا سردها باستخدام الأمر ps وتوجيهها إلى egrep . مرة أخرى ، عمليات الزومبي لها علم حالة "Z" ، وعادةً ما ترى أيضًا "منتهي".

اكتب ما يلي:

 ps aux | egrep "Z | توقّف نشاطه" 

يتم سرد عمليات الزومبي.

هذه طريقة أكثر إتقانًا لاكتشاف معرّفات عمليات الزومبي بدلاً من التمرير ذهابًا وإيابًا من خلال top . نرى أيضًا أن تطبيقًا يسمى "badprg" أنتج هؤلاء الزومبي.

معرّف العملية لأول زومبي هو 7641 ، لكننا نحتاج إلى إيجاد معرّف العملية للعملية الأصلية. يمكننا القيام بذلك عن طريق استخدام ps مرة أخرى. سنستخدم خيار الإخراج ( -o ) لإخبار ps بعرض معرف العملية الخاص بالوالد فقط ، ثم تمريره ppid= .

الإعلانات

ستتم الإشارة إلى العملية التي نريد العثور عليها باستخدام الخيار -p (العملية) ، ثم تمرير معرف عملية الزومبي.

لذلك ، نكتب الأمر التالي للبحث عن معلومات العملية للعملية 7641 ، ولكنها ستبلغ فقط معرّف العملية الأم:

 ps -o ppid = -p 7641 

أخبرنا أن معرف العملية الأصل هو 7636. يمكننا الآن الإسناد الترافقي لهذا باستخدام ps مرة أخرى.

نرى أن هذا يطابق اسم العملية الأصلية من وقت سابق. لقتل العملية الأبوية ، استخدم خيار SIGKILL مع أمر القتل كما يلي:

 7636

اعتمادًا على مالك العملية الأبوية ، قد تحتاج أيضًا إلى استخدام sudo .

الزومبي ليسوا مخيفين ...

... إلا إذا كانوا في حشد ضخم. القليل منها لا يدعو للقلق وستؤدي إعادة التشغيل البسيطة إلى القضاء عليهم.

الإعلانات

ومع ذلك ، إذا لاحظت أن تطبيقًا أو عملية تؤدي دائمًا إلى إنتاج كائنات الزومبي ، فهذا شيء يجب أن تبحث فيه. من المحتمل أن يكون مجرد برنامج مكتوب بطريقة قذرة ، وفي هذه الحالة ، ربما يكون هناك إصدار محدث يتم تنظيفه بشكل صحيح بعد عملياته الفرعية.