میشه گفت اولین برنامه ای که هر برنامه نویسی نوشته Hello World هست. توی این برنامه شما فقط یک متن ساده رو داخل خروجی چاپ میکنید. اما چطوری ممکنه ی برنامه به این سادگی باگ داشته باشه ؟!
خب ، اول این رو بگم که توی زبان های مختلف این برنامه رو میشه به شکل های مختلفی نوشت مثلا توی زبانی مثل C یا C++ شما میتونید به چندین روش اون رو بنویسید. یکی از استاندارد ترین روش ها برای نوشتن این برنامه به زبان C کد زیر هست :
اما هر چقدر هم که استاندارد بنویسیم باز هم این برنامه باگ داره ?
قبل از اینکه در مورد باگ این برنامه حرف بزنیم بیایید کمی با امکانات لینوکس آشنا بشیم.
فایل dev/full/
توی لینوکس هر چیزی یا فایل هست یا پروسس. یکسری فایل هم داریم که واقعا فایل نیستن که بهشون میگیم device file مثل فایل های /dev/null و یا /dev/full.
فایل /dev/null مثل یک چاه هست که هیچ وقت پر نمیشه و هر چیزی که لازمش نداریم مثلا خروجی یک برنامه یا وارنینگ های یک برنامه رو داخلش میریزیم. فایل /dev/full برعکس dev/null/ ، فایلی هست که کاملا پر شده و شما نمیتونید داده ی جدیدی رو داخلش بنویسید. گاهی اوقات برای اینکه ببینیم برنامه ما IO stream ها رو به درستی مدیریت میکنه ازش استفاده میکنیم مثلا میخواهیم تست کنیم که آیا برنامه من زمانی که یک فایل پر شده میتونه به کار خودش ادامه بده و مشکلش رو حل کنه یا نه از این فایل برای تست استفاده میکنیم.
مثلا توی عکس زیر من یک متن رو داخل ترمینال چاپ کردم و خروجیش رو داخل این فایل ریختم و همونطور که میبینید بهم ارور داده که فضای کافی نداره.
متغیر ?$
اگر به خط آخر مربوط به برنامه Hello World که بالا تر بود نگاه کنید میبینید که توی خط آخر از return استفاده کردم. معنی این return این هست که اگر برنامه با موفقیت اجرا شد و به درستی به اتمام رسید مقداری که داخل EXIT_SUCCESS هست رو بهم برگردون و اگر موفق نبود خودش کد اروری که اتفاق افتاده رو برمیگردونه.
پس اگر قراره من بدونم که برنامم درست اجرا شده یا نه باید ببینم که چه مقداری رو بر میگردونه. توی لینوکس اگر بخواهیم مقدار بازگشتی برنامه رو بدونیم از ?$ استفاده میکنیم که یک متغیر هست و وضعیت خروج آخرین برنامه رو داخل خودش داره .
مثلا برنامه ای که توی تصویر بالا اجرا کردم به ارور خورد و حالا اگر بخواهم که مقدار بازگشتی این برنامه رو ببینم به این روش عمل میکنم :
دستور echo متنی رو روی صفحه کنسول من چاپ میکنه و همونطور که میبینید عدد 1 رو به من نشون میده که یعنی آخرین برنامه ای که اجرا کردی به ارور خورده و به درستی به اتمام نرسید. اگر 0 برگردونه یعنی برنامه به درستی اجرا و به اتمام رسیده.
باگ برنامه کجاست ؟
بیاید با چیز هایی که تا اینجا دیدیم برنامه Hello World رو اجرا کنیم.
من اول برنامه رو کمپایل میکنم ، اجراش میکنم و خروجیش رو داخل فایل /dev/full میریزم و بعد هم مقدار بازگشتی برنامه رو چک میکنم :
مشکل رو میبینید ؟ من انتظار داشتم که برنامه به من ارور بده و عدد 1 رو برگردونه چون فایل /dev/full پر هست و نباید بشه چیزی رو داخلش نوشت اما خروجی چیز دیگه ای رو میگه.
مشکل کجاست ؟
بیایید ی نگاهی هم به سیستم کال ها یا همون فراخوانی های سیستمی کنیم. برای این کار توی لینوکس از دستور strace استفاده میکنیم.
اگر نگاه کنید توی سمت راست اروری که ما میخواستیم وجود داره یعنی سیستم عامل این ارور رو تشخیص و گزارش داده ولی برنامه اون رو نادیده گرفته.
چقدر این باگ میتونه مشکل ساز بشه ؟
درسته که برنامه ی Hello World برنامه ی ساده ای هست و یک برنامه مهم و قابل استفاده نیست ولی داره همون کاری رو میکنه که یک برنامه واقعی ممکنه انجام بده، یک متن رو داخل خروجی استاندارد مینویسه و اون رو داخل یک فایل ریدایرکت میکنه.
فرض کنید فرزند یک پروسس میخواد داده ای رو به این شکل داخل یک فایل بنویسه و اون فایل حجم کافی رو نداره و داده ذخیره نمیشه اما برنامه هم ارور نمیده و والد پروسس هم متوجه ارور نمیشه و به کارش ادامه میده در نتیجه یکسری داده رو از دست میدیم.
توی زبان های دیگه چطور ؟
این باگ توی زبان های دیگه هم وجود داره داخل این لینک از گیتهاب میتونید لیست شون رو ببینید.