當在下面的程序運行的valgrind斷言失敗:錯誤或valgrind/gcc錯誤?
#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與信號處理程序的ucontext中的RAX不匹配(ucontext中的RAX值等於'bs')。在啓用寫入RAX包含(bs)後重新執行(!!)。按預期執行valgrind外部工作。
我做了一些事情會導致未定義的行爲,或者這可能是GCC或valgrind中的錯誤嗎?
我在valgrind 3.6.1和svn的最新版本中得到了這個行爲。 – user836336
一個側面說明不是問題得到解答:我意識到這是一個簡單的測試,但是您不應該將帶有副作用的代碼作爲參數提交給'assert'。如果使用-DNDEBUG進行編譯,一切都會中斷。另外'wprintf'在信號處理程序中調用不安全(參見[這裏](https://www.securecoding.cert.org/confluence/display/seccode/SIG30-C.+Call+only+asynchronous-safe+functions + + +信號處理程序中))。 – user786653
@ user786653:好點重新:斷言。 – user836336