bool BacktraceCurrent::ReadWord(uintptr_t ptr, uint32_t* out_value) {
  if (!VerifyReadWordArgs(ptr, out_value)) {
    return false;
  }

  const backtrace_map_t* map = FindMap(ptr);
  if (map && map->flags & PROT_READ) {
    *out_value = *reinterpret_cast<uint32_t*>(ptr);
    return true;
  } else {
    BACK_LOGW("pointer %p not in a readable map", reinterpret_cast<void*>(ptr));
    *out_value = static_cast<uint32_t>(-1);
    return false;
  }
}
bool BacktracePtrace::ReadWord(uintptr_t ptr, word_t* out_value) {
#if defined(__APPLE__)
  BACK_LOGW("MacOS does not support reading from another pid.");
  return false;
#else
  if (!VerifyReadWordArgs(ptr, out_value)) {
    return false;
  }

  backtrace_map_t map;
  FillInMap(ptr, &map);
  if (!BacktraceMap::IsValid(map) || !(map.flags & PROT_READ)) {
    return false;
  }

  return PtraceRead(Tid(), ptr, out_value);
#endif
}
bool BacktracePtrace::ReadWord(uintptr_t ptr, uint32_t* out_value) {
  if (!VerifyReadWordArgs(ptr, out_value)) {
    return false;
  }

#if defined(__APPLE__)
  BACK_LOGW("MacOS does not support reading from another pid.");
  return false;
#else
  // ptrace() returns -1 and sets errno when the operation fails.
  // To disambiguate -1 from a valid result, we clear errno beforehand.
  errno = 0;
  *out_value = ptrace(PTRACE_PEEKTEXT, Tid(), reinterpret_cast<void*>(ptr), NULL);
  if (*out_value == static_cast<uint32_t>(-1) && errno) {
    BACK_LOGW("invalid pointer %p reading from tid %d, ptrace() strerror(errno)=%s",
              reinterpret_cast<void*>(ptr), Tid(), strerror(errno));
    return false;
  }
  return true;
#endif
}