كيفية تنفيذ محلل الكود الثابت في مشروع قديم دون تثبيط عزيمة الفريق

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

مقدمة

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

يقدم فريق PVS-Studio وجهة نظره حول هذا الموضوع. دعونا نلقي نظرة على كيفية ظهور مشكلة تنفيذ محلل الكود الثابت في المقام الأول، وكيفية التغلب على هذه المشكلة، وكيفية التخلص التدريجي من الديون الفنية دون ألم.

مشاكل

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

تنتج جميع المحللات الثابتة نتائج إيجابية كاذبة. هذه إحدى سمات منهجية تحليل الكود الثابت، ولا يمكن فعل أي شيء حيال ذلك. في الحالة العامة، هذه مشكلة غير قابلة للحل، كما تؤكد نظرية رايس [2]. لن تساعد خوارزميات التعلم الآلي أيضًا [3]. حتى لو كان الشخص لا يستطيع دائما معرفة ما إذا كان هذا الرمز أو ذاك خاطئا، فلا يجب أن تتوقع ذلك من البرنامج :).

لا تمثل الإيجابيات الكاذبة مشكلة إذا تم تكوين المحلل الثابت بالفعل:

  • تعطيل مجموعات القواعد غير ذات الصلة؛
  • تم تعطيل بعض التشخيصات غير ذات الصلة؛
  • إذا كنا نتحدث عن C أو C++، فسيتم ترميز وحدات الماكرو التي تحتوي على بنيات محددة تؤدي إلى ظهور تحذيرات غير مجدية في كل مكان يتم فيه استخدام وحدات الماكرو هذه؛
  • يتم وضع علامة على الوظائف الخاصة التي تؤدي إجراءات مشابهة لوظائف النظام (نظيرتها الخاصة com.memcpy أو printf) [4];
  • يتم تعطيل الإيجابيات الكاذبة على وجه التحديد باستخدام التعليقات؛
  • وهلم جرا.

في هذه الحالة، يمكننا أن نتوقع معدل إيجابي كاذب منخفض يبلغ حوالي 10-15٪ [5]. بمعنى آخر، 9 من أصل 10 تحذيرات للمحلل ستشير إلى وجود مشكلة حقيقية في الكود، أو على الأقل "كود ذو رائحة قوية". موافق، هذا السيناريو ممتع للغاية، والمحلل صديق حقيقي للمبرمج.

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

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

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

ينظر المبرمجون، انظروا، انظروا إلى كل هذه التحذيرات حول كود العمل القديم. وهم يعتقدون: يمكننا الاستغناء عن التحليل الثابت. دعنا نذهب لكتابة بعض الوظائف المفيدة الجديدة.

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

هذا هو نفس التشبيه كما هو الحال مع تحذيرات المترجم. ليس من قبيل الصدفة أنهم يوصون بالحفاظ على عدد تحذيرات المترجم عند 0. إذا كان هناك 1000 تحذير، فعندما يكون هناك 1001، لن ينتبه إليها أحد، وليس من الواضح مكان البحث عن هذا التحذير الأحدث.

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

تنفيذ وإلغاء الديون الفنية

في الواقع، لا يوجد شيء صعب أو مخيف في إدخال التحليل الثابت حتى في مشروع قديم كبير.

CI / CD

علاوة على ذلك، يمكن جعل المحلل على الفور جزءًا من عملية التطوير المستمر. على سبيل المثال، يحتوي توزيع PVS-Studio على أدوات مساعدة لعرض التقرير بشكل ملائم بالتنسيق الذي تحتاجه، وإخطارات للمطورين الذين كتبوا أقسامًا إشكالية من التعليمات البرمجية. بالنسبة لأولئك الذين يهتمون أكثر بإطلاق PVS-Studio من أنظمة CI/CD، أوصي بأن تتعرف على ما يقابلها قسم التوثيق وسلسلة المقالات:

لكن دعنا نعود إلى مسألة وجود عدد كبير من النتائج الإيجابية الخاطئة في المراحل الأولى من تنفيذ أدوات تحليل الكود.

إصلاح الديون الفنية الموجودة والتعامل مع التحذيرات الجديدة

تسمح لك أدوات التحليل الثابتة التجارية الحديثة بدراسة التحذيرات الجديدة فقط التي تظهر في التعليمات البرمجية الجديدة أو المتغيرة. ويختلف تنفيذ هذه الآلية، ولكن الجوهر واحد. في المحلل الثابت PVS-Studio، يتم تنفيذ هذه الوظيفة على النحو التالي.

