Skip to content

Commit

Permalink
Mapping the core file
Browse files Browse the repository at this point in the history
Changed the way of reading data from the core file. The core file is mapped directly into a virtual memory page.

Signed-off-by: Ivona Stojanovic <[email protected]>
  • Loading branch information
ivonastojanovic authored and pablogsal committed Jul 31, 2023
1 parent 088cf4b commit 2261938
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 15 deletions.
84 changes: 73 additions & 11 deletions src/pystack/_pystack/mem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,23 +344,89 @@ CorefileRemoteMemoryManager::CorefileRemoteMemoryManager(
{
CoreFileExtractor extractor{d_analyzer};
d_shared_libs = extractor.ModuleInformation();

const char* filename = d_analyzer->d_filename.c_str();
int fd = open(filename, O_RDONLY);

if (fd == -1) {
LOG(ERROR) << "Failed to open a file " << filename;
throw RemoteMemCopyError();
}

StatusCode ret = readCorefile(fd, filename);
int close_ret = close(fd);

if (close_ret == -1) {
LOG(ERROR) << "Failed to close a file " << filename;
throw RemoteMemCopyError();
}

if (ret == StatusCode::ERROR) {
throw RemoteMemCopyError();
}
}

CorefileRemoteMemoryManager::StatusCode
CorefileRemoteMemoryManager::readCorefile(int fd, const char* filename) noexcept
{
struct stat fileInfo = {0};

if (fstat(fd, &fileInfo) == -1) {
LOG(ERROR) << "Failed to get a file size for a file " << filename;
return StatusCode::ERROR;
}

if (fileInfo.st_size == 0) {
LOG(ERROR) << "File " << filename << " is empty";
return StatusCode::ERROR;
}

d_corefile_size = fileInfo.st_size;

void* map = mmap(0, d_corefile_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (map == MAP_FAILED) {
LOG(ERROR) << "Failed to mmap a file " << filename;
return StatusCode::ERROR;
}

d_corefile_data = std::unique_ptr<char, std::function<void(char*)>>(
reinterpret_cast<char*>(map),
[this](auto addr) {
if (munmap(addr, d_corefile_size) == -1) {
LOG(ERROR) << "Failed to un-mmap a file " << d_analyzer->d_filename.c_str();
}
});

int madvise_result = madvise(d_corefile_data.get(), d_corefile_size, MADV_RANDOM);

if (madvise_result == -1) {
LOG(WARNING) << "Madvise for a file " << filename << " failed";
}

return StatusCode::SUCCESS;
}

ssize_t
CorefileRemoteMemoryManager::copyMemoryFromProcess(remote_addr_t addr, size_t size, void* destination)
const
{
const std::string* filename = nullptr;
off_t offset_in_file = 0;

StatusCode ret = getMemoryLocationFromCore(addr, &filename, &offset_in_file);
StatusCode ret = getMemoryLocationFromCore(addr, &offset_in_file);

if (ret == StatusCode::ERROR) {
// The memory may be in the data segment of some shared library
getMemoryLocationFromElf(addr, &filename, &offset_in_file);
if (ret == StatusCode::SUCCESS) {
if (static_cast<size_t>(offset_in_file) > d_corefile_size) {
throw InvalidRemoteAddress();
}
memcpy(destination, d_corefile_data.get() + offset_in_file, size);
return size;
}

if (filename == nullptr) {
// The memory may be in the data segment of some shared library
const std::string* filename = nullptr;
ret = getMemoryLocationFromElf(addr, &filename, &offset_in_file);

if (ret == StatusCode::ERROR) {
throw InvalidRemoteAddress();
}

Expand All @@ -376,10 +442,7 @@ CorefileRemoteMemoryManager::copyMemoryFromProcess(remote_addr_t addr, size_t si
}

CorefileRemoteMemoryManager::StatusCode
CorefileRemoteMemoryManager::getMemoryLocationFromCore(
remote_addr_t addr,
const std::string** filename,
off_t* offset_in_file) const
CorefileRemoteMemoryManager::getMemoryLocationFromCore(remote_addr_t addr, off_t* offset_in_file) const
{
auto corefile_it = std::find_if(d_vmaps.cbegin(), d_vmaps.cend(), [&](auto& map) {
return (map.Start() <= addr && addr <= map.End()) && (map.FileSize() != 0 && map.Offset() != 0);
Expand All @@ -390,7 +453,6 @@ CorefileRemoteMemoryManager::getMemoryLocationFromCore(

unsigned long base = corefile_it->Offset() - corefile_it->Start();
*offset_in_file = base + addr;
*filename = &d_analyzer->d_filename;
return StatusCode::SUCCESS;
}

Expand Down
12 changes: 8 additions & 4 deletions src/pystack/_pystack/mem.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
#pragma once

#include <cstdint>
#include <fcntl.h>
#include <functional>
#include <list>
#include <memory>
#include <optional>
#include <stdexcept>
#include <string>
#include <sys/mman.h>
#include <sys/stat.h>
#include <vector>

#include <elf_common.h>
Expand Down Expand Up @@ -227,11 +231,11 @@ class CorefileRemoteMemoryManager : public AbstractRemoteMemoryManager
std::shared_ptr<CoreFileAnalyzer> d_analyzer;
std::vector<VirtualMap> d_vmaps;
std::vector<SimpleVirtualMap> d_shared_libs;
size_t d_corefile_size;
std::unique_ptr<char, std::function<void(char*)>> d_corefile_data;

StatusCode getMemoryLocationFromCore(
remote_addr_t addr,
const std::string** filename,
off_t* offset_in_file) const;
StatusCode readCorefile(int fd, const char* filename) noexcept;
StatusCode getMemoryLocationFromCore(remote_addr_t addr, off_t* offset_in_file) const;
StatusCode getMemoryLocationFromElf(
remote_addr_t addr,
const std::string** filename,
Expand Down

0 comments on commit 2261938

Please sign in to comment.