Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(200)

Side by Side Diff: runtime/vm/profiler.cc

Issue 1919743003: Add Profiler::DumpStackTrace (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/profiler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "platform/address_sanitizer.h" 5 #include "platform/address_sanitizer.h"
6 #include "platform/memory_sanitizer.h" 6 #include "platform/memory_sanitizer.h"
7 #include "platform/utils.h" 7 #include "platform/utils.h"
8 8
9 #include "vm/allocation.h" 9 #include "vm/allocation.h"
10 #include "vm/atomic.h" 10 #include "vm/atomic.h"
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 ClearProfileVisitor::ClearProfileVisitor(Isolate* isolate) 321 ClearProfileVisitor::ClearProfileVisitor(Isolate* isolate)
322 : SampleVisitor(isolate) { 322 : SampleVisitor(isolate) {
323 } 323 }
324 324
325 325
326 void ClearProfileVisitor::VisitSample(Sample* sample) { 326 void ClearProfileVisitor::VisitSample(Sample* sample) {
327 sample->Clear(); 327 sample->Clear();
328 } 328 }
329 329
330 330
331 static void DumpStackFrame(intptr_t frame_index, uword pc) {
332 uintptr_t start = 0;
333 char* native_symbol_name =
334 NativeSymbolResolver::LookupSymbolName(pc, &start);
335 if (native_symbol_name == NULL) {
336 OS::Print("Frame[%" Pd "] = `unknown symbol` [0x%" Px "]\n",
337 frame_index, pc);
338 } else {
339 OS::Print("Frame[%" Pd "] = `%s` [0x%" Px "]\n",
340 frame_index, native_symbol_name, pc);
341 free(native_symbol_name);
342 }
343 }
344
345
346 static void DumpStackFrame(intptr_t frame_index,
347 uword pc,
348 const Code& code) {
349 if (code.IsNull()) {
350 DumpStackFrame(frame_index, pc);
351 } else {
352 OS::Print("Frame[%" Pd "] = Dart:`%s` [0x%" Px "]\n",
353 frame_index, code.ToCString(), pc);
354 }
355 }
356
357
331 class ProfilerStackWalker : public ValueObject { 358 class ProfilerStackWalker : public ValueObject {
332 public: 359 public:
333 ProfilerStackWalker(Isolate* isolate, 360 ProfilerStackWalker(Isolate* isolate,
334 Sample* head_sample, 361 Sample* head_sample,
335 SampleBuffer* sample_buffer) 362 SampleBuffer* sample_buffer)
336 : isolate_(isolate), 363 : isolate_(isolate),
337 sample_(head_sample), 364 sample_(head_sample),
338 sample_buffer_(sample_buffer), 365 sample_buffer_(sample_buffer),
339 frame_index_(0), 366 frame_index_(0),
340 total_frames_(0) { 367 total_frames_(0) {
341 ASSERT(isolate_ != NULL); 368 ASSERT(isolate_ != NULL);
342 ASSERT(sample_ != NULL); 369 if (sample_ == NULL) {
343 ASSERT(sample_buffer_ != NULL); 370 ASSERT(sample_buffer_ == NULL);
344 ASSERT(sample_->head_sample()); 371 } else {
372 ASSERT(sample_buffer_ != NULL);
373 ASSERT(sample_->head_sample());
374 }
375 }
376
377 bool Append(uword pc, const Code& code) {
378 if (sample_ == NULL) {
379 DumpStackFrame(frame_index_, pc, code);
380 frame_index_++;
381 total_frames_++;
382 return true;
383 }
384 return Append(pc);
345 } 385 }
346 386
347 bool Append(uword pc) { 387 bool Append(uword pc) {
388 if (sample_ == NULL) {
389 DumpStackFrame(frame_index_, pc);
390 frame_index_++;
391 total_frames_++;
392 return true;
393 }
348 if (total_frames_ >= FLAG_max_profile_depth) { 394 if (total_frames_ >= FLAG_max_profile_depth) {
349 sample_->set_truncated_trace(true); 395 sample_->set_truncated_trace(true);
350 return false; 396 return false;
351 } 397 }
352 ASSERT(sample_ != NULL); 398 ASSERT(sample_ != NULL);
353 if (frame_index_ == kSampleSize) { 399 if (frame_index_ == kSampleSize) {
354 Sample* new_sample = sample_buffer_->ReserveSampleAndLink(sample_); 400 Sample* new_sample = sample_buffer_->ReserveSampleAndLink(sample_);
355 if (new_sample == NULL) { 401 if (new_sample == NULL) {
356 // Could not reserve new sample- mark this as truncated. 402 // Could not reserve new sample- mark this as truncated.
357 sample_->set_truncated_trace(true); 403 sample_->set_truncated_trace(true);
(...skipping 27 matching lines...) Expand all
385 SampleBuffer* sample_buffer) 431 SampleBuffer* sample_buffer)
386 : ProfilerStackWalker(isolate, sample, sample_buffer), 432 : ProfilerStackWalker(isolate, sample, sample_buffer),
387 frame_iterator_(thread) { 433 frame_iterator_(thread) {
388 } 434 }
389 435
390 void walk() { 436 void walk() {
391 // Mark that this sample was collected from an exit frame. 437 // Mark that this sample was collected from an exit frame.
392 sample_->set_exit_frame_sample(true); 438 sample_->set_exit_frame_sample(true);
393 439
394 StackFrame* frame = frame_iterator_.NextFrame(); 440 StackFrame* frame = frame_iterator_.NextFrame();
395 while (frame != NULL) { 441 if (sample_ == NULL) {
396 if (!Append(frame->pc())) { 442 // Only when we are dumping the stack trace for debug purposes.
397 return; 443 Code& code = Code::Handle();
444 while (frame != NULL) {
445 code ^= frame->LookupDartCode();
446 if (!Append(frame->pc(), code)) {
447 return;
448 }
449 frame = frame_iterator_.NextFrame();
398 } 450 }
399 frame = frame_iterator_.NextFrame(); 451 } else {
452 while (frame != NULL) {
453 if (!Append(frame->pc())) {
454 return;
455 }
456 frame = frame_iterator_.NextFrame();
457 }
400 } 458 }
401 } 459 }
402 460
403 private: 461 private:
404 DartFrameIterator frame_iterator_; 462 DartFrameIterator frame_iterator_;
405 }; 463 };
406 464
407 465
408 // Executing Dart code, walk the stack. 466 // Executing Dart code, walk the stack.
409 class ProfilerDartStackWalker : public ProfilerStackWalker { 467 class ProfilerDartStackWalker : public ProfilerStackWalker {
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 : ProfilerStackWalker(isolate, sample, sample_buffer), 632 : ProfilerStackWalker(isolate, sample, sample_buffer),
575 stack_upper_(stack_upper), 633 stack_upper_(stack_upper),
576 original_pc_(pc), 634 original_pc_(pc),
577 original_fp_(fp), 635 original_fp_(fp),
578 original_sp_(sp), 636 original_sp_(sp),
579 lower_bound_(stack_lower) { 637 lower_bound_(stack_lower) {
580 } 638 }
581 639
582 void walk() { 640 void walk() {
583 const uword kMaxStep = VirtualMemory::PageSize(); 641 const uword kMaxStep = VirtualMemory::PageSize();
584
585 Append(original_pc_); 642 Append(original_pc_);
586 643
587 uword* pc = reinterpret_cast<uword*>(original_pc_); 644 uword* pc = reinterpret_cast<uword*>(original_pc_);
588 uword* fp = reinterpret_cast<uword*>(original_fp_); 645 uword* fp = reinterpret_cast<uword*>(original_fp_);
589 uword* previous_fp = fp; 646 uword* previous_fp = fp;
590 647
591 uword gap = original_fp_ - original_sp_; 648 uword gap = original_fp_ - original_sp_;
592 if (gap >= kMaxStep) { 649 if (gap >= kMaxStep) {
593 // Gap between frame pointer and stack pointer is 650 // Gap between frame pointer and stack pointer is
594 // too large. 651 // too large.
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
874 static uintptr_t GetProgramCounter() { 931 static uintptr_t GetProgramCounter() {
875 return reinterpret_cast<uintptr_t>(_ReturnAddress()); 932 return reinterpret_cast<uintptr_t>(_ReturnAddress());
876 } 933 }
877 #else 934 #else
878 static uintptr_t __attribute__((noinline)) GetProgramCounter() { 935 static uintptr_t __attribute__((noinline)) GetProgramCounter() {
879 return reinterpret_cast<uintptr_t>( 936 return reinterpret_cast<uintptr_t>(
880 __builtin_extract_return_addr(__builtin_return_address(0))); 937 __builtin_extract_return_addr(__builtin_return_address(0)));
881 } 938 }
882 #endif 939 #endif
883 940
941
942 void Profiler::DumpStackTrace(bool native_stack_trace) {
943 Thread* thread = Thread::Current();
944 ASSERT(thread != NULL);
945 OSThread* os_thread = thread->os_thread();
946 ASSERT(os_thread != NULL);
947 Isolate* isolate = thread->isolate();
948 if (!CheckIsolate(isolate)) {
949 return;
950 }
951
952 const bool exited_dart_code = thread->HasExitedDartCode();
953
954 OS::Print("Dumping %s stack trace for thread %" Px "\n",
955 native_stack_trace ? "native" : "dart-only",
956 static_cast<uintptr_t>(os_thread->trace_id()));
957
958 uintptr_t sp = Thread::GetCurrentStackPointer();
959 uintptr_t fp = 0;
960 uintptr_t pc = GetProgramCounter();
961
962 COPY_FP_REGISTER(fp);
963
964 uword stack_lower = 0;
965 uword stack_upper = 0;
966
967 if (!InitialRegisterCheck(pc, fp, sp)) {
968 OS::Print(
969 "Stack dump aborted because InitialRegisterCheck.\n");
970 return;
971 }
972
973 if (!GetAndValidateIsolateStackBounds(thread,
974 fp,
975 sp,
976 &stack_lower,
977 &stack_upper)) {
978 OS::Print(
979 "Stack dump aborted because GetAndValidateIsolateStackBounds.\n");
980 return;
981 }
982
983 if (native_stack_trace) {
984 ProfilerNativeStackWalker native_stack_walker(isolate,
985 NULL,
986 NULL,
987 stack_lower,
988 stack_upper,
989 pc,
990 fp,
991 sp);
992 native_stack_walker.walk();
993 } else if (exited_dart_code) {
994 ProfilerDartExitStackWalker dart_exit_stack_walker(thread,
995 isolate,
996 NULL,
997 NULL);
998 dart_exit_stack_walker.walk();
999 } else {
1000 ProfilerDartStackWalker dart_stack_walker(isolate,
1001 NULL,
1002 NULL,
1003 stack_lower,
1004 stack_upper,
1005 pc,
1006 fp,
1007 sp);
1008 }
1009 }
1010
1011
884 void Profiler::SampleAllocation(Thread* thread, intptr_t cid) { 1012 void Profiler::SampleAllocation(Thread* thread, intptr_t cid) {
885 ASSERT(thread != NULL); 1013 ASSERT(thread != NULL);
886 OSThread* os_thread = thread->os_thread(); 1014 OSThread* os_thread = thread->os_thread();
887 ASSERT(os_thread != NULL); 1015 ASSERT(os_thread != NULL);
888 Isolate* isolate = thread->isolate(); 1016 Isolate* isolate = thread->isolate();
889 if (!CheckIsolate(isolate)) { 1017 if (!CheckIsolate(isolate)) {
890 return; 1018 return;
891 } 1019 }
892 1020
893 const bool exited_dart_code = thread->HasExitedDartCode(); 1021 const bool exited_dart_code = thread->HasExitedDartCode();
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after
1435 1563
1436 1564
1437 ProcessedSampleBuffer::ProcessedSampleBuffer() 1565 ProcessedSampleBuffer::ProcessedSampleBuffer()
1438 : code_lookup_table_(new CodeLookupTable(Thread::Current())) { 1566 : code_lookup_table_(new CodeLookupTable(Thread::Current())) {
1439 ASSERT(code_lookup_table_ != NULL); 1567 ASSERT(code_lookup_table_ != NULL);
1440 } 1568 }
1441 1569
1442 #endif // !PRODUCT 1570 #endif // !PRODUCT
1443 1571
1444 } // namespace dart 1572 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/profiler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698