1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* 18 * Preparation and completion of hprof data generation. The output is 19 * written into two files and then combined. This is necessary because 20 * we generate some of the data (strings and classes) while we dump the 21 * heap, and some analysis tools require that the class and string data 22 * appear first. 23 */ 24 25 #include "hprof.h" 26 27 #include <cutils/open_memstream.h> 28 #include <errno.h> 29 #include <fcntl.h> 30 #include <stdio.h> 31 #include <string.h> 32 #include <sys/time.h> 33 #include <sys/uio.h> 34 #include <time.h> 35 #include <time.h> 36 #include <unistd.h> 37 38 #include <set> 39 40 #include "art_field-inl.h" 41 #include "base/logging.h" 42 #include "base/stringprintf.h" 43 #include "base/time_utils.h" 44 #include "base/unix_file/fd_file.h" 45 #include "class_linker.h" 46 #include "common_throws.h" 47 #include "debugger.h" 48 #include "dex_file-inl.h" 49 #include "gc_root.h" 50 #include "gc/accounting/heap_bitmap.h" 51 #include "gc/heap.h" 52 #include "gc/space/space.h" 53 #include "globals.h" 54 #include "jdwp/jdwp.h" 55 #include "jdwp/jdwp_priv.h" 56 #include "mirror/class.h" 57 #include "mirror/class-inl.h" 58 #include "mirror/object-inl.h" 59 #include "os.h" 60 #include "safe_map.h" 61 #include "scoped_thread_state_change.h" 62 #include "thread_list.h" 63 64 namespace art { 65 66 namespace hprof { 67 68 static constexpr bool kDirectStream = true; 69 70 static constexpr uint32_t kHprofTime = 0; 71 static constexpr uint32_t kHprofNullStackTrace = 0; 72 static constexpr uint32_t kHprofNullThread = 0; 73 74 static constexpr size_t kMaxObjectsPerSegment = 128; 75 static constexpr size_t kMaxBytesPerSegment = 4096; 76 77 // The static field-name for the synthetic object generated to account for class static overhead. 78 static constexpr const char* kStaticOverheadName = "$staticOverhead"; 79 80 enum HprofTag { 81 HPROF_TAG_STRING = 0x01, 82 HPROF_TAG_LOAD_CLASS = 0x02, 83 HPROF_TAG_UNLOAD_CLASS = 0x03, 84 HPROF_TAG_STACK_FRAME = 0x04, 85 HPROF_TAG_STACK_TRACE = 0x05, 86 HPROF_TAG_ALLOC_SITES = 0x06, 87 HPROF_TAG_HEAP_SUMMARY = 0x07, 88 HPROF_TAG_START_THREAD = 0x0A, 89 HPROF_TAG_END_THREAD = 0x0B, 90 HPROF_TAG_HEAP_DUMP = 0x0C, 91 HPROF_TAG_HEAP_DUMP_SEGMENT = 0x1C, 92 HPROF_TAG_HEAP_DUMP_END = 0x2C, 93 HPROF_TAG_CPU_SAMPLES = 0x0D, 94 HPROF_TAG_CONTROL_SETTINGS = 0x0E, 95 }; 96 97 // Values for the first byte of HEAP_DUMP and HEAP_DUMP_SEGMENT records: 98 enum HprofHeapTag { 99 // Traditional. 100 HPROF_ROOT_UNKNOWN = 0xFF, 101 HPROF_ROOT_JNI_GLOBAL = 0x01, 102 HPROF_ROOT_JNI_LOCAL = 0x02, 103 HPROF_ROOT_JAVA_FRAME = 0x03, 104 HPROF_ROOT_NATIVE_STACK = 0x04, 105 HPROF_ROOT_STICKY_CLASS = 0x05, 106 HPROF_ROOT_THREAD_BLOCK = 0x06, 107 HPROF_ROOT_MONITOR_USED = 0x07, 108 HPROF_ROOT_THREAD_OBJECT = 0x08, 109 HPROF_CLASS_DUMP = 0x20, 110 HPROF_INSTANCE_DUMP = 0x21, 111 HPROF_OBJECT_ARRAY_DUMP = 0x22, 112 HPROF_PRIMITIVE_ARRAY_DUMP = 0x23, 113 114 // Android. 115 HPROF_HEAP_DUMP_INFO = 0xfe, 116 HPROF_ROOT_INTERNED_STRING = 0x89, 117 HPROF_ROOT_FINALIZING = 0x8a, // Obsolete. 118 HPROF_ROOT_DEBUGGER = 0x8b, 119 HPROF_ROOT_REFERENCE_CLEANUP = 0x8c, // Obsolete. 120 HPROF_ROOT_VM_INTERNAL = 0x8d, 121 HPROF_ROOT_JNI_MONITOR = 0x8e, 122 HPROF_UNREACHABLE = 0x90, // Obsolete. 123 HPROF_PRIMITIVE_ARRAY_NODATA_DUMP = 0xc3, // Obsolete. 124 }; 125 126 enum HprofHeapId { 127 HPROF_HEAP_DEFAULT = 0, 128 HPROF_HEAP_ZYGOTE = 'Z', 129 HPROF_HEAP_APP = 'A', 130 HPROF_HEAP_IMAGE = 'I', 131 }; 132 133 enum HprofBasicType { 134 hprof_basic_object = 2, 135 hprof_basic_boolean = 4, 136 hprof_basic_char = 5, 137 hprof_basic_float = 6, 138 hprof_basic_double = 7, 139 hprof_basic_byte = 8, 140 hprof_basic_short = 9, 141 hprof_basic_int = 10, 142 hprof_basic_long = 11, 143 }; 144 145 typedef uint32_t HprofStringId; 146 typedef uint32_t HprofClassObjectId; 147 148 class EndianOutput { 149 public: 150 EndianOutput() : length_(0), sum_length_(0), max_length_(0), started_(false) {} 151 virtual ~EndianOutput() {} 152 153 void StartNewRecord(uint8_t tag, uint32_t time) { 154 if (length_ > 0) { 155 EndRecord(); 156 } 157 DCHECK_EQ(length_, 0U); 158 AddU1(tag); 159 AddU4(time); 160 AddU4(0xdeaddead); // Length, replaced on flush. 161 started_ = true; 162 } 163 164 void EndRecord() { 165 // Replace length in header. 166 if (started_) { 167 UpdateU4(sizeof(uint8_t) + sizeof(uint32_t), 168 length_ - sizeof(uint8_t) - 2 * sizeof(uint32_t)); 169 } 170 171 HandleEndRecord(); 172 173 sum_length_ += length_; 174 max_length_ = std::max(max_length_, length_); 175 length_ = 0; 176 started_ = false; 177 } 178 179 void AddU1(uint8_t value) { 180 AddU1List(&value, 1); 181 } 182 void AddU2(uint16_t value) { 183 AddU2List(&value, 1); 184 } 185 void AddU4(uint32_t value) { 186 AddU4List(&value, 1); 187 } 188 189 void AddU8(uint64_t value) { 190 AddU8List(&value, 1); 191 } 192 193 void AddObjectId(const mirror::Object* value) { 194 AddU4(PointerToLowMemUInt32(value)); 195 } 196 197 // The ID for the synthetic object generated to account for class static overhead. 198 void AddClassStaticsId(const mirror::Class* value) { 199 AddU4(1 | PointerToLowMemUInt32(value)); 200 } 201 202 void AddJniGlobalRefId(jobject value) { 203 AddU4(PointerToLowMemUInt32(value)); 204 } 205 206 void AddClassId(HprofClassObjectId value) { 207 AddU4(value); 208 } 209 210 void AddStringId(HprofStringId value) { 211 AddU4(value); 212 } 213 214 void AddU1List(const uint8_t* values, size_t count) { 215 HandleU1List(values, count); 216 length_ += count; 217 } 218 void AddU2List(const uint16_t* values, size_t count) { 219 HandleU2List(values, count); 220 length_ += count * sizeof(uint16_t); 221 } 222 void AddU4List(const uint32_t* values, size_t count) { 223 HandleU4List(values, count); 224 length_ += count * sizeof(uint32_t); 225 } 226 virtual void UpdateU4(size_t offset, uint32_t new_value ATTRIBUTE_UNUSED) { 227 DCHECK_LE(offset, length_ - 4); 228 } 229 void AddU8List(const uint64_t* values, size_t count) { 230 HandleU8List(values, count); 231 length_ += count * sizeof(uint64_t); 232 } 233 234 void AddIdList(mirror::ObjectArray<mirror::Object>* values) 235 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 236 const int32_t length = values->GetLength(); 237 for (int32_t i = 0; i < length; ++i) { 238 AddObjectId(values->GetWithoutChecks(i)); 239 } 240 } 241 242 void AddUtf8String(const char* str) { 243 // The terminating NUL character is NOT written. 244 AddU1List((const uint8_t*)str, strlen(str)); 245 } 246 247 size_t Length() const { 248 return length_; 249 } 250 251 size_t SumLength() const { 252 return sum_length_; 253 } 254 255 size_t MaxLength() const { 256 return max_length_; 257 } 258 259 protected: 260 virtual void HandleU1List(const uint8_t* values ATTRIBUTE_UNUSED, 261 size_t count ATTRIBUTE_UNUSED) { 262 } 263 virtual void HandleU2List(const uint16_t* values ATTRIBUTE_UNUSED, 264 size_t count ATTRIBUTE_UNUSED) { 265 } 266 virtual void HandleU4List(const uint32_t* values ATTRIBUTE_UNUSED, 267 size_t count ATTRIBUTE_UNUSED) { 268 } 269 virtual void HandleU8List(const uint64_t* values ATTRIBUTE_UNUSED, 270 size_t count ATTRIBUTE_UNUSED) { 271 } 272 virtual void HandleEndRecord() { 273 } 274 275 size_t length_; // Current record size. 276 size_t sum_length_; // Size of all data. 277 size_t max_length_; // Maximum seen length. 278 bool started_; // Was StartRecord called? 279 }; 280 281 // This keeps things buffered until flushed. 282 class EndianOutputBuffered : public EndianOutput { 283 public: 284 explicit EndianOutputBuffered(size_t reserve_size) { 285 buffer_.reserve(reserve_size); 286 } 287 virtual ~EndianOutputBuffered() {} 288 289 void UpdateU4(size_t offset, uint32_t new_value) OVERRIDE { 290 DCHECK_LE(offset, length_ - 4); 291 buffer_[offset + 0] = static_cast<uint8_t>((new_value >> 24) & 0xFF); 292 buffer_[offset + 1] = static_cast<uint8_t>((new_value >> 16) & 0xFF); 293 buffer_[offset + 2] = static_cast<uint8_t>((new_value >> 8) & 0xFF); 294 buffer_[offset + 3] = static_cast<uint8_t>((new_value >> 0) & 0xFF); 295 } 296 297 protected: 298 void HandleU1List(const uint8_t* values, size_t count) OVERRIDE { 299 DCHECK_EQ(length_, buffer_.size()); 300 buffer_.insert(buffer_.end(), values, values + count); 301 } 302 303 void HandleU2List(const uint16_t* values, size_t count) OVERRIDE { 304 DCHECK_EQ(length_, buffer_.size()); 305 for (size_t i = 0; i < count; ++i) { 306 uint16_t value = *values; 307 buffer_.push_back(static_cast<uint8_t>((value >> 8) & 0xFF)); 308 buffer_.push_back(static_cast<uint8_t>((value >> 0) & 0xFF)); 309 values++; 310 } 311 } 312 313 void HandleU4List(const uint32_t* values, size_t count) OVERRIDE { 314 DCHECK_EQ(length_, buffer_.size()); 315 for (size_t i = 0; i < count; ++i) { 316 uint32_t value = *values; 317 buffer_.push_back(static_cast<uint8_t>((value >> 24) & 0xFF)); 318 buffer_.push_back(static_cast<uint8_t>((value >> 16) & 0xFF)); 319 buffer_.push_back(static_cast<uint8_t>((value >> 8) & 0xFF)); 320 buffer_.push_back(static_cast<uint8_t>((value >> 0) & 0xFF)); 321 values++; 322 } 323 } 324 325 void HandleU8List(const uint64_t* values, size_t count) OVERRIDE { 326 DCHECK_EQ(length_, buffer_.size()); 327 for (size_t i = 0; i < count; ++i) { 328 uint64_t value = *values; 329 buffer_.push_back(static_cast<uint8_t>((value >> 56) & 0xFF)); 330 buffer_.push_back(static_cast<uint8_t>((value >> 48) & 0xFF)); 331 buffer_.push_back(static_cast<uint8_t>((value >> 40) & 0xFF)); 332 buffer_.push_back(static_cast<uint8_t>((value >> 32) & 0xFF)); 333 buffer_.push_back(static_cast<uint8_t>((value >> 24) & 0xFF)); 334 buffer_.push_back(static_cast<uint8_t>((value >> 16) & 0xFF)); 335 buffer_.push_back(static_cast<uint8_t>((value >> 8) & 0xFF)); 336 buffer_.push_back(static_cast<uint8_t>((value >> 0) & 0xFF)); 337 values++; 338 } 339 } 340 341 void HandleEndRecord() OVERRIDE { 342 DCHECK_EQ(buffer_.size(), length_); 343 if (kIsDebugBuild && started_) { 344 uint32_t stored_length = 345 static_cast<uint32_t>(buffer_[5]) << 24 | 346 static_cast<uint32_t>(buffer_[6]) << 16 | 347 static_cast<uint32_t>(buffer_[7]) << 8 | 348 static_cast<uint32_t>(buffer_[8]); 349 DCHECK_EQ(stored_length, length_ - sizeof(uint8_t) - 2 * sizeof(uint32_t)); 350 } 351 HandleFlush(buffer_.data(), length_); 352 buffer_.clear(); 353 } 354 355 virtual void HandleFlush(const uint8_t* buffer ATTRIBUTE_UNUSED, size_t length ATTRIBUTE_UNUSED) { 356 } 357 358 std::vector<uint8_t> buffer_; 359 }; 360 361 class FileEndianOutput FINAL : public EndianOutputBuffered { 362 public: 363 FileEndianOutput(File* fp, size_t reserved_size) 364 : EndianOutputBuffered(reserved_size), fp_(fp), errors_(false) { 365 DCHECK(fp != nullptr); 366 } 367 ~FileEndianOutput() { 368 } 369 370 bool Errors() { 371 return errors_; 372 } 373 374 protected: 375 void HandleFlush(const uint8_t* buffer, size_t length) OVERRIDE { 376 if (!errors_) { 377 errors_ = !fp_->WriteFully(buffer, length); 378 } 379 } 380 381 private: 382 File* fp_; 383 bool errors_; 384 }; 385 386 class NetStateEndianOutput FINAL : public EndianOutputBuffered { 387 public: 388 NetStateEndianOutput(JDWP::JdwpNetStateBase* net_state, size_t reserved_size) 389 : EndianOutputBuffered(reserved_size), net_state_(net_state) { 390 DCHECK(net_state != nullptr); 391 } 392 ~NetStateEndianOutput() {} 393 394 protected: 395 void HandleFlush(const uint8_t* buffer, size_t length) OVERRIDE { 396 std::vector<iovec> iov; 397 iov.push_back(iovec()); 398 iov[0].iov_base = const_cast<void*>(reinterpret_cast<const void*>(buffer)); 399 iov[0].iov_len = length; 400 net_state_->WriteBufferedPacketLocked(iov); 401 } 402 403 private: 404 JDWP::JdwpNetStateBase* net_state_; 405 }; 406 407 #define __ output_-> 408 409 class Hprof : public SingleRootVisitor { 410 public: 411 Hprof(const char* output_filename, int fd, bool direct_to_ddms) 412 : filename_(output_filename), 413 fd_(fd), 414 direct_to_ddms_(direct_to_ddms), 415 start_ns_(NanoTime()), 416 current_heap_(HPROF_HEAP_DEFAULT), 417 objects_in_segment_(0), 418 next_string_id_(0x400000) { 419 LOG(INFO) << "hprof: heap dump \"" << filename_ << "\" starting..."; 420 } 421 422 void Dump() 423 EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) 424 LOCKS_EXCLUDED(Locks::heap_bitmap_lock_) { 425 // First pass to measure the size of the dump. 426 size_t overall_size; 427 size_t max_length; 428 { 429 EndianOutput count_output; 430 output_ = &count_output; 431 ProcessHeap(false); 432 overall_size = count_output.SumLength(); 433 max_length = count_output.MaxLength(); 434 output_ = nullptr; 435 } 436 437 bool okay; 438 if (direct_to_ddms_) { 439 if (kDirectStream) { 440 okay = DumpToDdmsDirect(overall_size, max_length, CHUNK_TYPE("HPDS")); 441 } else { 442 okay = DumpToDdmsBuffered(overall_size, max_length); 443 } 444 } else { 445 okay = DumpToFile(overall_size, max_length); 446 } 447 448 if (okay) { 449 uint64_t duration = NanoTime() - start_ns_; 450 LOG(INFO) << "hprof: heap dump completed (" 451 << PrettySize(RoundUp(overall_size, 1024)) 452 << ") in " << PrettyDuration(duration); 453 } 454 } 455 456 private: 457 static void VisitObjectCallback(mirror::Object* obj, void* arg) 458 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 459 DCHECK(obj != nullptr); 460 DCHECK(arg != nullptr); 461 reinterpret_cast<Hprof*>(arg)->DumpHeapObject(obj); 462 } 463 464 void DumpHeapObject(mirror::Object* obj) 465 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 466 467 void DumpHeapClass(mirror::Class* klass) 468 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 469 470 void DumpHeapArray(mirror::Array* obj, mirror::Class* klass) 471 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 472 473 void DumpHeapInstanceObject(mirror::Object* obj, mirror::Class* klass) 474 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 475 476 void ProcessHeap(bool header_first) 477 EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) { 478 // Reset current heap and object count. 479 current_heap_ = HPROF_HEAP_DEFAULT; 480 objects_in_segment_ = 0; 481 482 if (header_first) { 483 ProcessHeader(); 484 ProcessBody(); 485 } else { 486 ProcessBody(); 487 ProcessHeader(); 488 } 489 } 490 491 void ProcessBody() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) { 492 Runtime* const runtime = Runtime::Current(); 493 // Walk the roots and the heap. 494 output_->StartNewRecord(HPROF_TAG_HEAP_DUMP_SEGMENT, kHprofTime); 495 496 runtime->VisitRoots(this); 497 runtime->VisitImageRoots(this); 498 runtime->GetHeap()->VisitObjectsPaused(VisitObjectCallback, this); 499 500 output_->StartNewRecord(HPROF_TAG_HEAP_DUMP_END, kHprofTime); 501 output_->EndRecord(); 502 } 503 504 void ProcessHeader() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) { 505 // Write the header. 506 WriteFixedHeader(); 507 // Write the string and class tables, and any stack traces, to the header. 508 // (jhat requires that these appear before any of the data in the body that refers to them.) 509 WriteStringTable(); 510 WriteClassTable(); 511 WriteStackTraces(); 512 output_->EndRecord(); 513 } 514 515 void WriteClassTable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 516 uint32_t nextSerialNumber = 1; 517 518 for (mirror::Class* c : classes_) { 519 CHECK(c != nullptr); 520 output_->StartNewRecord(HPROF_TAG_LOAD_CLASS, kHprofTime); 521 // LOAD CLASS format: 522 // U4: class serial number (always > 0) 523 // ID: class object ID. We use the address of the class object structure as its ID. 524 // U4: stack trace serial number 525 // ID: class name string ID 526 __ AddU4(nextSerialNumber++); 527 __ AddObjectId(c); 528 __ AddU4(kHprofNullStackTrace); 529 __ AddStringId(LookupClassNameId(c)); 530 } 531 } 532 533 void WriteStringTable() { 534 for (const std::pair<std::string, HprofStringId>& p : strings_) { 535 const std::string& string = p.first; 536 const size_t id = p.second; 537 538 output_->StartNewRecord(HPROF_TAG_STRING, kHprofTime); 539 540 // STRING format: 541 // ID: ID for this string 542 // U1*: UTF8 characters for string (NOT null terminated) 543 // (the record format encodes the length) 544 __ AddU4(id); 545 __ AddUtf8String(string.c_str()); 546 } 547 } 548 549 void StartNewHeapDumpSegment() { 550 // This flushes the old segment and starts a new one. 551 output_->StartNewRecord(HPROF_TAG_HEAP_DUMP_SEGMENT, kHprofTime); 552 objects_in_segment_ = 0; 553 // Starting a new HEAP_DUMP resets the heap to default. 554 current_heap_ = HPROF_HEAP_DEFAULT; 555 } 556 557 void CheckHeapSegmentConstraints() { 558 if (objects_in_segment_ >= kMaxObjectsPerSegment || output_->Length() >= kMaxBytesPerSegment) { 559 StartNewHeapDumpSegment(); 560 } 561 } 562 563 void VisitRoot(mirror::Object* obj, const RootInfo& root_info) 564 OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 565 void MarkRootObject(const mirror::Object* obj, jobject jni_obj, HprofHeapTag heap_tag, 566 uint32_t thread_serial); 567 568 HprofClassObjectId LookupClassId(mirror::Class* c) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 569 if (c != nullptr) { 570 auto result = classes_.insert(c); 571 const mirror::Class* present = *result.first; 572 CHECK_EQ(present, c); 573 // Make sure that we've assigned a string ID for this class' name 574 LookupClassNameId(c); 575 } 576 return PointerToLowMemUInt32(c); 577 } 578 579 HprofStringId LookupStringId(mirror::String* string) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 580 return LookupStringId(string->ToModifiedUtf8()); 581 } 582 583 HprofStringId LookupStringId(const char* string) { 584 return LookupStringId(std::string(string)); 585 } 586 587 HprofStringId LookupStringId(const std::string& string) { 588 auto it = strings_.find(string); 589 if (it != strings_.end()) { 590 return it->second; 591 } 592 HprofStringId id = next_string_id_++; 593 strings_.Put(string, id); 594 return id; 595 } 596 597 HprofStringId LookupClassNameId(mirror::Class* c) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 598 return LookupStringId(PrettyDescriptor(c)); 599 } 600 601 void WriteFixedHeader() { 602 // Write the file header. 603 // U1: NUL-terminated magic string. 604 const char magic[] = "JAVA PROFILE 1.0.3"; 605 __ AddU1List(reinterpret_cast<const uint8_t*>(magic), sizeof(magic)); 606 607 // U4: size of identifiers. We're using addresses as IDs and our heap references are stored 608 // as uint32_t. 609 // Note of warning: hprof-conv hard-codes the size of identifiers to 4. 610 static_assert(sizeof(mirror::HeapReference<mirror::Object>) == sizeof(uint32_t), 611 "Unexpected HeapReference size"); 612 __ AddU4(sizeof(uint32_t)); 613 614 // The current time, in milliseconds since 0:00 GMT, 1/1/70. 615 timeval now; 616 const uint64_t nowMs = (gettimeofday(&now, nullptr) < 0) ? 0 : 617 (uint64_t)now.tv_sec * 1000 + now.tv_usec / 1000; 618 // TODO: It seems it would be correct to use U8. 619 // U4: high word of the 64-bit time. 620 __ AddU4(static_cast<uint32_t>(nowMs >> 32)); 621 // U4: low word of the 64-bit time. 622 __ AddU4(static_cast<uint32_t>(nowMs & 0xFFFFFFFF)); 623 } 624 625 void WriteStackTraces() { 626 // Write a dummy stack trace record so the analysis tools don't freak out. 627 output_->StartNewRecord(HPROF_TAG_STACK_TRACE, kHprofTime); 628 __ AddU4(kHprofNullStackTrace); 629 __ AddU4(kHprofNullThread); 630 __ AddU4(0); // no frames 631 } 632 633 bool DumpToDdmsBuffered(size_t overall_size ATTRIBUTE_UNUSED, size_t max_length ATTRIBUTE_UNUSED) 634 EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) { 635 LOG(FATAL) << "Unimplemented"; 636 UNREACHABLE(); 637 // // Send the data off to DDMS. 638 // iovec iov[2]; 639 // iov[0].iov_base = header_data_ptr_; 640 // iov[0].iov_len = header_data_size_; 641 // iov[1].iov_base = body_data_ptr_; 642 // iov[1].iov_len = body_data_size_; 643 // Dbg::DdmSendChunkV(CHUNK_TYPE("HPDS"), iov, 2); 644 } 645 646 bool DumpToFile(size_t overall_size, size_t max_length) 647 EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) { 648 // Where exactly are we writing to? 649 int out_fd; 650 if (fd_ >= 0) { 651 out_fd = dup(fd_); 652 if (out_fd < 0) { 653 ThrowRuntimeException("Couldn't dump heap; dup(%d) failed: %s", fd_, strerror(errno)); 654 return false; 655 } 656 } else { 657 out_fd = open(filename_.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644); 658 if (out_fd < 0) { 659 ThrowRuntimeException("Couldn't dump heap; open(\"%s\") failed: %s", filename_.c_str(), 660 strerror(errno)); 661 return false; 662 } 663 } 664 665 std::unique_ptr<File> file(new File(out_fd, filename_, true)); 666 bool okay; 667 { 668 FileEndianOutput file_output(file.get(), max_length); 669 output_ = &file_output; 670 ProcessHeap(true); 671 okay = !file_output.Errors(); 672 673 if (okay) { 674 // Check for expected size. Output is expected to be less-or-equal than first phase, see 675 // b/23521263. 676 DCHECK_LE(file_output.SumLength(), overall_size); 677 } 678 output_ = nullptr; 679 } 680 681 if (okay) { 682 okay = file->FlushCloseOrErase() == 0; 683 } else { 684 file->Erase(); 685 } 686 if (!okay) { 687 std::string msg(StringPrintf("Couldn't dump heap; writing \"%s\" failed: %s", 688 filename_.c_str(), strerror(errno))); 689 ThrowRuntimeException("%s", msg.c_str()); 690 LOG(ERROR) << msg; 691 } 692 693 return okay; 694 } 695 696 bool DumpToDdmsDirect(size_t overall_size, size_t max_length, uint32_t chunk_type) 697 EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) { 698 CHECK(direct_to_ddms_); 699 JDWP::JdwpState* state = Dbg::GetJdwpState(); 700 CHECK(state != nullptr); 701 JDWP::JdwpNetStateBase* net_state = state->netState; 702 CHECK(net_state != nullptr); 703 704 // Hold the socket lock for the whole time since we want this to be atomic. 705 MutexLock mu(Thread::Current(), *net_state->GetSocketLock()); 706 707 // Prepare the Ddms chunk. 708 constexpr size_t kChunkHeaderSize = kJDWPHeaderLen + 8; 709 uint8_t chunk_header[kChunkHeaderSize] = { 0 }; 710 state->SetupChunkHeader(chunk_type, overall_size, kChunkHeaderSize, chunk_header); 711 712 // Prepare the output and send the chunk header. 713 NetStateEndianOutput net_output(net_state, max_length); 714 output_ = &net_output; 715 net_output.AddU1List(chunk_header, kChunkHeaderSize); 716 717 // Write the dump. 718 ProcessHeap(true); 719 720 // Check for expected size. See DumpToFile for comment. 721 DCHECK_LE(net_output.SumLength(), overall_size + kChunkHeaderSize); 722 output_ = nullptr; 723 724 return true; 725 } 726 727 // If direct_to_ddms_ is set, "filename_" and "fd" will be ignored. 728 // Otherwise, "filename_" must be valid, though if "fd" >= 0 it will 729 // only be used for debug messages. 730 std::string filename_; 731 int fd_; 732 bool direct_to_ddms_; 733 734 uint64_t start_ns_; 735 736 EndianOutput* output_; 737 738 HprofHeapId current_heap_; // Which heap we're currently dumping. 739 size_t objects_in_segment_; 740 741 std::set<mirror::Class*> classes_; 742 HprofStringId next_string_id_; 743 SafeMap<std::string, HprofStringId> strings_; 744 745 DISALLOW_COPY_AND_ASSIGN(Hprof); 746 }; 747 748 static HprofBasicType SignatureToBasicTypeAndSize(const char* sig, size_t* size_out) { 749 char c = sig[0]; 750 HprofBasicType ret; 751 size_t size; 752 753 switch (c) { 754 case '[': 755 case 'L': 756 ret = hprof_basic_object; 757 size = 4; 758 break; 759 case 'Z': 760 ret = hprof_basic_boolean; 761 size = 1; 762 break; 763 case 'C': 764 ret = hprof_basic_char; 765 size = 2; 766 break; 767 case 'F': 768 ret = hprof_basic_float; 769 size = 4; 770 break; 771 case 'D': 772 ret = hprof_basic_double; 773 size = 8; 774 break; 775 case 'B': 776 ret = hprof_basic_byte; 777 size = 1; 778 break; 779 case 'S': 780 ret = hprof_basic_short; 781 size = 2; 782 break; 783 case 'I': 784 ret = hprof_basic_int; 785 size = 4; 786 break; 787 case 'J': 788 ret = hprof_basic_long; 789 size = 8; 790 break; 791 default: 792 LOG(FATAL) << "UNREACHABLE"; 793 UNREACHABLE(); 794 } 795 796 if (size_out != nullptr) { 797 *size_out = size; 798 } 799 800 return ret; 801 } 802 803 // Always called when marking objects, but only does 804 // something when ctx->gc_scan_state_ is non-zero, which is usually 805 // only true when marking the root set or unreachable 806 // objects. Used to add rootset references to obj. 807 void Hprof::MarkRootObject(const mirror::Object* obj, jobject jni_obj, HprofHeapTag heap_tag, 808 uint32_t thread_serial) { 809 if (heap_tag == 0) { 810 return; 811 } 812 813 CheckHeapSegmentConstraints(); 814 815 switch (heap_tag) { 816 // ID: object ID 817 case HPROF_ROOT_UNKNOWN: 818 case HPROF_ROOT_STICKY_CLASS: 819 case HPROF_ROOT_MONITOR_USED: 820 case HPROF_ROOT_INTERNED_STRING: 821 case HPROF_ROOT_DEBUGGER: 822 case HPROF_ROOT_VM_INTERNAL: 823 __ AddU1(heap_tag); 824 __ AddObjectId(obj); 825 break; 826 827 // ID: object ID 828 // ID: JNI global ref ID 829 case HPROF_ROOT_JNI_GLOBAL: 830 __ AddU1(heap_tag); 831 __ AddObjectId(obj); 832 __ AddJniGlobalRefId(jni_obj); 833 break; 834 835 // ID: object ID 836 // U4: thread serial number 837 // U4: frame number in stack trace (-1 for empty) 838 case HPROF_ROOT_JNI_LOCAL: 839 case HPROF_ROOT_JNI_MONITOR: 840 case HPROF_ROOT_JAVA_FRAME: 841 __ AddU1(heap_tag); 842 __ AddObjectId(obj); 843 __ AddU4(thread_serial); 844 __ AddU4((uint32_t)-1); 845 break; 846 847 // ID: object ID 848 // U4: thread serial number 849 case HPROF_ROOT_NATIVE_STACK: 850 case HPROF_ROOT_THREAD_BLOCK: 851 __ AddU1(heap_tag); 852 __ AddObjectId(obj); 853 __ AddU4(thread_serial); 854 break; 855 856 // ID: thread object ID 857 // U4: thread serial number 858 // U4: stack trace serial number 859 case HPROF_ROOT_THREAD_OBJECT: 860 __ AddU1(heap_tag); 861 __ AddObjectId(obj); 862 __ AddU4(thread_serial); 863 __ AddU4((uint32_t)-1); // xxx 864 break; 865 866 case HPROF_CLASS_DUMP: 867 case HPROF_INSTANCE_DUMP: 868 case HPROF_OBJECT_ARRAY_DUMP: 869 case HPROF_PRIMITIVE_ARRAY_DUMP: 870 case HPROF_HEAP_DUMP_INFO: 871 case HPROF_PRIMITIVE_ARRAY_NODATA_DUMP: 872 // Ignored. 873 break; 874 875 case HPROF_ROOT_FINALIZING: 876 case HPROF_ROOT_REFERENCE_CLEANUP: 877 case HPROF_UNREACHABLE: 878 LOG(FATAL) << "obsolete tag " << static_cast<int>(heap_tag); 879 break; 880 } 881 882 ++objects_in_segment_; 883 } 884 885 static int StackTraceSerialNumber(const mirror::Object* /*obj*/) { 886 return kHprofNullStackTrace; 887 } 888 889 void Hprof::DumpHeapObject(mirror::Object* obj) { 890 // Ignore classes that are retired. 891 if (obj->IsClass() && obj->AsClass()->IsRetired()) { 892 return; 893 } 894 895 gc::Heap* const heap = Runtime::Current()->GetHeap(); 896 const gc::space::ContinuousSpace* const space = heap->FindContinuousSpaceFromObject(obj, true); 897 HprofHeapId heap_type = HPROF_HEAP_APP; 898 if (space != nullptr) { 899 if (space->IsZygoteSpace()) { 900 heap_type = HPROF_HEAP_ZYGOTE; 901 } else if (space->IsImageSpace()) { 902 heap_type = HPROF_HEAP_IMAGE; 903 } 904 } else { 905 const auto* los = heap->GetLargeObjectsSpace(); 906 if (los->Contains(obj) && los->IsZygoteLargeObject(Thread::Current(), obj)) { 907 heap_type = HPROF_HEAP_ZYGOTE; 908 } 909 } 910 CheckHeapSegmentConstraints(); 911 912 if (heap_type != current_heap_) { 913 HprofStringId nameId; 914 915 // This object is in a different heap than the current one. 916 // Emit a HEAP_DUMP_INFO tag to change heaps. 917 __ AddU1(HPROF_HEAP_DUMP_INFO); 918 __ AddU4(static_cast<uint32_t>(heap_type)); // uint32_t: heap type 919 switch (heap_type) { 920 case HPROF_HEAP_APP: 921 nameId = LookupStringId("app"); 922 break; 923 case HPROF_HEAP_ZYGOTE: 924 nameId = LookupStringId("zygote"); 925 break; 926 case HPROF_HEAP_IMAGE: 927 nameId = LookupStringId("image"); 928 break; 929 default: 930 // Internal error 931 LOG(ERROR) << "Unexpected desiredHeap"; 932 nameId = LookupStringId("<ILLEGAL>"); 933 break; 934 } 935 __ AddStringId(nameId); 936 current_heap_ = heap_type; 937 } 938 939 mirror::Class* c = obj->GetClass(); 940 if (c == nullptr) { 941 // This object will bother HprofReader, because it has a null 942 // class, so just don't dump it. It could be 943 // gDvm.unlinkedJavaLangClass or it could be an object just 944 // allocated which hasn't been initialized yet. 945 } else { 946 if (obj->IsClass()) { 947 DumpHeapClass(obj->AsClass()); 948 } else if (c->IsArrayClass()) { 949 DumpHeapArray(obj->AsArray(), c); 950 } else { 951 DumpHeapInstanceObject(obj, c); 952 } 953 } 954 955 ++objects_in_segment_; 956 } 957 958 void Hprof::DumpHeapClass(mirror::Class* klass) { 959 if (!klass->IsLoaded() && !klass->IsErroneous()) { 960 // Class is allocated but not yet loaded: we cannot access its fields or super class. 961 return; 962 } 963 size_t sFieldCount = klass->NumStaticFields(); 964 if (sFieldCount != 0) { 965 int byteLength = sFieldCount * sizeof(JValue); // TODO bogus; fields are packed 966 // Create a byte array to reflect the allocation of the 967 // StaticField array at the end of this class. 968 __ AddU1(HPROF_PRIMITIVE_ARRAY_DUMP); 969 __ AddClassStaticsId(klass); 970 __ AddU4(StackTraceSerialNumber(klass)); 971 __ AddU4(byteLength); 972 __ AddU1(hprof_basic_byte); 973 for (int i = 0; i < byteLength; ++i) { 974 __ AddU1(0); 975 } 976 } 977 978 __ AddU1(HPROF_CLASS_DUMP); 979 __ AddClassId(LookupClassId(klass)); 980 __ AddU4(StackTraceSerialNumber(klass)); 981 __ AddClassId(LookupClassId(klass->GetSuperClass())); 982 __ AddObjectId(klass->GetClassLoader()); 983 __ AddObjectId(nullptr); // no signer 984 __ AddObjectId(nullptr); // no prot domain 985 __ AddObjectId(nullptr); // reserved 986 __ AddObjectId(nullptr); // reserved 987 if (klass->IsClassClass()) { 988 // ClassObjects have their static fields appended, so aren't all the same size. 989 // But they're at least this size. 990 __ AddU4(sizeof(mirror::Class)); // instance size 991 } else if (klass->IsStringClass()) { 992 // Strings are variable length with character data at the end like arrays. 993 // This outputs the size of an empty string. 994 __ AddU4(sizeof(mirror::String)); 995 } else if (klass->IsArrayClass() || klass->IsPrimitive()) { 996 __ AddU4(0); 997 } else { 998 __ AddU4(klass->GetObjectSize()); // instance size 999 } 1000 1001 __ AddU2(0); // empty const pool 1002 1003 // Static fields 1004 if (sFieldCount == 0) { 1005 __ AddU2((uint16_t)0); 1006 } else { 1007 __ AddU2((uint16_t)(sFieldCount+1)); 1008 __ AddStringId(LookupStringId(kStaticOverheadName)); 1009 __ AddU1(hprof_basic_object); 1010 __ AddClassStaticsId(klass); 1011 1012 for (size_t i = 0; i < sFieldCount; ++i) { 1013 ArtField* f = klass->GetStaticField(i); 1014 1015 size_t size; 1016 HprofBasicType t = SignatureToBasicTypeAndSize(f->GetTypeDescriptor(), &size); 1017 __ AddStringId(LookupStringId(f->GetName())); 1018 __ AddU1(t); 1019 switch (t) { 1020 case hprof_basic_byte: 1021 __ AddU1(f->GetByte(klass)); 1022 break; 1023 case hprof_basic_boolean: 1024 __ AddU1(f->GetBoolean(klass)); 1025 break; 1026 case hprof_basic_char: 1027 __ AddU2(f->GetChar(klass)); 1028 break; 1029 case hprof_basic_short: 1030 __ AddU2(f->GetShort(klass)); 1031 break; 1032 case hprof_basic_float: 1033 case hprof_basic_int: 1034 case hprof_basic_object: 1035 __ AddU4(f->Get32(klass)); 1036 break; 1037 case hprof_basic_double: 1038 case hprof_basic_long: 1039 __ AddU8(f->Get64(klass)); 1040 break; 1041 default: 1042 LOG(FATAL) << "Unexpected size " << size; 1043 UNREACHABLE(); 1044 } 1045 } 1046 } 1047 1048 // Instance fields for this class (no superclass fields) 1049 int iFieldCount = klass->NumInstanceFields(); 1050 if (klass->IsStringClass()) { 1051 __ AddU2((uint16_t)iFieldCount + 1); 1052 } else { 1053 __ AddU2((uint16_t)iFieldCount); 1054 } 1055 for (int i = 0; i < iFieldCount; ++i) { 1056 ArtField* f = klass->GetInstanceField(i); 1057 __ AddStringId(LookupStringId(f->GetName())); 1058 HprofBasicType t = SignatureToBasicTypeAndSize(f->GetTypeDescriptor(), nullptr); 1059 __ AddU1(t); 1060 } 1061 // Add native value character array for strings. 1062 if (klass->IsStringClass()) { 1063 __ AddStringId(LookupStringId("value")); 1064 __ AddU1(hprof_basic_object); 1065 } 1066 } 1067 1068 void Hprof::DumpHeapArray(mirror::Array* obj, mirror::Class* klass) { 1069 uint32_t length = obj->GetLength(); 1070 1071 if (obj->IsObjectArray()) { 1072 // obj is an object array. 1073 __ AddU1(HPROF_OBJECT_ARRAY_DUMP); 1074 1075 __ AddObjectId(obj); 1076 __ AddU4(StackTraceSerialNumber(obj)); 1077 __ AddU4(length); 1078 __ AddClassId(LookupClassId(klass)); 1079 1080 // Dump the elements, which are always objects or null. 1081 __ AddIdList(obj->AsObjectArray<mirror::Object>()); 1082 } else { 1083 size_t size; 1084 HprofBasicType t = SignatureToBasicTypeAndSize( 1085 Primitive::Descriptor(klass->GetComponentType()->GetPrimitiveType()), &size); 1086 1087 // obj is a primitive array. 1088 __ AddU1(HPROF_PRIMITIVE_ARRAY_DUMP); 1089 1090 __ AddObjectId(obj); 1091 __ AddU4(StackTraceSerialNumber(obj)); 1092 __ AddU4(length); 1093 __ AddU1(t); 1094 1095 // Dump the raw, packed element values. 1096 if (size == 1) { 1097 __ AddU1List(reinterpret_cast<const uint8_t*>(obj->GetRawData(sizeof(uint8_t), 0)), length); 1098 } else if (size == 2) { 1099 __ AddU2List(reinterpret_cast<const uint16_t*>(obj->GetRawData(sizeof(uint16_t), 0)), length); 1100 } else if (size == 4) { 1101 __ AddU4List(reinterpret_cast<const uint32_t*>(obj->GetRawData(sizeof(uint32_t), 0)), length); 1102 } else if (size == 8) { 1103 __ AddU8List(reinterpret_cast<const uint64_t*>(obj->GetRawData(sizeof(uint64_t), 0)), length); 1104 } 1105 } 1106 } 1107 1108 void Hprof::DumpHeapInstanceObject(mirror::Object* obj, mirror::Class* klass) { 1109 // obj is an instance object. 1110 __ AddU1(HPROF_INSTANCE_DUMP); 1111 __ AddObjectId(obj); 1112 __ AddU4(StackTraceSerialNumber(obj)); 1113 __ AddClassId(LookupClassId(klass)); 1114 1115 // Reserve some space for the length of the instance data, which we won't 1116 // know until we're done writing it. 1117 size_t size_patch_offset = output_->Length(); 1118 __ AddU4(0x77777777); 1119 1120 // What we will use for the string value if the object is a string. 1121 mirror::Object* string_value = nullptr; 1122 1123 // Write the instance data; fields for this class, followed by super class fields, and so on. 1124 do { 1125 const size_t instance_fields = klass->NumInstanceFields(); 1126 for (size_t i = 0; i < instance_fields; ++i) { 1127 ArtField* f = klass->GetInstanceField(i); 1128 size_t size; 1129 HprofBasicType t = SignatureToBasicTypeAndSize(f->GetTypeDescriptor(), &size); 1130 switch (t) { 1131 case hprof_basic_byte: 1132 __ AddU1(f->GetByte(obj)); 1133 break; 1134 case hprof_basic_boolean: 1135 __ AddU1(f->GetBoolean(obj)); 1136 break; 1137 case hprof_basic_char: 1138 __ AddU2(f->GetChar(obj)); 1139 break; 1140 case hprof_basic_short: 1141 __ AddU2(f->GetShort(obj)); 1142 break; 1143 case hprof_basic_float: 1144 case hprof_basic_int: 1145 case hprof_basic_object: 1146 __ AddU4(f->Get32(obj)); 1147 break; 1148 case hprof_basic_double: 1149 case hprof_basic_long: 1150 __ AddU8(f->Get64(obj)); 1151 break; 1152 } 1153 } 1154 // Add value field for String if necessary. 1155 if (klass->IsStringClass()) { 1156 mirror::String* s = obj->AsString(); 1157 if (s->GetLength() == 0) { 1158 // If string is empty, use an object-aligned address within the string for the value. 1159 string_value = reinterpret_cast<mirror::Object*>( 1160 reinterpret_cast<uintptr_t>(s) + kObjectAlignment); 1161 } else { 1162 string_value = reinterpret_cast<mirror::Object*>(s->GetValue()); 1163 } 1164 __ AddObjectId(string_value); 1165 } 1166 1167 klass = klass->GetSuperClass(); 1168 } while (klass != nullptr); 1169 1170 // Patch the instance field length. 1171 __ UpdateU4(size_patch_offset, output_->Length() - (size_patch_offset + 4)); 1172 1173 // Output native value character array for strings. 1174 CHECK_EQ(obj->IsString(), string_value != nullptr); 1175 if (string_value != nullptr) { 1176 mirror::String* s = obj->AsString(); 1177 __ AddU1(HPROF_PRIMITIVE_ARRAY_DUMP); 1178 __ AddObjectId(string_value); 1179 __ AddU4(StackTraceSerialNumber(obj)); 1180 __ AddU4(s->GetLength()); 1181 __ AddU1(hprof_basic_char); 1182 __ AddU2List(s->GetValue(), s->GetLength()); 1183 } 1184 } 1185 1186 void Hprof::VisitRoot(mirror::Object* obj, const RootInfo& info) { 1187 static const HprofHeapTag xlate[] = { 1188 HPROF_ROOT_UNKNOWN, 1189 HPROF_ROOT_JNI_GLOBAL, 1190 HPROF_ROOT_JNI_LOCAL, 1191 HPROF_ROOT_JAVA_FRAME, 1192 HPROF_ROOT_NATIVE_STACK, 1193 HPROF_ROOT_STICKY_CLASS, 1194 HPROF_ROOT_THREAD_BLOCK, 1195 HPROF_ROOT_MONITOR_USED, 1196 HPROF_ROOT_THREAD_OBJECT, 1197 HPROF_ROOT_INTERNED_STRING, 1198 HPROF_ROOT_FINALIZING, 1199 HPROF_ROOT_DEBUGGER, 1200 HPROF_ROOT_REFERENCE_CLEANUP, 1201 HPROF_ROOT_VM_INTERNAL, 1202 HPROF_ROOT_JNI_MONITOR, 1203 }; 1204 CHECK_LT(info.GetType(), sizeof(xlate) / sizeof(HprofHeapTag)); 1205 if (obj == nullptr) { 1206 return; 1207 } 1208 MarkRootObject(obj, 0, xlate[info.GetType()], info.GetThreadId()); 1209 } 1210 1211 // If "direct_to_ddms" is true, the other arguments are ignored, and data is 1212 // sent directly to DDMS. 1213 // If "fd" is >= 0, the output will be written to that file descriptor. 1214 // Otherwise, "filename" is used to create an output file. 1215 void DumpHeap(const char* filename, int fd, bool direct_to_ddms) { 1216 CHECK(filename != nullptr); 1217 1218 Thread* self = Thread::Current(); 1219 gc::Heap* heap = Runtime::Current()->GetHeap(); 1220 if (heap->IsGcConcurrentAndMoving()) { 1221 // Need to take a heap dump while GC isn't running. See the 1222 // comment in Heap::VisitObjects(). 1223 heap->IncrementDisableMovingGC(self); 1224 } 1225 Runtime::Current()->GetThreadList()->SuspendAll(__FUNCTION__, true /* long suspend */); 1226 Hprof hprof(filename, fd, direct_to_ddms); 1227 hprof.Dump(); 1228 Runtime::Current()->GetThreadList()->ResumeAll(); 1229 if (heap->IsGcConcurrentAndMoving()) { 1230 heap->DecrementDisableMovingGC(self); 1231 } 1232 } 1233 1234 } // namespace hprof 1235 } // namespace art 1236