للبدء بسرعة في استخدام التحليل الثابت، نقترح على مستخدمي PVS-Studio استخدام آلية القمع الجماعي للتحذيرات [6]. الفكرة العامة هي التالية. قام المستخدم بتشغيل المحلل وتلقى العديد من التحذيرات. نظرًا لأن المشروع الذي كان قيد التطوير لسنوات عديدة لا يزال على قيد الحياة ويتطور ويكسب المال، فمن المرجح ألا يكون هناك الكثير من التحذيرات في التقرير تشير إلى العيوب الجسيمة. بمعنى آخر، تم بالفعل إصلاح الأخطاء الحرجة بطريقة أو بأخرى باستخدام أساليب أكثر تكلفة أو بفضل تعليقات العملاء. وبناء على ذلك، فإن كل ما يجده المحلل حاليا يمكن اعتباره دينا فنيا، وهو أمر غير عملي لمحاولة التخلص منه على الفور.

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

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

لذلك، تم حل المشكلة الأولى في تنفيذ المحلل في مشروع قديم كبير. الآن دعونا نتعرف على ما يجب فعله بالديون الفنية.

إصلاحات الأخطاء وإعادة البناء

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

if (a = b)

يشكو معظم مترجمي ومحللي لغة C++ من مثل هذه التعليمات البرمجية، نظرًا لوجود احتمال كبير بأنهم يريدون كتابتها بالفعل (أ == ب). ولكن هناك اتفاق غير معلن، وهذا عادة ما يُلاحظ في الوثائق، أنه إذا كانت هناك أقواس إضافية، فيُعتبر أن المبرمج قد كتب مثل هذا الرمز عمدًا، ولا داعي للقسم. على سبيل المثال، في وثائق PVS-Studio للتشخيص V559 (CWE-481) من الواضح أن السطر التالي سيعتبر صحيحًا وآمنًا:

if ((a = b))

مثال آخر. هل تم نسيانه في رمز C++ هذا؟ استراحة ام لا

case A:
  foo();
case B:
  bar();
  break;

سيصدر محلل PVS-Studio تحذيرًا هنا V796 (CWE-484). قد لا يكون هذا خطأ، وفي هذه الحالة يجب عليك إعطاء المحلل تلميحًا عن طريق إضافة السمة [[وقع خلال]] أو على سبيل المثال __السمة__((السقوط)):

case A:
  foo();
  [[fallthrough]];
case B:
  bar();
  break;

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

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

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

كما أننا نساعد عملائنا دائمًا في إعداد PVS-Studio في حالة ظهور أي صعوبات. علاوة على ذلك، كانت هناك حالات قمنا فيها بأنفسنا بإزالة التحذيرات الكاذبة وتصحيح الأخطاء [8]. فقط في حالة قررت أن أذكر أن هذا الخيار للتعاون الموسع ممكن أيضًا :).

طريقة السقاطة

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

كيفية تنفيذ محلل الكود الثابت في مشروع قديم دون تثبيط عزيمة الفريق

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

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

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

لدى كاتب المقال أيضًا تقرير حول هذا الموضوع: "التحليل الثابت المستمر".

اختتام

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

هناك شكوك نموذجية أخرى حول ما إذا كان التحليل الثابت يمكن أن يكون مناسبًا ومفيدًا حقًا. حاولت تبديد معظم هذه الشكوك في منشور "أسباب إدخال محلل الكود الثابت PVS-Studio في عملية التطوير" [9].

شكرا لاهتمامكم وتأتي تحميل وحاول محلل PVS-Studio.

روابط إضافية

  1. أندريه كاربوف. كيف يمكنني رؤية التحذيرات المثيرة للاهتمام التي ينتجها محلل PVS-Studio لكود C وC++ بسرعة؟
  2. ويكيبيديا. نظرية رايس.
  3. أندريه كاربوف، فيكتوريا خانييفا. استخدام التعلم الآلي في التحليل الثابت للكود المصدري للبرنامج.
  4. استوديو PVS. توثيق. إعدادات تشخيصية إضافية.
  5. أندريه كاربوف. خصائص محلل PVS-Studio باستخدام مثال EFL Core Libraries، 10-15% نتائج إيجابية كاذبة.
  6. استوديو PVS. توثيق. قمع جماعي لرسائل المحلل.
  7. إيفان أندرياشين. حول كيفية اختبارنا للتحليل الثابت في مشروعنا الخاص بالمحاكاة التعليمية لجراحة الأوعية الدموية بالأشعة السينية.
  8. بافل إريمييف، سفياتوسلاف رازميسلوف. كيف قام فريق PVS-Studio بتحسين كود Unreal Engine.
  9. أندريه كاربوف. أسباب إدخال محلل الكود الثابت PVS-Studio في عملية التطوير.

كيفية تنفيذ محلل الكود الثابت في مشروع قديم دون تثبيط عزيمة الفريق

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

المصدر: www.habr.com

إضافة تعليق