2008-10-17 57 views
203

Thông báo "lỗi xe buýt" có nghĩa là gì và nó khác với một segfault như thế nào?Lỗi bus là gì?

+2

Tôi muốn thêm giải thích đơn giản cho cả hai: Lỗi phân đoạn có nghĩa là bạn đang cố gắng truy cập vào bộ nhớ mà bạn không được phép (e. G. Nó không phải là một phần của chương trình của bạn). Tuy nhiên, trên một lỗi bus thường có nghĩa là bạn đang cố truy cập bộ nhớ không tồn tại (ví dụ: bạn cố gắng truy cập địa chỉ ở 12G nhưng bạn chỉ có bộ nhớ 8G) hoặc nếu bạn vượt quá giới hạn bộ nhớ có thể sử dụng. – xdevs23

Trả lời

189

lỗi Bus rất hiếm hiện nay trên x86 và xảy ra khi vi xử lý của bạn thậm chí không thể cố gắng truy cập bộ nhớ được yêu cầu, thường:

  • sử dụng một hướng dẫn xử lý với một địa chỉ không đáp ứng yêu cầu liên kết của nó.

lỗi Segmentation xảy ra khi truy cập vào bộ nhớ mà không thuộc về quá trình của bạn, họ đang rất phổ biến và thường là kết quả của:

  • sử dụng một con trỏ đến một cái gì đó đã được deallocated.
  • bằng cách sử dụng con trỏ do đó không được khởi tạo.
  • bằng cách sử dụng con trỏ rỗng.
  • tràn bộ đệm.

PS: Để chính xác hơn, điều này không phải là thao tác với chính con trỏ sẽ gây ra sự cố, nó truy cập vào bộ nhớ mà nó trỏ đến (dereferencing).

+71

Chúng không hiếm; Tôi chỉ tập thể dục 9 từ Làm thế nào để tìm hiểu C cách cứng và đã gặp phải một ... – 11684

+11

