-/* Copyright (c) 2014-2020. The SimGrid Team. All rights reserved. */
+/* Copyright (c) 2014-2021. 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 "src/mc/remote/RemoteSimulation.hpp"
-#include "src/mc/mc_smx.hpp"
#include "src/mc/sosp/Snapshot.hpp"
#include "xbt/file.hpp"
#include "xbt/log.h"
#include <libunwind-ptrace.h>
#include <sys/mman.h> // PROT_*
+#include <algorithm>
+#include <memory>
+#include <string>
+
using simgrid::mc::remote;
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_process, mc, "MC process information");
#endif
"libargp", /* workarounds for glibc-less systems */
"libasan", /* gcc sanitizers */
+ "libasn1",
"libboost_chrono",
"libboost_context",
"libboost_context-mt",
"libboost_system",
"libboost_thread",
"libboost_timer",
+ "libbrotlicommon",
+ "libbrotlidec",
"libbz2",
"libc",
"libc++",
"libcdt",
"libcgraph",
+ "libcom_err",
+ "libcrypt",
"libcrypto",
+ "libcurl",
+ "libcurl-gnutls",
"libcxxrt",
+ "libdebuginfod",
"libdl",
"libdw",
"libelf",
"libevent",
"libexecinfo",
+ "libffi",
"libflang",
"libflangrti",
"libgcc_s",
+ "libgmp",
+ "libgnutls",
+ "libgcrypt",
"libgfortran",
+ "libgpg-error",
+ "libgssapi",
+ "libgssapi_krb5",
+ "libhcrypto",
+ "libheimbase",
+ "libheimntlm",
+ "libhx509",
+ "libhogweed",
+ "libidn2",
"libimf",
"libintlc",
"libirng",
+ "libk5crypto",
+ "libkeyutils",
+ "libkrb5",
+ "libkrb5support", /*odd behaviour on fedora rawhide ... remove these when fixed*/
+ "liblber",
+ "libldap",
+ "libldap_r",
"liblua5.1",
"liblua5.3",
"liblzma",
"libm",
+ "libmd",
+ "libnettle",
+ "libnghttp2",
"libomp",
+ "libp11-kit",
"libpapi",
"libpcre2",
"libpfm",
"libpgmath",
+ "libpsl",
"libpthread",
"libquadmath",
+ "libresolv",
+ "libroken",
"librt",
+ "librtmp",
+ "libsasl2",
+ "libselinux",
+ "libsqlite3",
+ "libssh",
+ "libssh2",
+ "libssl",
"libstdc++",
"libsvml",
+ "libtasn1",
"libtsan", /* gcc sanitizers */
"libubsan", /* gcc sanitizers */
+ "libunistring",
"libunwind",
"libunwind-ptrace",
"libunwind-x86",
"libunwind-x86_64",
+ "libwind",
"libz",
- "libkrb5support", /*odd behaviour on fedora rawhide ... remove these when fixed*/
- "libkeyutils",
- "libunistring",
- "libbrotlidec",
- "liblber",
- "libldap",
- "libcom_err",
- "libk5crypto",
- "libkrb5",
- "libgssapi_krb5",
- "libssl",
- "libpsl",
- "libssh",
- "libssh2",
- "libidn2",
- "libnghttp2",
- "libcurl",
- "libdebuginfod",
- "libbrotlicommon",
- "libsasl2",
- "libresolv",
- "libcrypt",
- "libselinux"};
-
-static bool is_simgrid_lib(const std::string& libname)
-{
- return libname == "libsimgrid";
-}
+ "libzstd"};
static bool is_filtered_lib(const std::string& libname)
{
static ssize_t pread_whole(int fd, void* buf, size_t count, off_t offset)
{
- char* buffer = (char*)buf;
+ auto* buffer = static_cast<char*>(buf);
ssize_t real_count = count;
while (count) {
ssize_t res = pread(fd, buffer, count, offset);
static ssize_t pwrite_whole(int fd, const void* buf, size_t count, off_t offset)
{
- const char* buffer = (const char*)buf;
+ const auto* buffer = static_cast<const char*>(buf);
ssize_t real_count = count;
while (count) {
ssize_t res = pwrite(fd, buffer, count, offset);
int open_vm(pid_t pid, int flags)
{
- const size_t buffer_size = 30;
- char buffer[buffer_size];
- int res = snprintf(buffer, buffer_size, "/proc/%lli/mem", (long long)pid);
- if (res < 0 || (size_t)res >= buffer_size) {
- errno = ENAMETOOLONG;
- return -1;
- }
- return open(buffer, flags);
+ std::string buffer = "/proc/" + std::to_string(pid) + "/mem";
+ return open(buffer.c_str(), flags);
}
// ***** RemoteSimulation
{
// Read/dereference/refresh the std_heap pointer:
if (not this->heap)
- this->heap.reset(new s_xbt_mheap_t());
+ this->heap = std::make_unique<s_xbt_mheap_t>();
this->read_bytes(this->heap.get(), sizeof(mdesc), remote(this->heap_address));
this->cache_flags_ |= RemoteSimulation::cache_heap;
}
this->maestro_stack_end_ = nullptr;
this->object_infos.resize(0);
this->binary_info = nullptr;
- this->libsimgrid_info = nullptr;
std::vector<simgrid::xbt::VmMap> const& maps = this->memory_map_;
this->object_infos.push_back(info);
if (is_executable)
this->binary_info = info;
- else if (is_simgrid_lib(libname))
- this->libsimgrid_info = info;
}
// Resolve time (including across different objects):
std::vector<char> res(128);
off_t off = 0;
- while (1) {
+ while (true) {
ssize_t c = pread(this->memory_file, res.data() + off, res.size() - off, (off_t)address.address() + off);
if (c == -1 && errno == EINTR)
continue;
* @param len data size
* @param address target process memory address (target)
*/
-void RemoteSimulation::write_bytes(const void* buffer, size_t len, RemotePtr<void> address)
+void RemoteSimulation::write_bytes(const void* buffer, size_t len, RemotePtr<void> address) const
{
if (pwrite_whole(this->memory_file, buffer, len, (size_t)address.address()) < 0)
xbt_die("Write to process %lli failed", (long long)this->pid_);
}
-void RemoteSimulation::clear_bytes(RemotePtr<void> address, size_t len)
+void RemoteSimulation::clear_bytes(RemotePtr<void> address, size_t len) const
{
pthread_once(&zero_buffer_flag, zero_buffer_init);
while (len) {
region.addr = addr;
region.size = size;
- if (ignored_regions_.empty()) {
- ignored_regions_.push_back(region);
- return;
- }
-
- unsigned int cursor = 0;
- const IgnoredRegion* current_region = nullptr;
-
- int start = 0;
- int end = ignored_regions_.size() - 1;
- while (start <= end) {
- cursor = (start + end) / 2;
- current_region = &ignored_regions_[cursor];
- if (current_region->addr == addr) {
- if (current_region->size == size)
- return;
- else if (current_region->size < size)
- start = cursor + 1;
- else
- end = cursor - 1;
- } else if (current_region->addr < addr)
- start = cursor + 1;
- else
- end = cursor - 1;
- }
-
- std::size_t position;
- if (current_region->addr == addr) {
- if (current_region->size < size)
- position = cursor + 1;
- else
- position = cursor;
- } else if (current_region->addr < addr)
- position = cursor + 1;
- else
- position = cursor;
- ignored_regions_.insert(ignored_regions_.begin() + position, region);
+ auto pos = std::lower_bound(ignored_regions_.begin(), ignored_regions_.end(), region,
+ [](auto const& reg1, auto const& reg2) {
+ return reg1.addr < reg2.addr || (reg1.addr == reg2.addr && reg1.size < reg2.size);
+ });
+ if (pos == ignored_regions_.end() || pos->addr != addr || pos->size != size)
+ ignored_regions_.insert(pos, region);
}
void RemoteSimulation::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 const& 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;
+ auto pos = std::lower_bound(ignored_heap_.begin(), ignored_heap_.end(), region.address,
+ [](auto const& reg, auto const* addr) { return reg.address < addr; });
+ if (pos == ignored_heap_.end() || pos->address != region.address) {
+ // Insert it:
+ ignored_heap_.insert(pos, region);
}
-
- // Insert it mc_heap_ignore_region_t:
- if (ignored_heap_[cursor].address < region.address)
- ++cursor;
- ignored_heap_.insert(ignored_heap_.begin() + cursor, region);
}
void RemoteSimulation::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 const& region = ignored_heap_[cursor];
- 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;
- }
+ auto pos = std::lower_bound(ignored_heap_.begin(), ignored_heap_.end(), address,
+ [](auto const& reg, auto const* addr) { return reg.address < addr; });
+ if (pos != ignored_heap_.end() && static_cast<char*>(pos->address) <= static_cast<char*>(address) + size)
+ ignored_heap_.erase(pos);
}
-void RemoteSimulation::ignore_local_variable(const char* var_name, const char* frame_name)
+void RemoteSimulation::ignore_local_variable(const char* var_name, const char* frame_name) const
{
if (frame_name != nullptr && strcmp(frame_name, "*") == 0)
frame_name = nullptr;
return smx_dead_actors_infos;
}
-void RemoteSimulation::dump_stack()
+void RemoteSimulation::dump_stack() const
{
unw_addr_space_t as = unw_create_addr_space(&_UPT_accessors, BYTE_ORDER);
if (as == nullptr) {