Почему эта ошибка шины возникает при чтении объекта общей памяти?

Версия: 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)

0 ответов

Другие вопросы по тегам