#include <xbt/mmalloc.h>
-#include "mc_object_info.h"
-#include "mc_unw.h"
-#include "mc_snapshot.h"
-#include "mc_ignore.h"
-#include "mc_smx.h"
-#include "mc_server.h"
-
-#include "mc/Process.hpp"
-#include "mc/AddressSpace.hpp"
-#include "mc/ObjectInformation.hpp"
-#include "mc/Variable.hpp"
+#include "src/mc/mc_object_info.h"
+#include "src/mc/mc_unw.h"
+#include "src/mc/mc_snapshot.h"
+#include "src/mc/mc_ignore.h"
+#include "src/mc/mc_smx.h"
+
+#include "src/mc/Process.hpp"
+#include "src/mc/AddressSpace.hpp"
+#include "src/mc/ObjectInformation.hpp"
+#include "src/mc/Variable.hpp"
using simgrid::mc::remote;
"libelf",
"libgcc_s",
"liblua5.1",
+ "liblua5.3",
"liblzma",
"libm",
"libpthread",
namespace simgrid {
namespace mc {
-Process::Process(pid_t pid, int sockfd)
+Process::Process(pid_t pid, int sockfd) : AddressSpace(this)
{
Process* process = this;
-
- process->process_flags = MC_PROCESS_NO_FLAG;
process->socket_ = sockfd;
process->pid_ = pid;
- if (pid==getpid())
- process->process_flags |= MC_PROCESS_SELF_FLAG;
process->running_ = true;
- process->status_ = 0;
- process->memory_map_ = get_memory_map(pid);
+ process->memory_map_ = simgrid::xbt::get_memory_map(pid);
process->cache_flags = MC_PROCESS_CACHE_FLAG_NONE;
- process->heap = NULL;
- process->heap_info = NULL;
process->init_memory_map_info();
process->clear_refs_fd_ = -1;
process->pagemap_fd_ = -1;
+ process->privatized_ = false;
- // Open the memory file
- if (process->is_self())
- process->memory_file = -1;
- else {
- int fd = open_vm(process->pid_, O_RDWR);
- if (fd<0)
- xbt_die("Could not open file for process virtual address space");
- process->memory_file = fd;
- }
+ int fd = open_vm(process->pid_, O_RDWR);
+ if (fd<0)
+ xbt_die("Could not open file for process virtual address space");
+ process->memory_file = fd;
// Read std_heap (is a struct mdesc*):
simgrid::mc::Variable* std_heap_var = process->find_variable("__mmalloc_default_mdp");
process->smx_process_infos = MC_smx_process_info_list_new();
process->smx_old_process_infos = MC_smx_process_info_list_new();
-
process->unw_addr_space = unw_create_addr_space(&mc_unw_accessors , __BYTE_ORDER);
- if (process->process_flags & MC_PROCESS_SELF_FLAG) {
- process->unw_underlying_addr_space = unw_local_addr_space;
- process->unw_underlying_context = NULL;
- } else {
- process->unw_underlying_addr_space = unw_create_addr_space(&mc_unw_vmread_accessors, __BYTE_ORDER);
- process->unw_underlying_context = _UPT_create(pid);
- }
+ process->unw_underlying_addr_space = unw_create_addr_space(&mc_unw_vmread_accessors, __BYTE_ORDER);
+ process->unw_underlying_context = _UPT_create(pid);
}
Process::~Process()
if (this->socket_ >= 0 && close(this->socket_) < 0)
xbt_die("Could not close communication socket");
- process->process_flags = MC_PROCESS_NO_FLAG;
process->pid_ = 0;
process->maestro_stack_start_ = nullptr;
process->cache_flags = MC_PROCESS_CACHE_FLAG_NONE;
- free(process->heap);
- process->heap = NULL;
-
- free(process->heap_info);
- process->heap_info = NULL;
-
if (process->clear_refs_fd_ >= 0)
close(process->clear_refs_fd_);
if (process->pagemap_fd_ >= 0)
void Process::refresh_heap()
{
xbt_assert(mc_mode == MC_MODE_SERVER);
- xbt_assert(!this->is_self());
// Read/dereference/refresh the std_heap pointer:
- if (!this->heap) {
- this->heap = (struct mdesc*) malloc(sizeof(struct mdesc));
- }
- this->read_bytes(this->heap, sizeof(struct mdesc), remote(this->heap_address),
- simgrid::mc::ProcessIndexDisabled);
+ if (!this->heap)
+ this->heap = std::unique_ptr<s_xbt_mheap_t>(new s_xbt_mheap_t());
+ this->read_bytes(this->heap.get(), sizeof(struct mdesc),
+ remote(this->heap_address), simgrid::mc::ProcessIndexDisabled);
this->cache_flags |= MC_PROCESS_CACHE_FLAG_HEAP;
}
void Process::refresh_malloc_info()
{
xbt_assert(mc_mode == MC_MODE_SERVER);
- xbt_assert(!this->is_self());
if (!(this->cache_flags & MC_PROCESS_CACHE_FLAG_HEAP))
this->refresh_heap();
// Refresh process->heapinfo:
- size_t malloc_info_bytesize =
- (this->heap->heaplimit + 1) * sizeof(malloc_info);
- this->heap_info = (malloc_info*) realloc(this->heap_info, malloc_info_bytesize);
- this->read_bytes(this->heap_info, malloc_info_bytesize,
+ size_t count = this->heap->heaplimit + 1;
+ if (this->heap_info.size() < count)
+ this->heap_info.resize(count);
+ this->read_bytes(this->heap_info.data(), count * sizeof(malloc_info),
remote(this->heap->heapinfo), simgrid::mc::ProcessIndexDisabled);
this->cache_flags |= MC_PROCESS_CACHE_FLAG_MALLOC_INFO;
}
if(regcomp(&res.so_re, SO_RE, 0) || regcomp(&res.version_re, VERSION_RE, 0))
xbt_die(".so regexp did not compile");
- std::vector<simgrid::mc::VmMap> const& maps = this->memory_map_;
+ std::vector<simgrid::xbt::VmMap> const& maps = this->memory_map_;
const char* current_name = NULL;
this->object_infos.resize(0);
for (size_t i=0; i < maps.size(); i++) {
- simgrid::mc::VmMap const& reg = maps[i];
+ simgrid::xbt::VmMap const& reg = maps[i];
const char* pathname = maps[i].pathname.c_str();
// Nothing to do
}
std::shared_ptr<simgrid::mc::ObjectInformation> info =
- MC_find_object_info(this->memory_map_, pathname, is_executable);
+ MC_find_object_info(this->memory_map_, pathname);
this->object_infos.push_back(info);
if (is_executable)
this->binary_info = info;
{
if (!address)
return NULL;
- if (this->is_self())
- return xbt_strdup((char*) address.address());
off_t len = 128;
char* res = (char*) malloc(len);
this->find_object_info_rw((void*)address.address());
// Segment overlap is not handled.
#ifdef HAVE_SMPI
- if (info.get() && info.get()->privatized()) {
+ if (info.get() && this->privatized(*info)) {
if (process_index < 0)
xbt_die("Missing process index");
if (process_index >= (int) MC_smpi_process_count())
#endif
}
- if (this->is_self()) {
- if (mode == simgrid::mc::AddressSpace::Lazy)
- return (void*)address.address();
- else {
- memcpy(buffer, (void*)address.address(), size);
- return buffer;
- }
- } else {
- if (pread_whole(this->memory_file, buffer, size, address.address()) < 0)
- xbt_die("Read from process %lli failed", (long long) this->pid_);
- return buffer;
- }
+ if (pread_whole(this->memory_file, buffer, size, address.address()) < 0)
+ xbt_die("Read from process %lli failed", (long long) this->pid_);
+ return buffer;
}
/** Write data to a process memory
*/
void Process::write_bytes(const void* buffer, size_t len, remote_ptr<void> address)
{
- if (this->is_self()) {
- memcpy((void*)address.address(), buffer, len);
- } else {
- if (pwrite_whole(this->memory_file, buffer, len, address.address()) < 0)
- xbt_die("Write to process %lli failed", (long long) this->pid_);
- }
+ if (pwrite_whole(this->memory_file, buffer, len, address.address()) < 0)
+ xbt_die("Write to process %lli failed", (long long) this->pid_);
}
void Process::clear_bytes(remote_ptr<void> address, size_t len)
{
- if (this->is_self()) {
- memset((void*)address.address(), 0, len);
- } else {
- pthread_once(&zero_buffer_flag, MC_zero_buffer_init);
- while (len) {
- size_t s = len > zero_buffer_size ? zero_buffer_size : len;
- this->write_bytes(zero_buffer, s, address);
- address = remote((char*) address.address() + s);
- len -= s;
- }
+ pthread_once(&zero_buffer_flag, MC_zero_buffer_init);
+ while (len) {
+ size_t s = len > zero_buffer_size ? zero_buffer_size : len;
+ this->write_bytes(zero_buffer, s, address);
+ address = remote((char*) address.address() + s);
+ len -= s;
}
}
xbt_die("Could not read pagemap");
}
+void Process::ignore_heap(IgnoredHeapRegion const& region)
+{
+ if (ignored_heap_.empty()) {
+ ignored_heap_.push_back(std::move(region));
+ return;
+ }
+
+ typedef std::vector<IgnoredHeapRegion>::size_type size_type;
+
+ size_type start = 0;
+ size_type end = ignored_heap_.size() - 1;
+
+ // Binary search the position of insertion:
+ size_type cursor;
+ while (start <= end) {
+ cursor = start + (end - start) / 2;
+ auto& current_region = ignored_heap_[cursor];
+ if (current_region.address == region.address)
+ return;
+ else if (current_region.address < region.address)
+ start = cursor + 1;
+ else if (cursor != 0)
+ end = cursor - 1;
+ // Avoid underflow:
+ else
+ break;
+ }
+
+ // Insert it mc_heap_ignore_region_t:
+ if (ignored_heap_[cursor].address < region.address)
+ ++cursor;
+ ignored_heap_.insert( ignored_heap_.begin() + cursor, region);
+}
+
+void Process::unignore_heap(void *address, size_t size)
+{
+ typedef std::vector<IgnoredHeapRegion>::size_type size_type;
+
+ size_type start = 0;
+ size_type end = ignored_heap_.size() - 1;
+
+ // Binary search:
+ size_type cursor;
+ while (start <= end) {
+ cursor = (start + end) / 2;
+ auto& region = ignored_heap_[cursor];
+ if (region.address == address) {
+ ignored_heap_.erase(ignored_heap_.begin() + cursor);
+ return;
+ } else if (region.address < address)
+ start = cursor + 1;
+ else if ((char *) region.address <= ((char *) address + size)) {
+ ignored_heap_.erase(ignored_heap_.begin() + cursor);
+ return;
+ } else if (cursor != 0)
+ end = cursor - 1;
+ // Avoid underflow:
+ else
+ break;
+ }
+}
+
+void Process::ignore_local_variable(const char *var_name, const char *frame_name)
+{
+ if (frame_name != nullptr && strcmp(frame_name, "*") == 0)
+ frame_name = nullptr;
+ for (std::shared_ptr<simgrid::mc::ObjectInformation> const& info :
+ this->object_infos)
+ info->remove_local_variable(var_name, frame_name);
+}
+
}
}