Аномальная ошибка шины для доступа к защищенной памяти в macOS?

контекст

Я написал небольшую программу с намерением использовать ее для генерации SIGSEGV сигнал, который я поймаю обработчиком, а затем распечатать.

проблема

Программа, которую я написал, прекрасно работает (или, кажется, так) в Linux. Однако при компиляции и выполнении в macOS 10.11.6 он не может генерировать SIGSEGV, но вместо этого генерирует Bus error: 10,

Решения попытались

Исследуя, сталкивались ли другие с этой ошибкой, я натолкнулся на следующее сообщение:

/questions/12356556/povedenie-protread-i-protwrite-s-pomoschyu-mprotect/12356567#12356567

К сожалению, пока я переключился с использования posix_memalign в mmapЯ все еще получаю ошибку автобуса. Я не могу найти похожие вопросы, которые могут помочь, кроме этого.

программа

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <sys/mman.h>

/*
 *******************************************************************************
 *                              Global Variables                               *
 *******************************************************************************
*/

// Page size.
int pagesize;

// Pointer to allocated memory page. 
void *page;

/*
 *******************************************************************************
 *                               Signal Handlers                               *
 *******************************************************************************
*/

// Handler: Invalid memory reference.
void handler_sigseg (int sig, siginfo_t *si, void *ignore) {

    // Mask SIGSEGV.
    if (sig != SIGSEGV) {
        return;
    }

    // Output siginfo fields.
    printf("si_signo = %d\n", si->si_signo);
    printf("si_code = %d\n", si->si_code);
    printf("si_value.sival_int = %d\n", si->si_value.sival_int);
    printf("si_errno = %d\n", si->si_errno);
    printf("si_pid = %d\n", si->si_pid);
    printf("si_uid = %d\n", si->si_uid);
    printf("si_statis = %d\n", si->si_status);

    // Grant writing protection.
    if (mprotect(page, pagesize, PROT_WRITE) == -1) {
        fprintf(stderr, "Error: Attempt to set memory access perms failed!\n");
        exit(EXIT_FAILURE);
    }

    return;
} 


/*
 *******************************************************************************
 *                                Main Routine                                 *
 *******************************************************************************
*/

int main (void) {

    /*
     ***************************************************************************
     *                              Memory Setup                               *
     ***************************************************************************
    */

    // Set page size.  
    pagesize = sysconf(_SC_PAGE_SIZE);

    printf("pagesize = %d\n", pagesize);

    // Allocate memory page, created at nearby page boundary. 
    if ((page = mmap(NULL, pagesize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
        fprintf(stderr, "Error: mmap allocation failed!\n");
        exit(EXIT_FAILURE);
    }

    // Zero out memory block. 
    memset(page, 0, pagesize);

    // Set protections.
    if (mprotect(page, pagesize, PROT_READ) == -1) {
        fprintf(stderr, "Error: Attempt to set memory access perms failed!\n");
        exit(EXIT_FAILURE);
    }

    /*
     ***************************************************************************
     *                              Signal Setup                               *
     ***************************************************************************
    */

    // Setup signal handler.
    struct sigaction segHandler;

    // Configure args.
    segHandler.sa_flags = SA_SIGINFO;

    // Reset signal-mask.
    sigemptyset(&segHandler.sa_mask);

    // Setup handler routine.
    segHandler.sa_sigaction = handler_sigseg;

    // Setup signals to be intercepted.
    sigaction(SIGSEGV, &segHandler, NULL);


    // Test the signal handler.
    printf("Poking protected memory...\n");
    char *p = (char *)page;
    *p = 0;

    return 0;
}

Итак, в заключение, может кто-нибудь сообщить мне о последнем подходящем способе резервирования памяти, чтобы я мог поднять SIGSEGV на macOS?

0 ответов

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