خطأ في ناقل البيانات
في مجال الحوسبة ، يُعد خطأ ناقل البيانات عطلاً يُصدره الجهاز، مُنبهًا نظام التشغيل بأن عملية ما تحاول الوصول إلى ذاكرة لا يستطيع المعالج المركزي الوصول إليها فعليًا: عنوان غير صالح لناقل العناوين ، ومن هنا جاءت التسمية. في الاستخدام الحديث على معظم البنى، تُعد هذه الأخطاء أقل شيوعًا بكثير من أخطاء تجزئة الذاكرة ، التي تحدث أساسًا بسبب انتهاكات الوصول إلى الذاكرة: مشاكل في العنوان المنطقي أو الأذونات.
في الأنظمة المتوافقة مع معيار POSIX ، عادةً ما تؤدي أخطاء ناقل البيانات إلى إرسال إشارة SIGBUS إلى العملية التي تسببت في الخطأ. قد ينتج خطأ SIGBUS أيضًا عن أي عطل عام في الجهاز يكتشفه الحاسوب، مع العلم أن خطأ ناقل البيانات نادرًا ما يعني وجود عطل مادي في مكونات الحاسوب ، بل عادةً ما يكون ناتجًا عن خلل برمجي . قد تُثار أخطاء ناقل البيانات أيضًا في حالات معينة من أخطاء الترحيل؛ انظر أدناه.
الأسباب
هناك ثلاثة أسباب رئيسية على الأقل لأخطاء الحافلات:
عنوان غير موجود
يُصدر البرنامج تعليماتٍ لوحدة المعالجة المركزية (CPU) لقراءة أو كتابة عنوان ذاكرة فعلي مُحدد . وبناءً على ذلك، تُعيّن وحدة المعالجة المركزية هذا العنوان الفعلي على ناقل العناوين الخاص بها ، وتطلب من جميع الأجهزة الأخرى المتصلة بها الاستجابة بالنتائج، إن وُجدت. إذا لم تستجب أي أجهزة أخرى، تُصدر وحدة المعالجة المركزية استثناءً يُفيد بأن العنوان الفعلي المطلوب غير مُعترف به من قِبل نظام الحاسوب بأكمله. تجدر الإشارة إلى أن هذا ينطبق فقط على عناوين الذاكرة الفعلية . أما محاولة الوصول إلى عنوان ذاكرة افتراضية غير مُعرّف ، فتُعتبر عمومًا خطأ تجزئة وليس خطأً في ناقل العناوين، مع العلم أنه في حال كانت وحدة إدارة الذاكرة (MMU) منفصلة، فلن يتمكن المعالج من التمييز بينهما.
الوصول غير المتوافق
معظم وحدات المعالجة المركزية قابلة للعنونة بالبايت ، حيث يشير كل عنوان ذاكرة فريد إلى بايت مكون من 8 بت . تستطيع معظم وحدات المعالجة المركزية الوصول إلى بايتات فردية من كل عنوان ذاكرة، لكنها لا تستطيع عمومًا الوصول إلى وحدات أكبر (16 بت، 32 بت، 64 بت، وما إلى ذلك) إلا إذا كانت هذه الوحدات " محاذية " لحدود محددة ( وتُعد منصة x86 استثناءً ملحوظًا).
على سبيل المثال، إذا كان الوصول إلى وحدات متعددة البايتات يتطلب محاذاة 16 بت، فإن العناوين (المُعطاة بالبايتات) عند 0، 2، 4، 6، وهكذا تُعتبر مُحاذية وبالتالي قابلة للوصول، بينما تُعتبر العناوين 1، 3، 5، وهكذا غير مُحاذية. وبالمثل، إذا كان الوصول إلى وحدات متعددة البايتات يتطلب محاذاة 32 بت، فإن العناوين 0، 4، 8، 12، وهكذا تُعتبر مُحاذية وبالتالي قابلة للوصول، وتُعتبر جميع العناوين بينها غير مُحاذية. محاولة الوصول إلى وحدة أكبر من بايت واحد عند عنوان غير مُحاذٍ قد تُسبب خطأً في ناقل البيانات.
قد تحتوي بعض الأنظمة على مزيج من هذه الأساليب اعتمادًا على البنية المستخدمة. على سبيل المثال، بالنسبة للأجهزة المبنية على نظام IBM System/360 الرئيسي، بما في ذلك IBM System z وFujitsu B8000 وRCA Spectra و UNIVAC Series 90 ، يجب أن تكون التعليمات على حدود 16 بت، أي يجب أن تبدأ عناوين التنفيذ من بايت زوجي. محاولات الانتقال إلى عنوان فردي تؤدي إلى استثناء في المواصفات. [ 1 ] مع ذلك، يمكن استرجاع البيانات من أي عنوان في الذاكرة، وقد يكون حجمها بايتًا واحدًا أو أكثر حسب التعليمات.
تستخدم وحدات المعالجة المركزية عادةً عرض ناقل البيانات بالكامل للوصول إلى البيانات . وللوصول إلى البايتات، تستخدم عرض ناقل البيانات بالكامل للوصول إلى الذاكرة، ثم تقوم بتطبيق قناع وإزاحة للوصول إلى البايت المطلوب. وتتحمل الأنظمة هذه الخوارزمية غير الفعالة، لأنها ميزة أساسية لمعظم البرامج، وخاصةً معالجة النصوص . على عكس البايتات، يمكن أن تمتد الوحدات الأكبر حجمًا على عنوانين متوازيين، مما يتطلب أكثر من عملية جلب واحدة على ناقل البيانات. من الممكن أن تدعم وحدات المعالجة المركزية هذه الميزة، ولكن نادرًا ما تكون هذه الوظيفة مطلوبة مباشرةً على مستوى كود الآلة ، لذا يتجنب مصممو وحدات المعالجة المركزية عادةً تنفيذها، ويكتفون بإصدار أخطاء ناقل البيانات عند الوصول إلى الذاكرة غير المتوازية.
أخطاء في الترحيل
يمكن لأنظمة FreeBSD و Linux و Solaris الإشارة إلى خطأ في ناقل البيانات عندما يتعذر نقل صفحات الذاكرة الافتراضية ، على سبيل المثال بسبب اختفائها (مثل الوصول إلى ملف مُرتبط بالذاكرة أو تنفيذ صورة ثنائية تم اقتطاعها أثناء تشغيل البرنامج)، [ 2 ] أو بسبب عدم إمكانية تخصيص ملف مُرتبط بالذاكرة تم إنشاؤه للتو فعليًا، لأن القرص ممتلئ.
مقطع غير موجود (x86)
في معالجات x86، توجد آلية قديمة لإدارة الذاكرة تُعرف باسم التجزئة . إذا قام التطبيق بتحميل سجل تجزئة باستخدام مُحدِّد تجزئة غير موجود (وهو ما لا يُمكن فعله في أنظمة التشغيل المتوافقة مع معيار POSIX إلا باستخدام لغة التجميع )، فسيتم توليد استثناء. استخدمت بعض أنظمة التشغيل هذه الآلية للتبديل، ولكن في نظام لينكس، يتم توليد استثناء SIGBUS.
مثال
هذا مثال على الوصول إلى الذاكرة غير المحاذية، مكتوب بلغة البرمجة C باستخدام صيغة التجميع AT&T .
#include <stdlib.h>int main ( int argc , char ** argv ) { int * iptr ; char * cptr ; #if defined(__GNUC__) #if defined(__i386__) /* تفعيل فحص المحاذاة على x86 */ __asm__ ( "pushf \n orl $0x40000,(%esp) \n popf" ); #elif defined(__x86_64__) /* تفعيل فحص المحاذاة على x86_64 */ __asm__ ( "pushf \n orl $0x40000,(%rsp) \n popf" ); #endif #endif/* توفر الدالة malloc() دائمًا ذاكرة مُحاذية لجميع الأنواع الأساسية */ cptr = malloc ( sizeof ( int ) + 1 ); /* زيادة المؤشر بمقدار واحد، مما يجعله غير مُحاذٍ */ iptr = ( int * ) ++ cptr ;/* فك مرجعيته كمؤشر عدد صحيح، مما يتسبب في وصول غير محاذٍ */ * iptr = 42 ;/* ستؤدي عمليات الوصول التالية أيضًا إلى خطأ في ناقل الإشارة. short *sptr; int i; sptr = (short *)&i; // بالنسبة لجميع الزيادات الفردية، سينتج عنها إشارة sigbus. sptr = (short *)(((char *)sptr) + 1); *sptr = 100; */return 0 ; }يوضح تجميع وتشغيل المثال على نظام تشغيل متوافق مع معيار POSIX على معالجات x86 الخطأ التالي:
$ gcc -ansi sigbus.c -o sigbus $ ./sigbus خطأ في ناقل البيانات $ gdb ./sigbus (gdb) r تلقى البرنامج إشارة SIGBUS، خطأ في ناقل البيانات. 0x080483ba في الدالة main () (gdb) x/i $pc 0x80483ba <main+54>: mov DWORD PTR [eax],0x2a (gdb) p/x $eax $ 1 = 0x804a009 (gdb) p/t $eax & (sizeof(int) - 1) $ 2 = 1يُظهر مصحح الأخطاء GDB أن القيمة الفورية 0x2a تُخزَّن في الموقع المُخزَّن في سجل EAX ، باستخدام لغة التجميع X86 . هذا مثال على عنونة السجلات غير المباشرة .
تُظهر طباعة البتات ذات الترتيب الأدنى للعنوان أنه غير محاذٍ لحدود الكلمة ("dword" باستخدام مصطلحات x86).
مراجع
- ↑ مبادئ تشغيل بنية z ، SA22-7832-04، الصفحة 6-6، الطبعة الخامسة (سبتمبر 2005)، شركة IBM، بوكيبسي، نيويورك، يمكن استرجاعها من http://publibfp.dhe.ibm.com/epubs/pdf/a2278324.pdf ، مؤرشفة في 22 مايو 2022 على موقع Wayback Machine (تم استرجاعها في 31 ديسمبر 2015).
- ↑ "ما هو SIGBUS - خطأ في الأجهزة خاص بالكائن؟ "
- إدارة الذاكرة
- أخطاء الحاسوب
- حافلات الكمبيوتر
