2010-01-15 32 views
15

Tôi đang cố gắng hết sức để gặp lỗi xe buýt.Làm thế nào để có được một "lỗi xe buýt"?

Một cách là truy cập không đúng chỗ và tôi đã thử các ví dụ được cung cấp herehere, nhưng không có lỗi đối với tôi - các chương trình thực thi tốt.

Có tình huống nào đó chắc chắn tạo ra lỗi xe buýt không?

+2

kiến ​​trúc nền tảng gì và phần cứng bạn đang sử dụng? –

+0

cần lưu ý rằng theo mặc định x86 sẽ không có lỗi xe buýt, thay vào đó nó sẽ hoạt động nhưng truy cập bộ nhớ sẽ không phải là biểu diễn dưới dạng đọc được căn chỉnh. Mặt khác, các vòm SPARC có lỗi bus. –

+1

Không, xem bình luận của Michael Burr và câu trả lời của tôi. Ngay cả trên x86, bạn có thể gặp lỗi bus bằng cách cố truy cập bộ nhớ không tồn tại (trái ngược với lỗi phân đoạn, xuất phát từ vi phạm chính sách truy cập). – ephemient

Trả lời

12

lỗi Bus chỉ có thể được gọi trên nền tảng phần cứng rằng:

  1. Yêu cầu liên kết truy cập, và
  2. Đừng bù đắp cho một truy cập unaligned bằng cách thực hiện hai truy cập liên kết và kết hợp các kết quả.

Có thể bạn không có quyền truy cập vào hệ thống như vậy.

+0

có cách nào để đảm bảo điều đó không? – Lazer

+0

@eSKay: Nếu bạn đang sử dụng CPU Intel, có nghĩa là về cơ bản bất kỳ máy tính cá nhân nào ngày nay, bạn sẽ không bao giờ gặp lỗi bus khi truy cập không đúng. Nếu bạn đang sử dụng PowerPC, SPARC, v.v. thì bạn có thể gây ra lỗi xe buýt theo cách đó. –

+2

Bạn có thiết bị SPARC hoặc MIPS nào không? –

0

đơn giản, ghi vào bộ nhớ mà không phải của mình:

int main() 
{ 
    char *bus_error = 0; 

    *bus_error = 'X'; 
} 

tức thì lỗi xe buýt trên PowerPC Mac của tôi [OS X 10.4, kép 1GHz PPC7455 của], không nhất thiết phải trên phần cứng của bạn và/hoặc hệ điều hành .

Thậm chí còn có wikipedia article về lỗi xe buýt, bao gồm cả chương trình tạo một lỗi.

+3

Trên phần cứng hiện đại dẫn đến lỗi phân đoạn, không phải lỗi xe buýt. –

+1

Điều này đã được biên soạn trên máy Mac PowerPC của tôi, khá "hiện đại". Nhưng cùng một mã trên hai máy x86 tiện dụng của tôi, bạn nói đúng. – Seth

+1

Điều này cũng phụ thuộc vào HĐH và cấu hình của bạn - nếu tôi chạy nó trên PowerPC Mac đang chạy Linux, tôi nhận được SIGSEGV. OS X thích cung cấp SIGBUS trong nhiều tình huống hơn so với Linux; nó không giống như POSIX luôn luôn ủy nhiệm một tín hiệu hoặc khác ... – ephemient

1

Cũng xin lưu ý rằng một số hệ điều hành báo cáo "lỗi bus" cho các lỗi ngoài truy cập không được điều chỉnh. Bạn đã không đề cập đến trong câu hỏi của bạn những gì nó đã được bạn thực sự cố gắng để đạt được. Có thể thử như sau:

int *x = 0; 
*x=1; 

trang Wikipedia bạn liên quan đến đề cập rằng việc truy cập vào bộ nhớ không tồn tại cũng có thể cho kết quả là một lỗi xe buýt. Bạn có thể có may mắn hơn với tải một địa chỉ không xác định được biết đến vào một con trỏ và dereferwncing đó.

-1

Lỗi xe buýt xảy ra nếu bạn cố gắng truy cập vào bộ nhớ mà máy tính của bạn không thể giải quyết được. Ví dụ: bộ nhớ máy tính của bạn có dải địa chỉ 0x00 đến 0xFF nhưng bạn cố gắng truy cập phần tử bộ nhớ ở mức 0x0100 hoặc cao hơn.

Thực tế, máy tính của bạn sẽ có phạm vi lớn hơn 0x00 đến 0xFF.

Để trả lời bài gốc của bạn:

Tell me some situation which is sure to produce a bus error.

Trong code của bạn, chỉ số vào bộ nhớ cách ngoài phạm vi giới hạn bộ nhớ tối đa. Tôi không ... sử dụng một số loại giá trị hex khổng lồ 0xFFFFFFFFFFFFFFFFFF được lập chỉ mục thành một ... *

+0

Một "giá trị hex khổng lồ" như vậy sẽ tràn khi nó vừa với con trỏ . Hầu hết các hệ điều hành nên bảo vệ bộ nhớ không thể truy cập anyway vì vậy bạn sẽ chỉ cần nhấn một SIGSEGV chứ không phải là một lỗi xe buýt. –

