Fix imgdiag after ObjPtr<>-ify Object::As*().
Test: imgdiag_test
Bug: 31113334
Change-Id: I2d6138e2db79a84fbac8b1cd687e0a2f5da04d69
diff --git a/imgdiag/imgdiag.cc b/imgdiag/imgdiag.cc
index ca23f0e..7166395 100644
--- a/imgdiag/imgdiag.cc
+++ b/imgdiag/imgdiag.cc
@@ -172,7 +172,7 @@
// Returned pointer will point to inside of remote_contents.
template <typename T>
static ObjPtr<T> FixUpRemotePointer(ObjPtr<T> remote_ptr,
- std::vector<uint8_t>& remote_contents,
+ ArrayRef<uint8_t> remote_contents,
const backtrace_map_t& boot_map)
REQUIRES_SHARED(Locks::mutator_lock_) {
if (remote_ptr == nullptr) {
@@ -194,7 +194,7 @@
template <typename T>
static ObjPtr<T> RemoteContentsPointerToLocal(ObjPtr<T> remote_ptr,
- std::vector<uint8_t>& remote_contents,
+ ArrayRef<uint8_t> remote_contents,
const ImageHeader& image_header)
REQUIRES_SHARED(Locks::mutator_lock_) {
if (remote_ptr == nullptr) {
@@ -226,8 +226,8 @@
struct RegionCommon {
public:
RegionCommon(std::ostream* os,
- std::vector<uint8_t>* remote_contents,
- std::vector<uint8_t>* zygote_contents,
+ ArrayRef<uint8_t> remote_contents,
+ ArrayRef<uint8_t> zygote_contents,
const backtrace_map_t& boot_map,
const ImageHeader& image_header) :
os_(*os),
@@ -238,8 +238,7 @@
different_entries_(0),
dirty_entry_bytes_(0),
false_dirty_entry_bytes_(0) {
- CHECK(remote_contents != nullptr);
- CHECK(zygote_contents != nullptr);
+ CHECK(!remote_contents.empty());
}
void DumpSamplesAndOffsetCount() {
@@ -301,9 +300,9 @@
// The output stream to write to.
std::ostream& os_;
// The byte contents of the remote (image) process' image.
- std::vector<uint8_t>* remote_contents_;
+ ArrayRef<uint8_t> remote_contents_;
// The byte contents of the zygote process' image.
- std::vector<uint8_t>* zygote_contents_;
+ ArrayRef<uint8_t> zygote_contents_;
const backtrace_map_t& boot_map_;
const ImageHeader& image_header_;
@@ -374,8 +373,8 @@
class RegionSpecializedBase<mirror::Object> : public RegionCommon<mirror::Object> {
public:
RegionSpecializedBase(std::ostream* os,
- std::vector<uint8_t>* remote_contents,
- std::vector<uint8_t>* zygote_contents,
+ ArrayRef<uint8_t> remote_contents,
+ ArrayRef<uint8_t> zygote_contents,
const backtrace_map_t& boot_map,
const ImageHeader& image_header,
bool dump_dirty_objects)
@@ -547,7 +546,7 @@
// local class object
ObjPtr<mirror::Class> local_klass =
RemoteContentsPointerToLocal(remote_klass,
- *RegionCommon<mirror::Object>::remote_contents_,
+ RegionCommon<mirror::Object>::remote_contents_,
RegionCommon<mirror::Object>::image_header_);
os_ << " " << reinterpret_cast<const void*>(object) << " ";
os_ << " class_status (remote): " << remote_klass->GetStatus() << ", ";
@@ -702,15 +701,15 @@
class RegionSpecializedBase<ArtMethod> : public RegionCommon<ArtMethod> {
public:
RegionSpecializedBase(std::ostream* os,
- std::vector<uint8_t>* remote_contents,
- std::vector<uint8_t>* zygote_contents,
+ ArrayRef<uint8_t> remote_contents,
+ ArrayRef<uint8_t> zygote_contents,
const backtrace_map_t& boot_map,
const ImageHeader& image_header,
bool dump_dirty_objects ATTRIBUTE_UNUSED)
: RegionCommon<ArtMethod>(os, remote_contents, zygote_contents, boot_map, image_header),
os_(*os) {
// Prepare the table for offset to member lookups.
- ArtMethod* art_method = reinterpret_cast<ArtMethod*>(&(*remote_contents)[0]);
+ ArtMethod* art_method = reinterpret_cast<ArtMethod*>(&remote_contents[0]);
art_method->VisitMembers(member_info_);
// Prepare the table for address to symbolic entry point names.
BuildEntryPointNames();
@@ -809,12 +808,12 @@
// remote class
ObjPtr<mirror::Class> remote_declaring_class =
FixUpRemotePointer(art_method->GetDeclaringClass(),
- *RegionCommon<ArtMethod>::remote_contents_,
+ RegionCommon<ArtMethod>::remote_contents_,
RegionCommon<ArtMethod>::boot_map_);
// local class
ObjPtr<mirror::Class> declaring_class =
RemoteContentsPointerToLocal(remote_declaring_class,
- *RegionCommon<ArtMethod>::remote_contents_,
+ RegionCommon<ArtMethod>::remote_contents_,
RegionCommon<ArtMethod>::image_header_);
DumpOneArtMethod(art_method, declaring_class, remote_declaring_class);
}
@@ -936,8 +935,8 @@
class RegionData : public RegionSpecializedBase<T> {
public:
RegionData(std::ostream* os,
- std::vector<uint8_t>* remote_contents,
- std::vector<uint8_t>* zygote_contents,
+ ArrayRef<uint8_t> remote_contents,
+ ArrayRef<uint8_t> zygote_contents,
const backtrace_map_t& boot_map,
const ImageHeader& image_header,
bool dump_dirty_objects)
@@ -948,8 +947,7 @@
image_header,
dump_dirty_objects),
os_(*os) {
- CHECK(remote_contents != nullptr);
- CHECK(zygote_contents != nullptr);
+ CHECK(!remote_contents.empty());
}
// Walk over the type T entries in theregion between begin_image_ptr and end_image_ptr,
@@ -993,7 +991,7 @@
os_ << " Application dirty entries (private dirty): ";
// If we are dumping private dirty, diff against the zygote map to make it clearer what
// fields caused the page to be private dirty.
- base_ptr = &RegionCommon<T>::zygote_contents_->operator[](0);
+ base_ptr = RegionCommon<T>::zygote_contents_.data();
break;
case RemoteProcesses::kImageOnly:
os_ << " Application dirty entries (unknown whether private or shared dirty): ";
@@ -1028,7 +1026,7 @@
void DiffDirtyEntries(ProcessType process_type,
const uint8_t* begin_image_ptr,
- std::vector<uint8_t>* contents,
+ ArrayRef<uint8_t> contents,
const uint8_t* base_ptr,
bool log_dirty_objects)
REQUIRES_SHARED(Locks::mutator_lock_) {
@@ -1040,7 +1038,7 @@
for (T* entry : entries) {
uint8_t* entry_bytes = reinterpret_cast<uint8_t*>(entry);
ptrdiff_t offset = entry_bytes - begin_image_ptr;
- uint8_t* remote_bytes = &(*contents)[offset];
+ uint8_t* remote_bytes = &contents[offset];
RegionSpecializedBase<T>::DiffEntryContents(entry,
remote_bytes,
&base_ptr[offset],
@@ -1056,10 +1054,10 @@
uint8_t* current = reinterpret_cast<uint8_t*>(entry);
ptrdiff_t offset = current - begin_image_ptr;
T* entry_remote =
- reinterpret_cast<T*>(const_cast<uint8_t*>(&(*RegionCommon<T>::remote_contents_)[offset]));
- const bool have_zygote = !RegionCommon<T>::zygote_contents_->empty();
+ reinterpret_cast<T*>(const_cast<uint8_t*>(&RegionCommon<T>::remote_contents_[offset]));
+ const bool have_zygote = !RegionCommon<T>::zygote_contents_.empty();
const uint8_t* current_zygote =
- have_zygote ? &(*RegionCommon<T>::zygote_contents_)[offset] : nullptr;
+ have_zygote ? &RegionCommon<T>::zygote_contents_[offset] : nullptr;
T* entry_zygote = reinterpret_cast<T*>(const_cast<uint8_t*>(current_zygote));
// Visit and classify entries at the current location.
RegionSpecializedBase<T>::VisitEntry(entry);
@@ -1305,7 +1303,7 @@
bool ComputeDirtyBytes(const ImageHeader& image_header,
const uint8_t* image_begin,
const backtrace_map_t& boot_map,
- const std::vector<uint8_t>& remote_contents,
+ ArrayRef<uint8_t> remote_contents,
MappingData* mapping_data /*out*/) {
std::ostream& os = *os_;
@@ -1502,18 +1500,42 @@
return false;
}
- // The contents of /proc/<image_diff_pid_>/maps.
- std::vector<uint8_t> remote_contents(boot_map_size);
- if (!image_mem_file_.PreadFully(remote_contents.data(), boot_map_size, boot_map.start)) {
- os << "Could not fully read file " << image_mem_file_.GetPath();
+ auto read_contents = [&](File* mem_file,
+ /*out*/ MemMap* map,
+ /*out*/ ArrayRef<uint8_t>* contents) {
+ DCHECK_ALIGNED(boot_map.start, kPageSize);
+ DCHECK_ALIGNED(boot_map_size, kPageSize);
+ std::string name = "Contents of " + mem_file->GetPath();
+ std::string local_error_msg;
+ // We need to use low 4 GiB memory so that we can walk the objects using standard
+ // functions that use ObjPtr<> which is checking that it fits into lower 4 GiB.
+ *map = MemMap::MapAnonymous(name.c_str(),
+ boot_map_size,
+ PROT_READ | PROT_WRITE,
+ /* low_4gb= */ true,
+ &local_error_msg);
+ if (!map->IsValid()) {
+ os << "Failed to allocate anonymous mapping for " << boot_map_size << " bytes.\n";
+ return false;
+ }
+ if (!mem_file->PreadFully(map->Begin(), boot_map_size, boot_map.start)) {
+ os << "Could not fully read file " << image_mem_file_.GetPath();
+ return false;
+ }
+ *contents = ArrayRef<uint8_t>(map->Begin(), boot_map_size);
+ return true;
+ };
+ // The contents of /proc/<image_diff_pid_>/mem.
+ MemMap remote_contents_map;
+ ArrayRef<uint8_t> remote_contents;
+ if (!read_contents(&image_mem_file_, &remote_contents_map, &remote_contents)) {
return false;
}
- // The contents of /proc/<zygote_diff_pid_>/maps.
- std::vector<uint8_t> zygote_contents;
+ // The contents of /proc/<zygote_diff_pid_>/mem.
+ MemMap zygote_contents_map;
+ ArrayRef<uint8_t> zygote_contents;
if (zygote_diff_pid_ != -1) {
- zygote_contents.resize(boot_map_size);
- if (!zygote_mem_file_.PreadFully(zygote_contents.data(), boot_map_size, boot_map.start)) {
- LOG(WARNING) << "Could not fully read zygote file " << zygote_mem_file_.GetPath();
+ if (!read_contents(&zygote_mem_file_, &zygote_contents_map, &zygote_contents)) {
return false;
}
}
@@ -1550,8 +1572,8 @@
// Check all the mirror::Object entries in the image.
RegionData<mirror::Object> object_region_data(os_,
- &remote_contents,
- &zygote_contents,
+ remote_contents,
+ zygote_contents,
boot_map,
image_header,
dump_dirty_objects_);
@@ -1561,8 +1583,8 @@
// Check all the ArtMethod entries in the image.
RegionData<ArtMethod> artmethod_region_data(os_,
- &remote_contents,
- &zygote_contents,
+ remote_contents,
+ zygote_contents,
boot_map,
image_header,
dump_dirty_objects_);