X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/ea9cce21b6d3f37823143217f1ca183bb2f0c9ac..c9680266ff5262307dd726d248c4e965cacc8e21:/src/mc/mc_unw_vmread.cpp diff --git a/src/mc/mc_unw_vmread.cpp b/src/mc/mc_unw_vmread.cpp index 3893ec9a1c..148a2f5995 100644 --- a/src/mc/mc_unw_vmread.cpp +++ b/src/mc/mc_unw_vmread.cpp @@ -1,12 +1,18 @@ +/* Copyright (c) 2015. The SimGrid Team. + * All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + #include #include +#include #include #include -#include "mc_unw.h" - -extern "C" { +#include "src/mc/Process.hpp" +#include "src/mc/mc_unw.h" /** \file * Libunwind namespace implementation using process_vm_readv. @@ -16,9 +22,9 @@ extern "C" { /** Partial structure of libunwind-ptrace context in order to get the PID * - * The context type for libunwind-race is an opaque type. We need to get the - * PID which is the first field. This is a hack which might break if the - * libunwind-ptrace structure changes. + * HACK, The context type for libunwind-race is an opaque type. + * We need to get the PID which is the first field. This is a hack + * which might break if the libunwind-ptrace structure changes. */ struct _UPT_info { pid_t pid; @@ -42,17 +48,16 @@ static int access_mem(const unw_addr_space_t as, { if (write) return - UNW_EINVAL; - ssize_t s; pid_t pid = _UPT_getpid(arg); size_t size = sizeof(unw_word_t); -#ifdef HAVE_PROCESS_VM_READV +#if HAVE_PROCESS_VM_READV // process_vm_read implementation. // This is only available since Linux 3.2. struct iovec local = { valp, size }; struct iovec remote = { (void*) addr, size }; - s = process_vm_readv(pid, &local, 1, &remote, 1, 0); + ssize_t s = process_vm_readv(pid, &local, 1, &remote, 1, 0); if (s >= 0) { if ((size_t) s != size) return - UNW_EINVAL; @@ -69,7 +74,7 @@ static int access_mem(const unw_addr_space_t as, size_t count = size; off_t off = (off_t) addr; char* buf = (char*) valp; - int fd = MC_process_vm_open(pid, O_RDONLY); + int fd = simgrid::mc::open_vm(pid, O_RDONLY); if (fd < 0) return - UNW_EINVAL; while (1) { @@ -95,16 +100,42 @@ static int access_mem(const unw_addr_space_t as, return _UPT_access_mem(as, addr, valp, write, arg); } -unw_accessors_t mc_unw_vmread_accessors = - { - .find_proc_info = &_UPT_find_proc_info, - .put_unwind_info = &_UPT_put_unwind_info, - .get_dyn_info_list_addr = &_UPT_get_dyn_info_list_addr, - .access_mem = &access_mem, - .access_reg = &_UPT_access_reg, - .access_fpreg = &_UPT_access_fpreg, - .resume = &_UPT_resume, - .get_proc_name = &_UPT_get_proc_name - }; +namespace simgrid { +namespace unw { + +/** Virtual table for our `libunwind-process_vm_readv` implementation. + * + * This implementation reuse most the code of `libunwind-ptrace` but + * does not use ptrace() to read the target process memory by + * `process_vm_readv()` or `/dev/${pid}/mem` if possible. + * + * Does not support any MC-specific behaviour (privatization, snapshots) + * and `ucontext_t`. + * + * It works with `void*` contexts allocated with `_UPT_create(pid)`. + */ +// TODO, we could get rid of this if we properly stop the model-checked +// process before reading the memory. +static unw_accessors_t accessors = { + &_UPT_find_proc_info, + &_UPT_put_unwind_info, + &_UPT_get_dyn_info_list_addr, + &access_mem, + &_UPT_access_reg, + &_UPT_access_fpreg, + &_UPT_resume, + &_UPT_get_proc_name +}; + +unw_addr_space_t create_addr_space() +{ + return unw_create_addr_space(&accessors, BYTE_ORDER); +} + +void* create_context(unw_addr_space_t as, pid_t pid) +{ + return _UPT_create(pid); +} } +}