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

Side by Side Diff: base/debug/activity_tracker.cc

Issue 2483473002: Include calling address in tracked activities. (Closed)
Patch Set: force inlining of methods that call GetProgramCounter() Created 4 years, 1 month 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 | « base/debug/activity_tracker.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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/debug/activity_tracker.h" 5 #include "base/debug/activity_tracker.h"
6 6
7 #include "base/debug/stack_trace.h" 7 #include "base/debug/stack_trace.h"
8 #include "base/files/file.h" 8 #include "base/files/file.h"
9 #include "base/files/file_path.h" 9 #include "base/files/file_path.h"
10 #include "base/files/memory_mapped_file.h" 10 #include "base/files/memory_mapped_file.h"
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 144
145 // Add this reference to our "free" cache if there is space. If not, the type 145 // Add this reference to our "free" cache if there is space. If not, the type
146 // has still been changed to indicate that it is free so this (or another) 146 // has still been changed to indicate that it is free so this (or another)
147 // thread can find it, albeit more slowly, using the iteration method above. 147 // thread can find it, albeit more slowly, using the iteration method above.
148 if (cache_used_ < cache_size_) 148 if (cache_used_ < cache_size_)
149 cache_values_[cache_used_++] = ref; 149 cache_values_[cache_used_++] = ref;
150 } 150 }
151 151
152 // static 152 // static
153 void Activity::FillFrom(Activity* activity, 153 void Activity::FillFrom(Activity* activity,
154 const void* program_counter,
154 const void* origin, 155 const void* origin,
155 Type type, 156 Type type,
156 const ActivityData& data) { 157 const ActivityData& data) {
157 activity->time_internal = base::TimeTicks::Now().ToInternalValue(); 158 activity->time_internal = base::TimeTicks::Now().ToInternalValue();
159 activity->calling_address = reinterpret_cast<uintptr_t>(program_counter);
158 activity->origin_address = reinterpret_cast<uintptr_t>(origin); 160 activity->origin_address = reinterpret_cast<uintptr_t>(origin);
159 activity->activity_type = type; 161 activity->activity_type = type;
160 activity->data = data; 162 activity->data = data;
161 163
162 #if defined(SYZYASAN) 164 #if defined(SYZYASAN)
163 // Create a stacktrace from the current location and get the addresses. 165 // Create a stacktrace from the current location and get the addresses.
164 StackTrace stack_trace; 166 StackTrace stack_trace;
165 size_t stack_depth; 167 size_t stack_depth;
166 const void* const* stack_addrs = stack_trace.Addresses(&stack_depth); 168 const void* const* stack_addrs = stack_trace.Addresses(&stack_depth);
167 // Copy the stack addresses, ignoring the first one (here). 169 // Copy the stack addresses, ignoring the first one (here).
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 DCHECK(IsValid()); 304 DCHECK(IsValid());
303 } else { 305 } else {
304 // This is a file with existing data. Perform basic consistency checks. 306 // This is a file with existing data. Perform basic consistency checks.
305 valid_ = true; 307 valid_ = true;
306 valid_ = IsValid(); 308 valid_ = IsValid();
307 } 309 }
308 } 310 }
309 311
310 ThreadActivityTracker::~ThreadActivityTracker() {} 312 ThreadActivityTracker::~ThreadActivityTracker() {}
311 313
312 void ThreadActivityTracker::PushActivity(const void* origin, 314 void ThreadActivityTracker::PushActivity(const void* program_counter,
315 const void* origin,
313 Activity::Type type, 316 Activity::Type type,
314 const ActivityData& data) { 317 const ActivityData& data) {
315 // A thread-checker creates a lock to check the thread-id which means 318 // A thread-checker creates a lock to check the thread-id which means
316 // re-entry into this code if lock acquisitions are being tracked. 319 // re-entry into this code if lock acquisitions are being tracked.
317 DCHECK(type == Activity::ACT_LOCK_ACQUIRE || 320 DCHECK(type == Activity::ACT_LOCK_ACQUIRE ||
318 thread_checker_.CalledOnValidThread()); 321 thread_checker_.CalledOnValidThread());
319 322
320 // Get the current depth of the stack. No access to other memory guarded 323 // Get the current depth of the stack. No access to other memory guarded
321 // by this variable is done here so a "relaxed" load is acceptable. 324 // by this variable is done here so a "relaxed" load is acceptable.
322 uint32_t depth = header_->current_depth.load(std::memory_order_relaxed); 325 uint32_t depth = header_->current_depth.load(std::memory_order_relaxed);
323 326
324 // Handle the case where the stack depth has exceeded the storage capacity. 327 // Handle the case where the stack depth has exceeded the storage capacity.
325 // Extra entries will be lost leaving only the base of the stack. 328 // Extra entries will be lost leaving only the base of the stack.
326 if (depth >= stack_slots_) { 329 if (depth >= stack_slots_) {
327 // Since no other threads modify the data, no compare/exchange is needed. 330 // Since no other threads modify the data, no compare/exchange is needed.
328 // Since no other memory is being modified, a "relaxed" store is acceptable. 331 // Since no other memory is being modified, a "relaxed" store is acceptable.
329 header_->current_depth.store(depth + 1, std::memory_order_relaxed); 332 header_->current_depth.store(depth + 1, std::memory_order_relaxed);
330 return; 333 return;
331 } 334 }
332 335
333 // Get a pointer to the next activity and load it. No atomicity is required 336 // Get a pointer to the next activity and load it. No atomicity is required
334 // here because the memory is known only to this thread. It will be made 337 // here because the memory is known only to this thread. It will be made
335 // known to other threads once the depth is incremented. 338 // known to other threads once the depth is incremented.
336 Activity::FillFrom(&stack_[depth], origin, type, data); 339 Activity::FillFrom(&stack_[depth], program_counter, origin, type, data);
337 340
338 // Save the incremented depth. Because this guards |activity| memory filled 341 // Save the incremented depth. Because this guards |activity| memory filled
339 // above that may be read by another thread once the recorded depth changes, 342 // above that may be read by another thread once the recorded depth changes,
340 // a "release" store is required. 343 // a "release" store is required.
341 header_->current_depth.store(depth + 1, std::memory_order_release); 344 header_->current_depth.store(depth + 1, std::memory_order_release);
342 } 345 }
343 346
344 void ThreadActivityTracker::ChangeActivity(Activity::Type type, 347 void ThreadActivityTracker::ChangeActivity(Activity::Type type,
345 const ActivityData& data) { 348 const ActivityData& data) {
346 DCHECK(thread_checker_.CalledOnValidThread()); 349 DCHECK(thread_checker_.CalledOnValidThread());
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 // Release this memory for re-use at a later time. 674 // Release this memory for re-use at a later time.
672 base::AutoLock autolock(thread_tracker_allocator_lock_); 675 base::AutoLock autolock(thread_tracker_allocator_lock_);
673 thread_tracker_allocator_.ReleaseObjectReference(mem_reference); 676 thread_tracker_allocator_.ReleaseObjectReference(mem_reference);
674 } 677 }
675 678
676 // static 679 // static
677 void GlobalActivityTracker::OnTLSDestroy(void* value) { 680 void GlobalActivityTracker::OnTLSDestroy(void* value) {
678 delete reinterpret_cast<ManagedActivityTracker*>(value); 681 delete reinterpret_cast<ManagedActivityTracker*>(value);
679 } 682 }
680 683
681 ScopedActivity::ScopedActivity(const tracked_objects::Location& location, 684 ScopedActivity::ScopedActivity(const void* program_counter,
682 uint8_t action, 685 uint8_t action,
683 uint32_t id, 686 uint32_t id,
684 int32_t info) 687 int32_t info)
685 : GlobalActivityTracker::ScopedThreadActivity( 688 : GlobalActivityTracker::ScopedThreadActivity(
686 location.program_counter(), 689 program_counter,
690 nullptr,
687 static_cast<Activity::Type>(Activity::ACT_GENERIC | action), 691 static_cast<Activity::Type>(Activity::ACT_GENERIC | action),
688 ActivityData::ForGeneric(id, info), 692 ActivityData::ForGeneric(id, info),
689 /*lock_allowed=*/true), 693 /*lock_allowed=*/true),
690 id_(id) { 694 id_(id) {
691 // The action must not affect the category bits of the activity type. 695 // The action must not affect the category bits of the activity type.
692 DCHECK_EQ(0, action & Activity::ACT_CATEGORY_MASK); 696 DCHECK_EQ(0, action & Activity::ACT_CATEGORY_MASK);
693 } 697 }
694 698
695 void ScopedActivity::ChangeAction(uint8_t action) { 699 void ScopedActivity::ChangeAction(uint8_t action) {
696 DCHECK_EQ(0, action & Activity::ACT_CATEGORY_MASK); 700 DCHECK_EQ(0, action & Activity::ACT_CATEGORY_MASK);
697 ChangeTypeAndData(static_cast<Activity::Type>(Activity::ACT_GENERIC | action), 701 ChangeTypeAndData(static_cast<Activity::Type>(Activity::ACT_GENERIC | action),
698 kNullActivityData); 702 kNullActivityData);
699 } 703 }
700 704
701 void ScopedActivity::ChangeInfo(int32_t info) { 705 void ScopedActivity::ChangeInfo(int32_t info) {
702 ChangeTypeAndData(Activity::ACT_NULL, ActivityData::ForGeneric(id_, info)); 706 ChangeTypeAndData(Activity::ACT_NULL, ActivityData::ForGeneric(id_, info));
703 } 707 }
704 708
705 void ScopedActivity::ChangeActionAndInfo(uint8_t action, int32_t info) { 709 void ScopedActivity::ChangeActionAndInfo(uint8_t action, int32_t info) {
706 DCHECK_EQ(0, action & Activity::ACT_CATEGORY_MASK); 710 DCHECK_EQ(0, action & Activity::ACT_CATEGORY_MASK);
707 ChangeTypeAndData(static_cast<Activity::Type>(Activity::ACT_GENERIC | action), 711 ChangeTypeAndData(static_cast<Activity::Type>(Activity::ACT_GENERIC | action),
708 ActivityData::ForGeneric(id_, info)); 712 ActivityData::ForGeneric(id_, info));
709 } 713 }
710 714
711 ScopedTaskRunActivity::ScopedTaskRunActivity(const base::PendingTask& task) 715 ScopedTaskRunActivity::ScopedTaskRunActivity(
716 const void* program_counter,
717 const base::PendingTask& task)
712 : GlobalActivityTracker::ScopedThreadActivity( 718 : GlobalActivityTracker::ScopedThreadActivity(
719 program_counter,
713 task.posted_from.program_counter(), 720 task.posted_from.program_counter(),
714 Activity::ACT_TASK_RUN, 721 Activity::ACT_TASK_RUN,
715 ActivityData::ForTask(task.sequence_num), 722 ActivityData::ForTask(task.sequence_num),
716 /*lock_allowed=*/true) {} 723 /*lock_allowed=*/true) {}
717 724
718 ScopedLockAcquireActivity::ScopedLockAcquireActivity( 725 ScopedLockAcquireActivity::ScopedLockAcquireActivity(
726 const void* program_counter,
719 const base::internal::LockImpl* lock) 727 const base::internal::LockImpl* lock)
720 : GlobalActivityTracker::ScopedThreadActivity( 728 : GlobalActivityTracker::ScopedThreadActivity(
729 program_counter,
721 nullptr, 730 nullptr,
722 Activity::ACT_LOCK_ACQUIRE, 731 Activity::ACT_LOCK_ACQUIRE,
723 ActivityData::ForLock(lock), 732 ActivityData::ForLock(lock),
724 /*lock_allowed=*/false) {} 733 /*lock_allowed=*/false) {}
725 734
726 ScopedEventWaitActivity::ScopedEventWaitActivity( 735 ScopedEventWaitActivity::ScopedEventWaitActivity(
736 const void* program_counter,
727 const base::WaitableEvent* event) 737 const base::WaitableEvent* event)
728 : GlobalActivityTracker::ScopedThreadActivity( 738 : GlobalActivityTracker::ScopedThreadActivity(
739 program_counter,
729 nullptr, 740 nullptr,
730 Activity::ACT_EVENT_WAIT, 741 Activity::ACT_EVENT_WAIT,
731 ActivityData::ForEvent(event), 742 ActivityData::ForEvent(event),
732 /*lock_allowed=*/true) {} 743 /*lock_allowed=*/true) {}
733 744
734 ScopedThreadJoinActivity::ScopedThreadJoinActivity( 745 ScopedThreadJoinActivity::ScopedThreadJoinActivity(
746 const void* program_counter,
735 const base::PlatformThreadHandle* thread) 747 const base::PlatformThreadHandle* thread)
736 : GlobalActivityTracker::ScopedThreadActivity( 748 : GlobalActivityTracker::ScopedThreadActivity(
749 program_counter,
737 nullptr, 750 nullptr,
738 Activity::ACT_THREAD_JOIN, 751 Activity::ACT_THREAD_JOIN,
739 ActivityData::ForThread(*thread), 752 ActivityData::ForThread(*thread),
740 /*lock_allowed=*/true) {} 753 /*lock_allowed=*/true) {}
741 754
742 #if !defined(OS_NACL) && !defined(OS_IOS) 755 #if !defined(OS_NACL) && !defined(OS_IOS)
743 ScopedProcessWaitActivity::ScopedProcessWaitActivity( 756 ScopedProcessWaitActivity::ScopedProcessWaitActivity(
757 const void* program_counter,
744 const base::Process* process) 758 const base::Process* process)
745 : GlobalActivityTracker::ScopedThreadActivity( 759 : GlobalActivityTracker::ScopedThreadActivity(
760 program_counter,
746 nullptr, 761 nullptr,
747 Activity::ACT_PROCESS_WAIT, 762 Activity::ACT_PROCESS_WAIT,
748 ActivityData::ForProcess(process->Pid()), 763 ActivityData::ForProcess(process->Pid()),
749 /*lock_allowed=*/true) {} 764 /*lock_allowed=*/true) {}
750 #endif 765 #endif
751 766
752 } // namespace debug 767 } // namespace debug
753 } // namespace base 768 } // namespace base
OLDNEW
« no previous file with comments | « base/debug/activity_tracker.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698