| 236 | } |
| 237 | |
| 238 | ssize_t |
| 239 | ProcessMemoryManager::readChunkDirect(remote_addr_t addr, size_t len, char* dst) const |
| 240 | { |
| 241 | struct iovec local[1]; |
| 242 | struct iovec remote[1]; |
| 243 | ssize_t result = 0; |
| 244 | ssize_t read = 0; |
| 245 | |
| 246 | do { |
| 247 | local[0].iov_base = dst + result; |
| 248 | local[0].iov_len = len - result; |
| 249 | remote[0].iov_base = reinterpret_cast<uint8_t*>(addr) + result; |
| 250 | remote[0].iov_len = len - result; |
| 251 | |
| 252 | read = _process_vm_readv(d_pid, local, 1, remote, 1, 0); |
| 253 | if (read < 0) { |
| 254 | if (errno == EFAULT) { |
| 255 | throw InvalidRemoteAddress(); |
| 256 | } else if (errno == EPERM) { |
| 257 | throw std::runtime_error(PERM_MESSAGE); |
| 258 | } else if (errno == ENOSYS) { |
| 259 | LOG(DEBUG) << "process_vm_readv not compiled in kernel, falling back to /proc/PID/mem"; |
| 260 | return readChunkThroughMemFile(addr, len, dst); |
| 261 | } |
| 262 | throw std::system_error(errno, std::generic_category()); |
| 263 | } |
| 264 | |
| 265 | result += read; |
| 266 | } while ((size_t)read != local[0].iov_len); |
| 267 | |
| 268 | return result; |
| 269 | } |
| 270 | |
| 271 | ssize_t |
| 272 | ProcessMemoryManager::readChunkThroughMemFile(remote_addr_t addr, size_t len, char* dst) const |
nothing calls this directly
no test coverage detected