Ошибка или ошибка valgrind / gcc? - PullRequest
2 голосов
/ 14 августа 2011

При запуске valgrind в следующей программе утверждение не выполняется:

#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <wchar.h>
#include <assert.h>
#include <signal.h>
#include <stdlib.h>
#include <ucontext.h>

static size_t pageSize = 4096;

uint8_t *bs;
static void sig(int num,
    siginfo_t *info, void *unused) {
    ucontext *p = (ucontext *)unused;
    uint8_t *addr = (uint8_t *)info->si_addr;
    wprintf(L"rax=%lx\n", p->uc_mcontext.gregs[REG_RAX]);
    wprintf(L"addr=%lx\n", addr);
    assert(mprotect(bs, pageSize*4,
        PROT_READ | PROT_WRITE) == 0);
}


bool setsig() {
    sigset_t mask;
    struct sigaction sa;

    if (sigemptyset(&mask))
        return false;

    sa.sa_sigaction = sig;
    sa.sa_mask = mask;
    sa.sa_flags = SA_SIGINFO;

    if (sigaction(SIGSEGV,&sa, NULL) != 0)
        return false;

    return true;
}

int main() {
    assert(setsig());

    bs = (uint8_t *)mmap(NULL, pageSize*4,
        PROT_READ,
        MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    assert(bs != MAP_FAILED);

    bs[pageSize] = 3; // !!
    assert(bs[pageSize] == 3);

    return 0;
}

RAX удерживает (bs + pageSize) на ошибочной инструкции, соответствующей (!!) в коде.Однако si_addr не совпадает с RAX в ucontext обработчика сигнала (значение RAX в ucontext равно 'bs').Когда (!!) повторно выполняется после включения записи, RAX содержит (bs).Выполнение за пределами valgrind работает, как и ожидалось.

Я что-то сделал, чтобы вызвать неопределенное поведение, или это ошибка в GCC или valgrind?

1 Ответ

6 голосов
/ 14 августа 2011

Это будет работать, если вы используете точные исключения.

valgrind --vex-iropt-precise-memory-exns=yes ./your_program

Эта страница точно описывает, что вы пытаетесь сделать: -))

Если вы используете сигналы хитроумными способами (например, перехват SIGSEGV, изменение состояния страницы и перезапуск инструкции ), вы, вероятно, полагаетесь на точные исключения.В этом случае вам нужно будет использовать --vex-iropt-precise-memory-exns=yes.

...