Почему эта ошибка шины возникает при чтении объекта общей памяти?
Версия: Ubuntu 22.04.3GCC: 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04)
Привет,
Я пытаюсь создать программу с очень большим объектом общей памяти. Это делается на экземпляре AWS EC2 со 130 ГБ ОЗУ. shm_open(), ftruncate() и mmap() не выдают ошибок, если создается объект общей памяти размером до 120 ГБ. Однако когда каждая ячейка памяти в объекте общей памяти выполняется и читается, возникает ошибка шины. Я создал небольшую тестовую программу, которая дает точно повторяемые результаты.
Обратите внимание, что shmmax = 18446744073692774399, shmall = 18446744073692774399 и shmmni = 8092.
При взгляде на нижнюю часть объекта общей памяти и чтении возникает ошибка шины по адресу 66 936954880. При запуске сверху (79 999 999 999) и чтении вниз возникает ошибка шины после 13063041023 операций чтения. Итак, 66 936958 976 снизу. Таким образом, между местом возникновения ошибки шины существует разрыв в одну страницу (4096).
Есть идеи, что может произойти?
Спасибо,
Ген
Очень простая тестовая программа C/C++, показывающая проблему. Объект общей памяти просто жестко запрограммирован на 80 ГБ. Измените закомментированную строку, чтобы она увеличивалась или уменьшалась через объект общей памяти.
// g++ -std=c++20 -O3 test2.cpp -W -Wall -Wextra -pedantic -pthread -o test2
#include <iostream>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
int main() {
uint_fast64_t mem_amt = 80000000000;
std::cout << "mem_amt = " << mem_amt << "\n";
int fd;
std::string shmpath = "/foo";
// Remove any existing shared memory object
shm_unlink(shmpath.c_str());
// Create the shared memory object with read-write access.
fd = shm_open(shmpath.c_str(), O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
if (fd == -1) {
std::cerr << "\nshm_open shmbuf failure. Exiting program.\n\n";
exit(EXIT_FAILURE);
}
// Truncate (set) the size.
if (ftruncate64(fd, mem_amt) == -1) {
std::cerr << "\nftruncate shmbuf failure. Exiting program.\n\n";
exit(EXIT_FAILURE);
}
// Map the shared memory object.
char* pool = (char*)mmap(NULL, mem_amt, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (pool == MAP_FAILED) {
std::cerr << "\nmmap pool failure. Exiting program.\n\n";
exit(EXIT_FAILURE);
}
std::cout << "pool = " << (uint_fast64_t)pool << "\n";
char temp;
for (uint_fast64_t i=0; i<mem_amt; i++) {
// for (uint_fast64_t i=mem_amt-1; i>0; i--) {
temp = pool[i];
if (i % 5000000000 == 0) {
std::cout << "i = " << i << "\n";
}
}
std::cout << "temp = " << temp << "\n";
}
gbd вывод основных файлов с увеличением и уменьшением соответственно:
Core was generated by `./test2'.
Program terminated with signal SIGBUS, Bus error.
#0 0x00005570b7fd1373 in main () at test2.cpp:47
47 temp = pool[i];
(gdb) bt full
#0 0x00005570b7fd1373 in main () at test2.cpp:47
i = 66936954880
mem_amt = 80000000000
fd = <optimized out>
shmpath = "/foo"
pool = 0x7fa09da0e000 ""
temp = <optimized out>
(gdb)
Core was generated by `./test2'.
Program terminated with signal SIGBUS, Bus error.
#0 0x000055e242fdc379 in main () at test2.cpp:47
47 temp = pool[i];
(gdb) bt full
#0 0x000055e242fdc379 in main () at test2.cpp:47
i = 13063041023
mem_amt = 80000000000
fd = <optimized out>
shmpath = "/foo"
pool = 0x7f7366a0e000 ""
temp = <optimized out>
(gdb)