在以下程序上运行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;
}
Run Code Online (Sandbox Code Playgroud)
RAX在错误指令处保存(bs + pageSize),对应于代码中的(!!).但是,si_addr在信号处理程序的ucontext中与RAX不匹配(ucontext中RAX的值等于'bs').在启用写入RAX包含(bs)后重新执行(!!)时.执行外部valgrind按预期工作.
我是否做过某些事情导致未定义的行为,或者这可能是GCC或valgrind中的错误?
如果您使用精确的例外,它将起作用.
valgrind --vex-iropt-precise-memory-exns=yes ./your_program
Run Code Online (Sandbox Code Playgroud)
这个页面准确地描述了你要做的事情:-))
如果您以巧妙的方式使用信号(例如,捕获SIGSEGV,修改页面状态并重新启动指令),那么您可能依赖于精确的异常.在这种情况下,您将需要使用
--vex-iropt-precise-memory-exns=yes.
| 归档时间: |
|
| 查看次数: |
475 次 |
| 最近记录: |