گنجه
پاداشی به نیت «خیر»خواهانهٔ شما
۰۸ ۳۰م, ۱۳۸۸آیات ۶ تا ۸ سورهٔ مبارکهٔ «عادیات»:
إِنَّ الْإِنسَانَ لِرَبِّهِ لَكَنُودٌ ﴿٦﴾ وَإِنَّهُ عَلَىٰ ذَٰلِكَ لَشَهِيدٌ ﴿٧﴾ وَإِنَّهُ لِحُبِّ الْخَيْرِ لَشَدِيدٌ ﴿٨﴾
ترجمهٔ استاد فولادوند:
كه انسان نسبت به پروردگارش سخت ناسپاس است، (٦) و او خود بر اين [امر]، نيك گواه است. (٧) و راستى او سخت شيفته مال است. (٨)
ترجمهٔ آیت الله مکارم شیرازی:
که انسان در برابر نعمتهای پروردگارش بسیار ناسپاس و بخیل است؛ (٦) و او خود (نیز) بر این معنی گواه است! (٧) و او علاقه شدید به مال دارد! (٨)
ترجمهٔ مرحوم الهی قمشهای:
(قسم به اسبان این مجاهدان دین خدا) که انسان نسبت به پروردگارش کافر نعمت و ناسپاس است. (٦) و (خدا و یا) خود او بر این ناسپاسی محققا گواه است. (٧) و هم او بر حب مال دنیا سخت فریفته و بخیل است. (٨)
دستکاری بستهٔ deb
۰۷ ۱۷م, ۱۳۸۸شاید براتون پیش اومده باشه که بخواهید یک بستهٔ deb رو نصب کنید، ولی یکی از وابستگی0هاش مانع شده باشه. مثلاً چند وقت پیش میخواستم بستهٔ gparted رو نصب کنم، ولی gksu جزو وابستگیهاش بود. (الان در Debian sid درستش کردهاند و دیگه جزو وابستگیهاش نیست، بلکه جزو توصیه1هاشه.) پس چون میخواست به خاطر gksu بخشی از GNOME رو نصب کنه، و از طرفی من هم به GNOME حساسیت دارم(!)، نمیتونستم با این اوضاع gparted رو نصب کنم. ولی یک نکتهٔ مهم این بود که من میدونستم که واقعا gksu رو نیاز ندارم و میتونم بدون اون هم از gparted استفاده کنم. در این شرایط راهی که به ذهن آدم میرسه اینه که بستهٔ deb مربوط به gparted رو دستکاری و gksu رو از فهرست وابستگیهاش حذف کنه.
$ apt-get install gparted -y --print-uris | grep '/gparted_' $ wget http://ftp.debian.org/debian/pool/main/g/gparted/gparted_0.3.7-1_amd64.deb $ mkdir gparted_0.3.7-1.mod_amd64 $ cd gparted_0.3.7-1.mod_amd64 $ dpkg-deb -x ../gparted_0.3.7-1_amd64.deb . $ dpkg-deb -e ../gparted_0.3.7-1_amd64.deb $ vim DEBIAN/control
(برای پایینگذاری2 پروندهٔ deb میشه از debget موجود در بستهٔ debian-goodies هم استفاده کرد)
با ویرایش پروندهٔ3 control بسته، gksu رو از خطی که با Depends شروع میشه حذف میکنم. شمارهٔ نسخه رو هم توی خطی که با Version شروع میشه تغییر میدم.
حالا نوبت بازسازی پروندهٔ deb و نصبش هست:
$ cd .. $ fakeroot dpkg-deb -b gparted_0.3.7-1.mod_amd64 dpkg-deb: building package `gparted' in `gparted_0.3.7-1.mod_amd64.deb'. $ sudo dpkg -i gparted_0.3.7-1.mod_amd64.deb
به بقیهٔ پروندههای داخل پوشهٔ DEBIAN (و حتی بقیهٔ پوشهها) هم نگاهی بندازید!
روشی برای تسریع dpkg
۰۷ ۱۷م, ۱۳۸۸همون طور که احتمالاً میدونید dpkg توساخت0 مدیریت بستهها1 در Debian است. یعنی APT و Synaptic و Aptitude و … همه روی dpkg بنا شده اند.
dpkg برای نگهداری بعضی اطلاعات بستههای نصبشده، از تعداد زیادی (برای من حدود ۹۰۰۰ تا) پروندهٔ2 کوچک توی مسیر /var/lib/dpkg/info استفاده میکنه. هر بار که بستهای رو نصب یا حذف میکنید dpkg همهٔ اون پروندهها رو از روی لوح3 میخونه. این کار روی سامانهٔ پروندهٔ4 مورد استفادهٔ من، که Ext4 هست، اولین بار بیست-سی ثانیهای طول میکشه، که برای من مدت زیادی هست. این کار در دفعات بعدی به علت قرار گرفتن همهٔ اون پروندهها در نهانگاه5 سامانهٔ پرونده در حافظهٔ اصلی، بسیار سریعتر انجام میشه، تا وقتی که دوباره از نهانگاه خارج بشند.
این مشکل هر از گاهی یک سیخی بهم میزد و روی اعصابم راه میرفت. فکرهای مختلفی برای حلش به ذهنم رسید. از بسیار پیچیده، مثل طراحی و پیادهسازی مجدد dpkg روی Tokyo Cabinet یا SQLite، تا بسیار ساده:
شاید بدونید که سامانهٔ پروندهٔ ReiserFS در کار با پروندههای کوچک بسیار عالی عمل میکنه. علتش هم استفاده از فن «تهچِپانی»6 است.7 فکر کردم شاید اگر پوشهٔ /var/lib/dpkg/info رو توی ReiserFS نگه دارم، مشکل حل بشه. این کار رو کردم، ولی به خاطر کارکرد8 داخلی dpkg روی کل /var/lib/dpkg:
$ sudo su - # cd /var/lib # tar cpzf dpkg.tar.gz dpkg # dd if=/dev/zero of=dpkg.reiserfs bs=$((256*1024*1024)) count=1 # mkreiserfs -f dpkg.reiserfs # mount -oloop dpkg.reiserfs dpkg # tar xpf dpkg.tar.gz
و بعد آزمودن و دائمی کردن با افزودن به fstab:
# echo 3 >/proc/sys/vm/drop_caches # apt-get install hello # apt-get purge hello # echo /var/lib/dpkg.reiserfs /var/lib/dpkg reiserfs loop,noatime 0 1 >>/etc/fstab
فکره جواب داد و سرعت dpkg بسیار بهتر شد. حالا حتی اولین بار هم dpkg اون کار رو در دو-سه ثانیه انجام میده.
علاوه بر مهارت ReiserFS در کار با پروندههای کوچک، چند نکتهٔ دیگه هم قابل ذکر هست. یکی این که Ext4 به علت فن «حوزه»9 در کار با پروندههای نسبتاً بزرگی که یکجا تخصیص10 مییابند بسیار سریع هست. برای همین به dd گفتم که کل پرونده رو یکجا بسازه.
از طرفی چون، در نتیجهٔ نکتهٔ قبل، کل پروندههای مربوط به dpkg روی لوح نزدیک به هم قرار میگیرند و پراکنده نیستند، با خونده شدن یک پرونده از اون حوالی، تعداد زیادی از بقیهشون هم توی نهانگاه لوح و تعدادی هم توی نهانگاه سامانهٔ پرونده قرار میگیرند. همین امر باعث میشه کلی زمان جویش11 که قبلاً برای رسیدن به پرندههای پراکنده در اطراف و اکناف لوح هدر میرفت، صرفهجویی بشه.
به گزینهٔ12 noatime در fstab هم دقت کنید. رفتار معمولی سامانههای پرونده این هست که در هر دسترسی (اعم از خواندن یا نوشتن) به یک پرونده، زمان دسترسی رو ذخیره میکنند. این خیلی بده! هر دسترسی = حداقل یک عمل نوشتن روی لوح، و عمل نوشتن هم معمولاً کندتر از خوندن هست. نکته این جاست که برنامههای رایج امروزی معمولاً روی اون زمان ثبتشده برای آخرین دسترسی حساب نمیکنند و عملاً اون عدد بیاستفاده است! گزینهٔ noatime به سامانهٔ پرونده میگه که کلاً قید ثبت اون زمان رو بزنه و به این ترتیب کلی عمل نوشتن صرفهجویی کنه.
زندهام
۰۷ ۱۷م, ۱۳۸۸ظاهراً هنوز زندهام.
توهم اکثریت بودن
۰۳ ۲۵م, ۱۳۸۸گاهی که مدام بین ملت بازمنبع0 زندگی میکنم، اخبارشون رو پیگیری میکنم، تارنوشت1هاشون رو میخونم، مطلب مینویسم و خلاصه تو جوّ بازمنبعیها هستم، فکر میکنم که اکثر کاربرهای رایانه2 با مقولهٔ نرمافزار آزاد3 و بازمنبع آشنا هستند. با خودم میگم حتماً اغلب کاربرها روی رایانهشون یک توزیع4 Linux نصب دارند. فکر میکنم همه حتی اگر از Linux یا یکی از BSDها استفاده هم نمیکنند، حداقل میدونند چیه. واقعاً باورم میشه که ما اکثریتیم!
روشنفکری نوین
۰۳ ۱م, ۱۳۸۸مردم: هُووو … شاه رو نگاه! لباس تنش نیست! هُووو …
بچه: ولی شاه که لباس تنشه!
[نگاههای معنیدار مردم به بچه و به همدیگر]
بابای بچه: ساکت شو بچه، مردم میفهمند روشنفکر نیستی.
جادوی یخزن
۰۲ ۱۸م, ۱۳۸۸چندی پیش در این مورد نوشته بودم که چگونه به کمک یخزن0، لوح سختی1 احیا شد.
چند روز بعدش یکی از دوستان پیامک2 زد که به همون روش، یک لوح لغزان3 رو احیا کرده!
جالبتر این که چند روز پیش، یک MP3پخشکن4 که چند سالی بود کار نمیکرد، به همون روش احیا شد!!!
مقابله با ایرادهای فساد حافظه
۰۱ ۲۷م, ۱۳۸۸مبنای بحث در این مطلب، زبانهای C++ و C هستند، ولی مطالعهٔ آن برای برنامهنویسان هر زبانی که در معرض ایراد0های فساد حافظه1 است و حتی هر برنامهنویسی، احتمالاً خالی از سود نخواهد بود.
برنامهای نوشتهاید که ایراد داره. اون رو حسابی آزمودهاید و هر ایراد منطقی2 رو که فکر میکنید ممکن هست وجود داشته باشه بررسی و رفع کردهاید، ولی هنوز برنامه ایراد داره!
برنامهٔ شما رفتارهای عجیبی از خودش نشون میده. مثلاً اگر در حالت ایرادزدایی3 بسازیدش4 کار میکنه، ولی در حالت انتشار5 یا اشتباه کار میکنه، یا کار نمیکنه و دچار سانحه6 میشه. یا مثلاً با ورودیهای مختلف، در جاهای کاملاً متفاوت و نسبتاً بیربط از کد دچار سانحه میشه. یا مثلاً همیشه در پایان یک تابع7 بعد از همهٔ عملیات، ولی قبل از بازگشت (یعنی دقیقاً روی { !!!) دچار سانحه میشه.
در چنین شرایطی هست که شما حدس میزنید برنامهتون دچار ایراد فساد حافظه1 شده.
اگر برنامه همیشه در یک تابع خاص دچار سانحه میشه، حدس میزنیم که در یکی از متغیرهای محلی همون تابع خرابکاری شده و پشته8 خراب شده؛ به همین دلیل در هنگام جمع کردن قاب پشتهٔ9 تابع از روی پشته، به علت فساد نشانی بازگشت10، برنامه دچار سانحه میشه11.12 معمولاً با خوندن دقیق همون تابع، ایراد یافت و حل میشه. اگر نشد، متغیرهای محلی که روی پشته هستند رو به کومه13 منتقل میکنیم (با استفاده از new یا malloc) و میریم به سراغ روشهای مربوط به فساد کومه که الان میخواهیم بگیم.
اولین قدم برای یافتن ایرادهای فساد حافظهٔ کومه، استمداد از حضرت Valgrind است (که در دبین14 بستهاش valgrind است)):
% valgrind --leak-check=full --leak-resolution=high ./buggy
برنامه با سرعتی بسیار کمتر از حد معمول اجرا میشه و هر دسترسی به حافظهٔ کومه که خارج از حافظهٔ تخصیصیافته15 باشه، با نام تابع و (در حالت ایرادزدایی) شمارهٔ خط کد منبع16 گزارش میشه. البته Valgrind بسیار جای حرف و معرفی و ستایش و غیره داره که از موضوع این مطلب خارجه!
اگر Valgrind مشکل رو یافت و ایراد رفع شد که خدا رو شکر میکنیم! اما اگر نه، با یک مورد بدخیم (!) طرف هستیم. یعنی دسترسیهایی داریم که به رغم ایراد داشتنشون، داخل حافظهٔ تخصیصیافته قرار گرفتهاند. مثلاً دو آرایهٔ ۱۰۰تایی پشت سر هم در کومه گرفتهایم و به عنصر ۱۲۵ام از آرایهٔ اول دست زدهایم! دسترسی هنوز داخل حافظهٔ پردازهٔ17 خودمان است، ولی نادرست و ایراددار. اگر کسی تا این جای مطلب رو خونده باشه تعجب میکنم! البته کسی به جز خودم!
انشاء الله در مطلب بعدی شیوهای برای یافتن این موارد بدخیم معرفی خواهد شد که از یکی از همکاران باتجربهترم (حفظه الله) آموختهام.
- Bug [↩]
- Memory corruption [↩] [↩]
- Logical [↩]
- Debug [↩]
- Build [↩]
- Release [↩]
- Crash [↩]
- Function [↩]
- Stack [↩]
- Stack frame [↩]
- Return address [↩]
- نوعی سرریز میانگیر (Buffer overflow) [↩]
- البته این رفتار سانحهآمیز (!) بستگی به همگردان داره، ولی همگردانهای جدید مثل GCCهای ۴ به بعد (و شاید بعضی قدیمیترها)، به علت داشتن روشهایی برای مقابله با خرابی پشته، عمداً برنامهای تولید میکنند که در این شرایط دچار سانحه بشه [↩]
- Heap [↩]
- Debian [↩]
- Allocated [↩]
- Source code [↩]
- Process [↩]
چند تشکر
۰۱ ۲۷م, ۱۳۸۸متشکرم0:
از آقای سید ابراهیم رئیسی، معاون اول رییس قوهٔ قضاییه، برای جلوگیری شجاعانه از آزاد کردن شهرام جزایری (یا فراری دادنش1)،
از کیهان و آقای حسین شریعتمداری، برای افشای فاجعهٔ مذکور2،
از بر و بچههای مرکز بررسی جرایم سازمانیافتهٔ سپاه پاسداران، برای پاک کردن اینترنت از لوث چند پایگاه عفتستیز، حیاستیز و دینستیز و دستگیری عواملشون.
- فارغ از همهٔ سیاستبازیهای رایج [↩]
- اگر تکذیب آزاد کردنش راست باشه [↩]
- در سرمقالهٔ کیهان در تاریخ ۱۳۸۸/۱/۲۲ [↩]
باخت به عربستان سعودی
۰۱ ۲۲م, ۱۳۸۸باخت اصلی، جستوجوی بُرد در زمین فوتبال است.