|
17 | 17 | namespace pystack { |
18 | 18 |
|
19 | 19 | using elf_unique_ptr = std::unique_ptr<Elf, std::function<void(Elf*)>>; |
20 | | -using file_unique_ptr = std::unique_ptr<FILE, std::function<int(FILE*)>>; |
21 | 20 |
|
22 | 21 | static ssize_t |
23 | 22 | _process_vm_readv( |
@@ -229,7 +228,7 @@ ProcessMemoryManager::ProcessMemoryManager(pid_t pid) |
229 | 228 | ssize_t |
230 | 229 | ProcessMemoryManager::readChunk(remote_addr_t addr, size_t len, char* dst) const |
231 | 230 | { |
232 | | - if (d_memfile.is_open()) { |
| 231 | + if (d_memfile) { |
233 | 232 | return readChunkThroughMemFile(addr, len, dst); |
234 | 233 | } else { |
235 | 234 | return readChunkDirect(addr, len, dst); |
@@ -272,25 +271,25 @@ ProcessMemoryManager::readChunkDirect(remote_addr_t addr, size_t len, char* dst) |
272 | 271 | ssize_t |
273 | 272 | ProcessMemoryManager::readChunkThroughMemFile(remote_addr_t addr, size_t len, char* dst) const |
274 | 273 | { |
275 | | - if (!d_memfile.is_open()) { |
| 274 | + if (!d_memfile) { |
276 | 275 | std::string filepath = "/proc/" + std::to_string(d_pid) + "/mem"; |
277 | | - d_memfile.open(filepath, std::ifstream::binary); |
| 276 | + d_memfile = file_unique_ptr(fopen(filepath.c_str(), "r"), fclose); |
278 | 277 | if (!d_memfile) { |
279 | | - LOG(ERROR) << "Failed to open file " << filepath; |
280 | | - if (-1 == open(filepath.c_str(), O_RDONLY)) { |
281 | | - if (errno == EPERM || errno == EACCES) { |
282 | | - throw std::runtime_error(PERM_MESSAGE); |
283 | | - } |
284 | | - throw std::system_error(errno, std::generic_category()); |
| 278 | + if (errno == EPERM || errno == EACCES) { |
| 279 | + LOG(ERROR) << "Permission denied opening file " << filepath; |
| 280 | + throw std::runtime_error(PERM_MESSAGE); |
285 | 281 | } |
| 282 | + LOG(ERROR) << "Failed to open file " << filepath << ": " << std::strerror(errno); |
286 | 283 | throw std::runtime_error("Failed to open " + filepath); |
287 | 284 | } |
288 | 285 | } |
289 | | - d_memfile.seekg(addr); |
290 | | - if (!d_memfile.read((char*)dst, len)) { |
| 286 | + fseeko(d_memfile.get(), addr, SEEK_SET); |
| 287 | + if (static_cast<off_t>(addr) != ftello(d_memfile.get()) |
| 288 | + || len != fread(dst, 1, len, d_memfile.get())) |
| 289 | + { |
291 | 290 | throw InvalidRemoteAddress(); |
292 | 291 | } |
293 | | - return d_memfile.gcount(); |
| 292 | + return static_cast<ssize_t>(len); |
294 | 293 | } |
295 | 294 |
|
296 | 295 | ssize_t |
|
0 commit comments