اشکال زدایی (Debugging) یک فرآیند چند مرحلهای در حوزهی برنامه نویسی و مهندسی کامپیوتر است که شامل پیدا کردن مشکل، جداسازی منبع مشکل از برنامهی اصلی و سپس تصحیح این مشکل و یا پیدا کردن راهی برای حل این مشکل است. در مرحلهی آخر دیباگ کردن، راه حلها و اصلاحات انجام شده را دوباره آزمایش میکنیم تا از صحیح بودن کارکرد برنامهی نوشته شده اطمینان حاصل کنیم.
در فرآیند توسعه ی نرم افزار، عمل دیباگ کردن به وسیلهی توسعه دهندهی کد و با پیدا کردن خطا در کد برنامهی کامپیوتری و توانایی باز تولید آن خطا آغاز میشود. فرآیند دیباگ کردن یکی از بخشهای فرآیند تست کردن نرم افزار Software Testing است. تست نرم افزار به نوبهی خود یکی از بخشهای جدایی ناپذیر از فرآیند چرخهی تولید نرم افزار میباشد.
در توسعهی سخت افزار، فرآیند دیباگ کردن به دنبال اجزای سخت افزاری میگردد که به درستی نصب یا پیکربندی نشده است. به عنوان مثال ممکن است یک مهندس، یک تست اتصال JTAG را اجرا کند تا به رفع اشکالات مربوط به اتصالات یک مدار الکتریکی بپردازد.
نحوه ی عملکرد دیباگ در نرم افزار
فرآیند دیباگ کردن به محض نوشته شدن یک کد آغاز میشود و در طول فرآیند نرم افزار، یعنی زمانی که قسمتهای دیگر نرم افزار برنامه نویسی شدهاند و به یک دیگر الحاق شدهاند ادامه مییابد. این روند تا آخر فرآیند ساخته شدن نرم افزار نیز ادامه دارد. در چرخهی تولید یک نرم افزار بزرگ که از هزاران هزار خط کد تولید شده است، میتوان به وسیلهی استراتژیها و تکنیکهایی مانند تست واحد (Unit Test)، بررسی کدها و Pair Programming، فرآیند دیباگ را آسان تر کرد.
برای شناسایی و پیدا کردن یک باگ، نگاه کردن به لاگ (Log)های کد و استفاده از یک ابزار دیباگ کردن، میتواند بسیار مفید باشد. همچنین در IDE های برنامه نویسی، معمولا یک مد یا حالت مربوط به دیباگ وجود دارد که میتواند فرآیند شناسایی باگ را تسریع ببخشد. اگر توسعه دهندگان در این مرحله، یعنی شناسایی خطا، با پیام خطاهای استاندارد آشنا باشند، راحتتر میتوانند به رفع آن خطا بپردازند. اگر توسعه دهندگان از کامنت گذاری (Comment) صحیح در کدهای خود استفاده نکنند، حتی تمیز ترین کدها میتوانند برای دیباگ توسط فردی دیگر چالش برانگیز باشد.
در برخی از موارد، ماژولی که خطا را ایجاد کرده است مشخص است، اما دقیق مشخص نیست که کدام خط از کد این خطا رو تولید کرده است. در این موارد تست واحد (Unit Test) مانند JUnit و XUnit به کار میآید. به وسیلهی تست واحد میتوان یک تابع خاص از برنامهی نوشته شده را با پارامترهای ورودی خاص اجرا کرد که برای فرآیند دیباگینگ بسیار مفید است.
یکی از روشهای استاندارد و مرسوم در دیباگ، استفاده از نقاط توقف یا Breakpoint در کدها است. وقتی در یک خط از کد، نقطهی توقف میگذاریم، برنامه از اول تا سر آن نقطهی توقف اجرا میشود. سپس با ابزارهای دیباگ کردن که داخل IDEها تعبیه شده است، قادر به رصد کردن برنامه و پیدا کردن خطاها میباشیم. همچنین به وسیلهی این ابزارها و نقاط توقف، قادر هستیم تا کارهای زیر را انجام دهیم:
- کل حافظه مصرف شده را مشاهده کنیم.
- مقدار تمامی متغیرهای تعریف شده را مشاهده و بررسی کنیم.
- برنامه را از آن نقطه که متوقف شد شروع کنیم تا نقطهی توقف دیگر.
- خط بعدی کد را اجرا کنیم (مثلا یک خط یک خط پیش برویم).
- مقدار یک متغیر را به صورت دستی و در حین اجرای برنامه تغییر دهیم.
- کل یک خط کد را به صورت دستی و در حین اجرای برنامه تغییر دهیم.
چرا فرایند دیباگ کردن از اهمیت بالایی برخوردار است؟
دیباگ کردن یکی از بخشهای مهمی است برای اینکه دریابیم که چرا یک سیستم عامل، یک نرم افزار و یا یک برنامه، رفتار صحیحی ندارد. حتی اگر توسعه دهندهها از کدهای استاندارد مشابهی استفاده کنند، باز هم احتمال وجود باگهایی در نرم افزار ساخته شدهی جدید وجود دارد. در بعضی از مواقع حتی ممکن است فرآیند دیباگ کردن برای یک نرم افزار جدید، از نوشتن کدها و ساخت خود آن قسمت از نرم افزار نیز بیشتر طول بکشد. لازم به ذکر است که بگوییم در اکثر اوقات، قسمتی از برنامه که بیشترین استفاده را دارد، زودتر باگهایش پیدا و رفع میشود.
تفاوت دیباگ کردن و تست کردن
دیباگ کردن و تست کردن در واقع مکمل یکدیگر هستند. هدف از انجام تست این است که پی ببریم اگر در قسمتی از سورس کد برنامهی نوشته شده، اشتباه و خطایی وجود داشته باشد چه اتفاقی میافتد. هدف از انجام دیباگ پیدا کردن محل این اشتباه و خطا و سپس رفع آن است.
فرآیند تست کردن هیچ کمکی به توسعه دهندهها در جهت اینکه چه خطایی رخ داده است نمیکند. به طور ساده تست کردن فقط نشان میدهد که یک خطا چه تاثیری در اجرای برنامه میگذارد. وقتی یک نرم تست میشود و یک خطا یافت میشود، فرآیند دیباگ کردن کمک میکند تا علت این خطا را کرده تا بتوانیم راهی برای حل این خطا پیدا کنیم.
نمونه های رایج خطا های کدنویسی
در زیر نمونههایی از خطاهای رایج کد نویسی آمده است:
- خطای نحو (Syntax Error)
- خطای زمان اجرا (Runtime Error)
- خطای معنایی (Semantic Error)
- خطای منطقی (Logic Error)
- بی توجهی به قواعد های کد نویسی
- فراخوان یک تابع اشتباه
- درست ننوشتن نام یک متغیر و یا استفاده از آن در یک قسمت نامناسب
- عدم مقدار دهی اولیهی یک متغیر وقتی نیاز به مقدار دهی داشته باشد
استراتژی های دیباگینگ
تحلیلگرهای سورس کد، که شامل بررسی امنیت، خطاهای متداول و تحلیل میزان پیچیدگی کد هستند، میتوانند در فرآیند دیباگ کردن نرم افزار بسیار مفید واقع شوند. یک تحلیلگر پیچیدگی، قادر است تا ماژولها و قسمتهای پیچیدهی کدی را پیدا کند که درک کردن و تست کردن آن دشوار است. استراتژیهای دیگری نیز برای رفع اشکال وجود دارد که در زیر آمده است:
- تجزیه و تحلیل ایستا (Static Analysis): توسعه دهنده، کد را آزمایش میکند بدون اینکه برنامه را به طور کامل اجرا کرده باشد.
- پرینت دیباگینگ یا رصد کردن کد (Print Debugging. Tracing): در قسمتهای مختلف کد، توسعه دهنده مقادیر مختلف را Print میکند تا با مانیتور کردن و رصد کردن آن، بتواند خطاها را تشخیص دهد.
- دیباگ از راه دور (Remote Debugging): در این استراتژی، دیباگر مربوط به توسعه دهنده، روی سیستمی به غیر از سیستمی که برنامهی مورد نظر روی آن دیباگ شده است اجرا میشود.
- دیباگ بعد از وقوع مشکل (Post-mortem Debugging): توسعه دهنده تنها موقعی که برنامه با استثناهات مهلک یا همان Fatal Exceptionها مواجه شود، دیباگ را متوقف میکند.
ابزارهای اشکال زدایی
دیباگر (Debugger) در واقع یک ابزار نرمافزاری است که توسعهدهندگان از طریق آن میتوانند اشکالات و خطاهای کدهای خود را در طول مراحل مختلف توسعهی یک نرم افزار شناسایی کنند. بعضی دیباگرها با اجرای کدها به صورت آزمایشی، میتوانند بررسی کنند که کدام خطوط از کد، اجرا نشدهاند. همچنین دیباگرهای دیگری نیز وجود دارند که ابزارهایی را برای شبیهسازی و مدل کردن برنامههای نوشته شده فراهم کردهاند تا برنامه نویسان به وسیلهی این ابزارها، بتوانند حاصل خروجی و رفتار کد خود را بر روی سیستمعامل و کامپیوتر مورد نظر مشاهده کنند.
بسیاری از ابزارهای دیباگینگ متن باز (Open Source)اوپن سورس یا متن باز چیست؟ اوپن سورس به چه معناست؟اوپن سورس یا متن باز چیست؟ این صفحه عالی به بررسی این موارد و همچنین تاریخچه نرم افزار متن باز و نحوه به کارگیری متن باز در توسعه نرم افزار پرداخته است و زبان های اسکریپتی بر روی یک IDE اجرا نمیشوند. بنابراین این ابزارها نیاز به یکسری کارهای دستی برای اشکال زدایی یا دیباگینگ دارند. به عنوان مثال در USB دیباگینگ، این امکان برای دستگاههای اندرویدی فراهم میباشد تا بتوانند با کامپیوتری که کیت توسعهی نرمافزار اندرویدسیستم عامل اندرويد چیست؟ هر آنچه باید درمورد Android بدانیداندروید چیست و چه ویژگی هایی دارد؟ این مقاله عالی به معرفی سیستم عامل اندروید (Android)، تاریخچه و توسعه اندروید، ویژگی های ورژن های مختلف اندروید پرداخته است یا همان Android SDK را اجرا کرده، در تعامل باشند.
برای انجام این کارها، توسعهدهنده ممکن است با در نظر گرفتن یک متغیر خاص و Log گرفتن از آن، به بررسی وضعیت و مقادیر آن متغیر با چاپ کردن متوالی مقدار آن متغیر در طول برنامه بپردازد و یا به عنوان مثالی دیگر، توسعهدهنده میتواند در بخشهای مختلف برنامهی نوشته شده یک نقطهی توقف (Breakpoint) ایجاد کند تا دیباگر تا آن نقطه کدها را اجرا کرده و منتظر دستورات بعدی توسعهدهنده بماند، مثلا منتظر یک ورودی یا منتظر ماندن در یک زمان از پیش تعیین شده.
چالش های دیباگینگ
فرآیند اشکال زدایی میتواند بسیار سخت باشد، گاهی ممکن است به اندازهی نوشتن کد نیز زمان ببرد. از مهمترین چالشهای فرآیند دیباگینگ، میتوان به موارد زیر اشاره کرد:
- اثر منفی خطای کد به طور واضحی مشخص است، اما دلیل آن مشخص نیست.
- وابستگیها به طور دقیقی مشخص نیستند. به عنوان مثال ممکن است یک خطا را در کدی برطرف کنیم و بعد از اجرا متوجهی این مورد بشویم که رفع این خطا، باعث بوجود آمدن خطا در قسمت دیگری از برنامه به دلیل وابستگی آن به کد اول شده است.
- در برنامهی خود از یکسری کتابخانههای خارجی استفاده کرده باشیم و بعد از اتمام کد، از اجرا شدن صحیح کد اطمینان حاصل میکنیم. اما بعد از مدت طولانی و با بروز رسانی شدن کتابخانههای خارجی، ناگهان یک خطای از پیش تعیین نشده برای کد ما بوجود میآید.
تاریخچه ی دیباگینگ
کلمهی باگ (Bug) اصطلاحی است که برای خطا در مهندسی استفاده میشود. این اصطلاح تاریخچهی جالبی دارد. کاربرد این اصطلاح برای خطایابی، به گریس هاپر (Grace Hopper) که از نخستین برنامهنویسان کامپیوتری بود نسبت داده شده است. زمانی که اولین کامپیوتر نیروی دریایی ایالات متحده دچار مشکل شد، هاپر و تیمش برای بررسی مشکل این کامپیوتر اقدام کردند و بعد از مدتی متوجه شدند که یک حشره (باگ در زبان انگلیسی به معنای حشره است) در واقع یک پروانه، بین رلههای الکتریکی گیر کرده و در مدار الکتریکی یک اتصال کوتاه بوجود آورده است. این پروانه از قطعه بیرون آورده شد و اکنون در موزهی Smithsonian نگهداری میشود.
جمع بندی
دیباگ کردن (Debugging) یک بخش جدایی ناپذیر از فرآیند تولید هر برنامهی کامپیوتری میباشد و در طول زمان، ابزارهای زیادی بوجود آمدند تا کار دیباگ کردن و رفع خطا را برای توسعه دهندگان و متخصصان حوزهی کامپیوتری راحتتر کنند. همچنین بسیاری از روشهای توسعهی نرم افزار نیز بوجود آمده که با استفاده از این روشها و ایدهها، سعی میشود تا خطای کمتری بوجود بیاید، زیرا پدید آمدن خطا ممکن است بسیار خطر آفرین باشد. در این مقاله به بررسی کلی در مورد فرآیند اشکال زدایی و انواع خطاهایی که ممکن است در طول نوشتن و اجرای یک برنامه بوجود بیاید پرداختیم.
دیباگ کردن چیست؟
به طور کلی به فرآیند پیدا کردن خطاها و باگهایی که در سورس کد نرمافزارها وجود دارد، دیباگ کردن یا اشکال زدایی میگویند. وقتی برنامهی نوشته شده به آن صورتی که انتظار میرود اجرا نشود، یعنی دچار خطایی شده است. برنامه نویسان و متخصصان حوزهی کامپیوتر به وسیلهی عمل دیباگ کردن، به پیدا کردن خطا و رفع آن میپردازند.
خطای نحوی یا نوشتاری به چه معناست؟
سادهترین نوع خطا در نوشتن یک کد، خطای نحوی یا Syntax Error میباشد. رفع کردن این مشکل کار آسانی است و نیاز به زمان کمی نیز دارد، گاهی اوقات به این خطا، خطای گرامری میگویند. این خطا برای اشکال در نوشتن نحو یا سینتکس دستور زبان مورد نظر ایجاد میشود و در اکثر ادیتورها و IDEها، ابزاری تعبیه شده تا قبل از کامپایل و یا تفسیر کد، این خطا را پیدا کند. به عنوان مثال اگر در زبان ++C در آخر عبارت، نقطه ویرگول (;) گذاشته نشود، با خطای نحوی مواجه میشویم.
خطای زمان اجرا به چه معناست؟
بعضی از اوقات برنامهی نوشته شده به درستی کامپایل و اجرا میشود. یعنی هیچ گونه خطای نحوی و گرامری نداشته اما در حین اجرای قسمتی از برنامه با اشکال مواجه میشویم. به این نوع خطا، خطای زمان اجرا یا Runtime Error میگویند. به عنوان مثال در برنامهی نوشته شده ممکن است نیاز باشد تا یک تصویر از اینترنت دانلود شود، اگر لینک یا URL این تصویر اشتباه نوشته شده باشد یا آن لینک حذف شده باشد، هنگام دانلود تصویر، با یک خطای زمان اجرا مواجه میشویم.
خطای منطقی چیست؟
یکی از مهلکترین خطاها، خطای منطقی یا Logical Error میباشد. پیدا کردن این مشکل و رفع آن ممکن است بسیار زمانبر و هزینهبر باشد. در این نوع خطا، در واقع هیچ خطای گرامری یا خطای اجرایی وجود ندارد، بلکه منشا خطا، منطق برنامه میباشد. هنگام اجرای نرمافزار، نرمافزار به درستی کار میکند، اما خروجی نرم افزار، خروجی مورد نظر ما نیست. به عنوان مثال ممکن است مشاهده کنیم در یک نرم افزار آماری، مقدار احتمال بیشتر از 100 درصد شده است! که مشخص است امکان چنین چیزی وجود ندارد و نتیجه میگیریم که مشکل از منطق نرمافزار ما بوده است. ممکن است بعد از دیباگ کردن متوجه شویم که به جای استفاده از عملگر جمع، از ضرب استفاده کردهایم.
نقطه ی توقف یا breakpoint به چه معناست؟
یکی از مهمترین بخشهای اشکال زدایی، نقطههای توقف یا Breakpointها هستند. این نقطهها در قسمتهای دلخواه سورس کد برنامهی نوشته شده قرار میگیرد و برنامه در حین اجرا، در این قسمت از کدها توقف میکند و برنامهنویس میتواند مقدار تمامی متغیرها را مشاهده، تجزیه و تحلیل کند. بنابراین با تعدادی از این نقاط در برنامه، میتوان کد برنامهی نوشته شده را رصد کرد و محل مشکلات بوجود آمده در کد را پیدا کرد.