Một nguyên nhân khác của lỗi bus (trên Linux anyway) là khi hệ điều hành không thể quay trở lại một trang ảo với bộ nhớ vật lý (ví dụ Thông thường các ký tự mmap (và malloc) chỉ cần đặt trước vùng địa chỉ ảo, và hạt nhân gán bộ nhớ vật lý theo yêu cầu (được gọi là lỗi trang mềm.) Thực hiện đủ lớn malloc, và sau đó viết cho đủ của nó và bạn sẽ nhận được một lỗi xe buýt. – Eloff

+0

cho tôi phân vùng chứa '/ var/cache' chỉ đơn giản là đầy đủ https://askubuntu.com/a/915520/493379 – c33s

2

Tùy thuộc vào hệ điều hành, CPU, Trình biên dịch và các yếu tố khác có thể. Nói chung nó có nghĩa là CPU bus không thể hoàn thành một lệnh, hoặc bị xung đột, nhưng điều đó có thể có nghĩa là một loạt các thứ phụ thuộc vào môi trường và mã đang được chạy.

-Adam

9

Tôi tin rằng hạt nhân tăng SIGBUS khi một triển lãm ứng dụng dữ liệu lệch chi tiết trên xe buýt dữ liệu. Tôi nghĩ rằng vì hầu hết [?] Trình biên dịch hiện đại cho hầu hết các bộ vi xử lý pad/align dữ liệu cho các lập trình viên, các rắc rối liên kết của ngày xưa (ít nhất) giảm nhẹ, và do đó ta không thấy SIGBUS quá thường xuyên trong những ngày (AFAIK).

Từ: Here

+0

Phụ thuộc vào các thủ thuật khó chịu mà bạn đang thực hiện với mã của mình. Bạn có thể kích hoạt một lỗi BUS/Alignment Trap nếu bạn làm điều gì đó ngớ ngẩn như làm phép toán con trỏ và sau đó gõ để truy cập vào một chế độ vấn đề (tức là bạn thiết lập một mảng uint8_t, thêm một, hai, hoặc ba vào con trỏ của mảng và sau đó gõ một đoạn ngắn, int, hoặc dài và cố gắng truy cập vào kết quả vi phạm.) Các hệ thống X86 sẽ cho phép bạn thực hiện điều này, mặc dù có một hình phạt thực sự thực sự. * MỘT SỐ * Các hệ thống ARMv7 sẽ cho phép bạn thực hiện điều này - nhưng hầu hết các ARM, MIPS, Power, v.v. sẽ gắp bạn vào nó. – Svartalf

68

Một segfault đang truy cập bộ nhớ rằng bạn không được phép truy cập. Đó là chỉ đọc, bạn không có quyền, v.v ...

Lỗi bus đang cố truy cập bộ nhớ không thể ở đó. Bạn đã sử dụng địa chỉ vô nghĩa đối với hệ thống hoặc loại địa chỉ sai cho hoạt động đó.

2

Thông thường có nghĩa là truy cập không được căn chỉnh.

Nỗ lực truy cập bộ nhớ không có mặt vật lý cũng sẽ gây ra lỗi bus, nhưng bạn sẽ không thấy điều này nếu bạn đang sử dụng bộ xử lý có MMU và hệ điều hành không lỗi, vì bạn đã thắng ' t có bất kỳ bộ nhớ không tồn tại nào được ánh xạ tới không gian địa chỉ của tiến trình của bạn.

+2

i7 của tôi chắc chắn có một MMU, nhưng tôi vẫn gặp lỗi này trong khi học C trên OS X (chuyển con trỏ chưa được khởi tạo sang 'scanf'). Điều đó có nghĩa là OS X Mavericks là lỗi? Điều gì sẽ là hành vi trên một hệ điều hành không lỗi? –

3

Một trường hợp điển hình của lỗi xe buýt trên một số kiến ​​trúc cụ thể, chẳng hạn như SPARC (ít nhất một số SPARC, có thể điều này đã được thay đổi), là khi bạn thực hiện truy cập sai. Ví dụ:

unsigned char data[6]; 
(unsigned int *) (data + 2) = 0xdeadf00d; 

đoạn này cố gắng để viết 32-bit số nguyên giá trị 0xdeadf00d đến một địa chỉ đó là (rất có thể) không phù hợp đúng cách, và sẽ tạo ra một lỗi xe buýt trên kiến ​​trúc mà là "kén cá chọn canh" trong việc này liên quan. Intel x86, bằng cách này, không kiến ​​trúc như vậy, nó sẽ cho phép truy cập (mặc dù thực thi nó chậm hơn).

+1

Trong trường hợp, tôi có dữ liệu [8]; Đây là một bội số của 4 trong kiến ​​trúc 32 bit. Vì vậy, nó là phù hợp. Tôi vẫn sẽ nhận được lỗi ngay bây giờ? Ngoài ra, hãy giải thích, đó là một ý tưởng tồi để chuyển đổi loại dữ liệu cho con trỏ. Nó sẽ gây ra sai lệch liên kết lỗi trên một kiến ​​trúc mong manh. Xin hãy giải thích, Nó sẽ giúp tôi. –

+0

Heh. Nó không phải là quá nhiều loại chuyển đổi khi bạn đang làm loại chuyển đổi trên một con trỏ mà bạn đã thực hiện toán học con trỏ trên. Nhìn * cẩn thận * ở đoạn mã trên. Trình biên dịch đã khéo léo dword liên kết con trỏ của bạn cho dữ liệu và sau đó bạn vặn tất cả mọi thứ lên trên trình biên dịch bằng cách bù đắp tham chiếu của TWO và typecasting đến rất nhiều cần phải được dword liên kết truy cập vào những gì sẽ là một ranh giới không dword. – Svartalf

+0

"Mong muốn" không phải là từ tôi muốn sử dụng cho tất cả những điều này.X86 máy và mã đã có những người làm những điều khá ngớ ngẩn trong một thời bây giờ, đây là một trong số họ. Hãy suy nghĩ lại mã của bạn nếu bạn gặp phải vấn đề này - nó không thực sự hiệu quả trên X86 để bắt đầu. – Svartalf

5

Bạn cũng có thể nhận SIGBUS khi không thể phân trang trang mã vì một số lý do.

+4

Điều này thường xảy ra khi tôi cập nhật tệp .so trong khi chạy quá trình – poordeveloper

+0

Một lý do khác xảy ra là nếu bạn cố gắng 'mmap' một tệp lớn hơn kích thước của'/dev/shm' – ilija139

-1

Một lỗi tràn bộ đệm điển hình mà kết quả trong lỗi Bus là,

{ 
    char buf[255]; 
    sprintf(buf,"%s:%s\n", ifname, message); 
} 

đây nếu kích thước của chuỗi trong dấu ngoặc kép ("") là hơn kích thước buf nó mang lại cho lỗi xe buýt.

+1

Heh ... nếu đây là trường hợp, bạn có mối lo ngại về lỗi BUS thay vì ngăn xếp khai thác ngăn xếp bạn đọc mọi lúc Windows và các máy khác. Lỗi BUS là do cố gắng truy cập "bộ nhớ" mà máy không thể truy cập vì địa chỉ không hợp lệ. (Do đó thuật ngữ "BUS" lỗi.) Điều này có thể do một loạt các lỗi, bao gồm sắp xếp không hợp lệ, và miễn là bộ vi xử lý không thể đặt địa chỉ ON các tuyến xe buýt. – Svartalf

0

Để thêm vào những gì blxtd đã trả lời ở trên, lỗi xe buýt cũng xảy ra khi quá trình của bạn không thể truy cập bộ nhớ của một 'biến' cụ thể.

for (j = 0; i < n; j++) { 
       for (i =0; i < m; i++) { 
         a[n+1][j] += a[i][j]; 
       } 
     } 

Thông báo của vô ý 'sử dụng biến 'i' trong đầu tiên 'cho vòng lặp'? Đó là nguyên nhân gây ra lỗi bus trong trường hợp này.

2

Một ví dụ cụ thể của một lỗi xe buýt tôi chỉ gặp trong khi lập trình C trên OS X:

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

int main(void) 
{ 
    char buffer[120]; 
    fgets(buffer, sizeof buffer, stdin); 
    strcat("foo", buffer); 
    return 0; 
} 

Trong trường hợp bạn không nhớ các tài liệu strcat gắn thêm đối số thứ hai để là người đầu tiên bằng cách thay đổi số đầu tiên (lật đối số và nó hoạt động tốt). Trên linux, điều này cho một lỗi segmentation (như mong đợi), nhưng trên OS X nó cho một lỗi bus. Tại sao? Tôi thực sự không biết.

+0

Có lẽ ngăn xếp tràn bảo vệ làm tăng lỗi bus. – Joshua

+1

'" foo "' được lưu trữ trong một phân đoạn chỉ đọc của bộ nhớ, do đó không thể ghi vào nó. Nó sẽ không được ngăn xếp tràn bảo vệ, chỉ cần ghi nhớ bảo vệ (đây là một lỗ hổng bảo mật nếu chương trình của bạn có thể viết lại chính nó). –

0

Tôi chỉ phát hiện ra một cách khó khăn mà trên bộ vi xử lý ARMv7 bạn có thể viết một số mã cung cấp cho bạn lỗi phân đoạn khi không được tối ưu hóa, nhưng cung cấp cho bạn lỗi bus khi được biên dịch bằng -O2 (tối ưu hóa nhiều hơn). Tôi đang sử dụng trình biên dịch gnueabihf của gcc arm từ ubuntu x64.

3

mmap tối thiểu POSIX 7 dụ

"Bus lỗi" xảy ra khi hạt nhân gửi SIGBUS đến một quá trình.

Một ví dụ rất nhỏ mà tạo ra nó vì ftruncate đã bị lãng quên:

#include <fcntl.h> /* O_ constants */ 
#include <unistd.h> /* ftruncate */ 
#include <sys/mman.h> /* mmap */ 

int main() { 
    int fd; 
    int *map; 
    int size = sizeof(int); 
    char *name = "/a"; 

    shm_unlink(name); 
    fd = shm_open(name, O_RDWR | O_CREAT, (mode_t)0600); 
    /* THIS is the cause of the problem. */ 
    /*ftruncate(fd, size);*/ 
    map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 
    /* This is what generates the SIGBUS. */ 
    *map = 0; 
} 

Run with:

gcc -std=c99 main.c -lrt 
./a.out 

Tested trong Ubuntu 14.04.

POSIX describesSIGBUS như:

Tiếp cận một phần không xác định của một đối tượng bộ nhớ.

Các mmap spec nói rằng:

Tài liệu tham khảo trong phạm vi địa chỉ bắt đầu từ pa và tiếp tục trong byte len cho toàn bộ các trang sau khi kết thúc của một đối tượng sẽ dẫn đến phân phối một tín hiệu SIGBUS.

shm_opensays that nó tạo ra đối tượng kích thước 0:

Đối tượng bộ nhớ chia sẻ có kích thước bằng không.

Vì vậy, tại *map = 0 chúng tôi đang chạm vào cuối đối tượng được phân bổ.

1

Lý do của tôi cho lỗi xe buýt trên Mac OS X là tôi đã cố gắng phân bổ khoảng 1Mb trên ngăn xếp. Điều này làm việc tốt trong một chủ đề, nhưng khi sử dụng openMP, điều này dẫn đến lỗi bus, vì Mac OS X rất hạn chế stack size for non-main threads.

-2

Điều này cũng có thể đề cập đến vấn đề của con người. Trong nhiều lĩnh vực nghiên cứu khác nhau (có lẽ rộng hơn), tiếng lóng "lỗi xe buýt" có ý nghĩa khác, điều mà tôi nghĩ có thể là một câu trả lời có liên quan. Khi chỉ có một người biết cách làm điều gì đó quan trọng đối với quy trình làm việc cụ thể, và người đó đột nhiên không có sẵn (tức là, "nằm dưới xe buýt" - nhưng rất có thể chỉ cần lên và rời khỏi bất ngờ), điều này được gọi là một lỗi bus. Nó chỉ là thảm họa như một lỗi xe buýt "thực sự", vì không có kiến ​​thức của người này về cách duy trì hoặc thậm chí thực hiện quy trình nghiên cứu, toàn bộ hệ thống bị xáo trộn. Dễ bị lỗi xe buýt là một dấu hiệu của quản lý xấu.

2

Tôi đã gặp lỗi bus khi thư mục gốc ở mức 100%.