15

Điều này đáng tin cậy sẽ dẫn đến SIGBUS trên hệ thống tuân thủ POSIX.

#include <unistd.h> 
#include <stdio.h> 
#include <sys/mman.h> 
int main() { 
    FILE *f = tmpfile(); 
    int *m = mmap(0, 4, PROT_WRITE, MAP_PRIVATE, fileno(f), 0); 
    *m = 0; 
    return 0; 
} 

Từ Độc Unix Specification, mmap:

References within the address range starting at pa and continuing for len bytes to whole pages following the end of an object shall result in delivery of a SIGBUS signal.

+0

Rất đẹp. Tôi đã xác minh rằng điều này gây ra lỗi xe buýt trên cả openSUSE 11.1 và Darwin 10.2.0 (ví dụ: Mac OS x 10.6.2). –

+0

Tôi biết đây là một chủ đề cũ nhưng .. Bất cứ ai có thể giải thích lý do tại sao điều này gây ra một 'lỗi bus'? Tôi hiểu rằng lỗi bus xảy ra trên dòng '* m = 0;', nhưng tôi không thấy nó liên quan đến lời giải thích của tín hiệu SIGBUS được trích dẫn như thế nào trong câu trả lời này .. – digawp

3

Như những người khác đã đề cập đến điều này rất nền tảng cụ thể.Trên hệ thống ARM tôi đang làm việc với (không có bộ nhớ ảo), có một phần lớn không gian địa chỉ không có bộ nhớ hoặc thiết bị ngoại vi được gán. Nếu tôi đọc hoặc viết một trong những địa chỉ đó, tôi gặp lỗi bus.

Bạn cũng có thể gặp lỗi bus nếu có sự cố phần cứng trên xe buýt.

Nếu bạn đang chạy trên nền tảng có bộ nhớ ảo, bạn có thể không cố ý tạo ra lỗi bus với chương trình trừ khi đó là trình điều khiển thiết bị hoặc phần mềm chế độ hạt nhân khác. Truy cập bộ nhớ không hợp lệ có thể bị bẫy như một sự vi phạm truy cập hoặc tương tự như trình quản lý bộ nhớ (và nó thậm chí không bao giờ có cơ hội để truy cập vào bus).

6

Hãy thử một cái gì đó dọc theo dòng: (! Tôi biết, có lẽ không phải là câu trả lời mà bạn muốn, nhưng nó gần như chắc chắn giúp bạn có một "lỗi xe buýt")

#include <signal.h> 
int main(void) 
{ 
    raise(SIGBUS); 
    return 0; 
} 

1

Làm thế nào về vấn đề này ? chưa được kiểm tra.

#include<stdio.h> 

    typedef struct 
    { 
    int a; 
    int b; 
    } busErr; 

    int main() 
    { 
    busErr err; 
    char * cPtr; 
    int *iPtr; 
    cPtr = (char *)&err; 
    cPtr++; 
    iPtr = (int *)cPtr; 
    *iPtr = 10; 
    } 
3

trên linux với một CPU Intel thử điều này:

int main(int argc, char **argv) 
{ 
# if defined i386 
    /* enable alignment check (AC) */ 
    asm("pushf; " 
    "orl $(1<<18), (%esp); " 
    "popf;"); 
# endif 

    char d[] = "12345678"; /* yep! - causes SIGBUS even on Linux-i386 */ 
    return 0; 
} 

thủ thuật ở đây là để thiết lập "liên kết kiểm tra" bit trong một trong những CPU "đặc biệt" đăng ký.

also see: here

3

Tôi chắc chắn rằng bạn phải sử dụng máy x86. Cpu X86 không tạo ra lỗi bus trừ khi cờ AC của nó trong thanh ghi EFALAGS được thiết lập.

Hãy thử mã này:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(void) 
{ 
    char *p; 

    __asm__("pushf\n" 
      "orl $0x40000, (%rsp)\n" 
      "popf"); 

    /* 
    * malloc() always provides aligned memory. 
    * Do not use stack variable like a[9], depending on the compiler you use, 
    * a may not be aligned properly. 
    */ 
    p = malloc(sizeof(int) + 1); 
    memset(p, 0, sizeof(int) + 1); 

    /* making p unaligned */ 
    p++; 

    printf("%d\n", *(int *)p); 

    return 0; 
} 

Thông tin thêm về điều này có thể được tìm thấy tại lỗi http://orchistro.tistory.com/206

+0

Tôi đã thử nghiệm này trên máy của mình và tôi có SIGBUS. Nhưng sau đó tôi gỡ bỏ tất cả các dòng trừ dòng '__asm__' và' return 0; 'và tôi vẫn nhận được SIGBUS. Vì vậy, phải có một số truy cập chưa được sắp xếp khác xảy ra, có lẽ từ thư viện CRT. –

1
int main(int argc, char **argv) 
{ 
    char *bus_error = new char[1]; 
    for (int i=0; i<1000000000;i++) { 
     bus_error += 0xFFFFFFFFFFFFFFF; 
    *(bus_error + 0xFFFFFFFFFFFFFF) = 'X'; 
    } 
} 

Bus: 10 (core dumped)

Các vấn đề liên quan