กลับไปหน้าบทความ

อ่าน 3 นาที

ข้อผิดพลาดของบัส

ในด้าน คอมพิวเตอร์ ข้อผิดพลาดของบัส (Bus error ) คือ ความผิดพลาด ที่เกิดขึ้นจากฮาร์ดแวร์ ซึ่งแจ้งให้ ระบบปฏิบัติการ (OS) ทราบว่ากระบวนการหนึ่งกำลังพยายามเข้าถึง หน่วยความจำ ที่...

ข้อผิดพลาดของบัส

ในด้านคอมพิวเตอร์ข้อผิดพลาดของบัส (Bus error ) คือความผิดพลาดที่เกิดขึ้นจากฮาร์ดแวร์ ซึ่งแจ้งให้ระบบปฏิบัติการ (OS) ทราบว่ากระบวนการหนึ่งกำลังพยายามเข้าถึงหน่วยความจำที่ซีพียูไม่สามารถเข้าถึงได้จริง กล่าวคือ เป็นที่อยู่ที่ไม่ถูกต้องสำหรับบัสที่อยู่ (address bus ) จึงเป็นที่มาของชื่อนี้ ในการใช้งานสมัยใหม่บนสถาปัตยกรรมส่วนใหญ่ ข้อผิดพลาดเหล่านี้เกิดขึ้นได้ยากกว่าข้อผิดพลาดของการแบ่งส่วนหน่วยความจำ (Segmentation fault)ซึ่งส่วนใหญ่เกิดจากการละเมิดการเข้าถึงหน่วยความจำ เช่น ปัญหาในที่อยู่เชิงตรรกะหรือสิทธิ์การเข้าถึง

บน แพลตฟอร์มที่รองรับมาตรฐาน POSIXข้อผิดพลาดของบัสโดยทั่วไปจะส่งผลให้มีการส่งสัญญาณ SIGBUS ไปยังกระบวนการที่ก่อให้เกิดข้อผิดพลาดนั้น SIGBUS อาจเกิดจากความผิดพลาดของอุปกรณ์ทั่วไปที่คอมพิวเตอร์ตรวจพบได้เช่นกัน แม้ว่าข้อผิดพลาดของบัสจะไม่ค่อยหมายความว่าฮาร์ดแวร์ของคอมพิวเตอร์เสียหายทางกายภาพก็ตาม โดยปกติแล้วมักเกิดจากข้อบกพร่องในซอฟต์แวร์นอกจากนี้ ข้อผิดพลาดของบัสอาจเกิดขึ้นจากข้อผิดพลาดในการเพจจิ้งอื่นๆ ด้วย โปรดดูรายละเอียดเพิ่มเติมด้านล่าง

สาเหตุ

สาเหตุหลักอย่างน้อยสามประการที่ทำให้เกิดข้อผิดพลาดบนบัส ได้แก่:

ที่อยู่ไม่มีอยู่จริง

ซอฟต์แวร์จะสั่งการให้ CPU อ่านหรือเขียนที่อยู่หน่วยความจำทาง กายภาพที่เฉพาะเจาะจง จากนั้น CPU จะตั้งค่าที่อยู่ทางกายภาพนี้บนบัสแอดเดรส ของมัน และร้องขอให้ฮาร์ดแวร์อื่นๆ ที่เชื่อมต่อกับ CPU ตอบกลับด้วยผลลัพธ์ หากฮาร์ดแวร์เหล่านั้นตอบสนองต่อที่อยู่เฉพาะนี้ หากไม่มีฮาร์ดแวร์อื่นใดตอบสนอง CPU จะส่งข้อผิดพลาดโดยระบุว่าที่อยู่ทางกายภาพที่ร้องขอไม่ได้รับการยอมรับจากระบบคอมพิวเตอร์ทั้งหมด โปรดทราบว่านี่ครอบคลุมเฉพาะ ที่อยู่หน่วยความจำ ทางกายภาพ เท่านั้น การพยายามเข้าถึง ที่อยู่หน่วย ความจำเสมือน ที่ไม่กำหนดไว้ โดยทั่วไปถือว่าเป็นข้อผิดพลาดในการแบ่งส่วน (segmentation fault) มากกว่าข้อผิดพลาดของบัส (bus error) แม้ว่าหาก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 ]อย่างไรก็ตาม ข้อมูลอาจถูกดึงมาจากที่อยู่ใดก็ได้ในหน่วยความจำ และอาจมีหนึ่งไบต์หรือมากกว่านั้น ขึ้นอยู่กับคำสั่ง

โดยทั่วไปแล้ว CPU จะเข้าถึงข้อมูลที่ความกว้างเต็มของบัสข้อมูลตลอดเวลา ในการเข้าถึงไบต์ CPU จะเข้าถึงหน่วยความจำที่ความกว้างเต็มของบัสข้อมูล จากนั้นจึงทำการมาสก์และเลื่อนเพื่อเข้าถึงไบต์แต่ละตัว ระบบยอมรับอัลกอริทึมที่ไม่ประสิทธิภาพนี้ได้ เนื่องจากเป็นคุณสมบัติที่จำเป็นสำหรับซอฟต์แวร์ส่วนใหญ่ โดยเฉพาะอย่างยิ่ง การประมวลผล สตริงต่างจากไบต์ หน่วยที่ใหญ่กว่าสามารถครอบคลุมที่อยู่สองตำแหน่งที่จัดเรียงกันได้ ดังนั้นจึงต้องใช้การดึงข้อมูลบนบัสมากกว่าหนึ่งครั้ง CPU สามารถรองรับฟังก์ชันนี้ได้ แต่ฟังก์ชันนี้ไม่ค่อยจำเป็นโดยตรงใน ระดับ รหัสเครื่องดังนั้นนักออกแบบ CPU จึงมักหลีกเลี่ยงการใช้งานและออกข้อผิดพลาดของบัสสำหรับการเข้าถึงหน่วยความจำที่ไม่จัดเรียงกันแทน

ข้อผิดพลาดในการเพจ

FreeBSD , LinuxและSolarisสามารถส่งสัญญาณข้อผิดพลาดของบัสเมื่อไม่สามารถเรียกเพจหน่วยความจำเสมือนเข้ามาได้เช่น เนื่องจากเพจนั้นหายไป (เช่น การเข้าถึงไฟล์ที่แมปหน่วยความจำหรือการเรียกใช้ภาพไบนารีที่ถูกตัดทอนในขณะที่โปรแกรมกำลังทำงาน) [ 2 ] หรือเนื่องจาก ไฟล์ที่แมปหน่วยความจำที่เพิ่งสร้างขึ้นไม่สามารถจัดสรรทางกายภาพได้ เนื่องจากดิสก์เต็ม

เซ็กเมนต์ที่ไม่มีอยู่ (x86)

บนสถาปัตยกรรม x86มีกลไกการจัดการหน่วยความจำแบบเก่าที่เรียกว่าการแบ่งส่วน (segmentation ) หากแอปพลิเคชันโหลดรีจิสเตอร์ส่วน (segment register) ด้วยตัวเลือกของส่วนที่ไม่มีอยู่จริง (ซึ่งในระบบปฏิบัติการที่รองรับ POSIX สามารถทำได้ด้วยภาษาแอสเซมบลี เท่านั้น ) จะเกิดข้อยกเว้นขึ้น ระบบปฏิบัติการบางระบบใช้กลไกนี้สำหรับการสลับข้อมูล แต่ใน Linux จะสร้างสัญญาณ 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 ;/* เข้าถึงค่าที่ชี้โดยตัวชี้ int ซึ่งทำให้เกิดการเข้าถึงที่ไม่ตรงแนว */ * iptr = 42 ;/*  การเข้าถึงต่อไปนี้จะส่งผลให้เกิดข้อผิดพลาด sigbus ด้วยเช่นกัน short *sptr;  int i; sptr = (short *)&i;  // สำหรับการเพิ่มค่าคี่ทั้งหมด จะได้ผลลัพธ์เป็น sigbus  sptr = (short *)(((char *)sptr) + 1);  *sptr = 100;  */ส่งคืนค่า0 ; }

การคอมไพล์และรันตัวอย่างบน ระบบปฏิบัติการที่รองรับ POSIXบนสถาปัตยกรรมx86แสดงให้เห็นข้อผิดพลาดดังนี้:

$ gcc -ansi sigbus.c -o sigbus $ ./sigbus Bus error $ gdb ./sigbus (gdb) r Program received signal SIGBUS, Bus error. 0x080483ba in 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)

ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=Bus_error&oldid=1305828223 "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ ข้อผิดพลาดของบัส

ในด้าน คอมพิวเตอร์ ข้อผิดพลาดของบัส (Bus error ) คือ ความผิดพลาด ที่เกิดขึ้นจากฮาร์ดแวร์ ซึ่งแจ้งให้ ระบบปฏิบัติการ (OS) ทราบว่ากระบวนการหนึ่งกำลังพยายามเข้าถึง หน่วยความจำ ที่...

สาเหตุ

สาเหตุหลักอย่างน้อยสามประการที่ทำให้เกิดข้อผิดพลาดบนบัส ได้แก่:

ที่อยู่ไม่มีอยู่จริง

ซอฟต์แวร์จะสั่งการให้ CPU อ่านหรือเขียน ที่อยู่หน่วยความจำทาง กายภาพที่เฉพาะเจาะจง จากนั้น CPU จะตั้งค่าที่อยู่ทางกายภาพนี้บน บัสแอดเดรส ของมัน และร้องขอให้ฮาร์ดแวร์อื่นๆ ที่เชื่อมต่อกับ CPU ตอบกลับด้วยผลลัพธ์ หากฮาร์ดแวร์เหล่านั้นตอบสนองต่อที่อยู่เฉพาะนี้...

การเข้าถึงที่ไม่สอดคล้องกัน

ซีพียูส่วนใหญ่สามารถ เข้าถึงได้ทีละไบต์ โดยที่แต่ละที่อยู่หน่วยความจำที่ไม่ซ้ำกันจะหมายถึง ไบต์ ขนาด 8 บิต ซีพียูส่วนใหญ่สามารถเข้าถึงไบต์แต่ละตัวจากที่อยู่หน่วยความจำแต่ละแห่งได้ แต่โดยทั่วไปแล้วจะไม่สามารถเข้าถึงหน่วยที่ใหญ่กว่า (16 บิต, 32 บิต, 64 บิต...