13614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko//===-- sanitizer_stoptheworld.h --------------------------------*- C++ -*-===// 23614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// 33614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// The LLVM Compiler Infrastructure 43614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// 53614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// This file is distributed under the University of Illinois Open Source 63614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// License. See LICENSE.TXT for details. 73614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// 83614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko//===----------------------------------------------------------------------===// 93614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// 103614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// Defines the StopTheWorld function which suspends the execution of the current 113614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// process and runs the user-supplied callback in the same address space. 123614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// 133614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko//===----------------------------------------------------------------------===// 143614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#ifndef SANITIZER_STOPTHEWORLD_H 153614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#define SANITIZER_STOPTHEWORLD_H 163614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 173614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#include "sanitizer_internal_defs.h" 183614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#include "sanitizer_common.h" 193614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 203614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenkonamespace __sanitizer { 213614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenkotypedef int SuspendedThreadID; 223614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 2353c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko// Holds the list of suspended threads and provides an interface to dump their 2453c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko// register contexts. 253614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenkoclass SuspendedThreadsList { 263614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko public: 273614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko SuspendedThreadsList() 283614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko : thread_ids_(1024) {} 2953c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko SuspendedThreadID GetThreadID(uptr index) const { 303614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko CHECK_LT(index, thread_ids_.size()); 313614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko return thread_ids_[index]; 323614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko } 3353c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko int GetRegistersAndSP(uptr index, uptr *buffer, uptr *sp) const; 3453c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko // The buffer in GetRegistersAndSP should be at least this big. 3553c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko static uptr RegisterCount(); 3653c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko uptr thread_count() const { return thread_ids_.size(); } 3753c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko bool Contains(SuspendedThreadID thread_id) const { 383614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko for (uptr i = 0; i < thread_ids_.size(); i++) { 393614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko if (thread_ids_[i] == thread_id) 403614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko return true; 413614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko } 423614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko return false; 433614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko } 443614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko void Append(SuspendedThreadID thread_id) { 453614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko thread_ids_.push_back(thread_id); 463614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko } 473614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 483614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko private: 49a64d4359902f1f64992aedfe10d8882ae7c66f40Alexey Samsonov InternalMmapVector<SuspendedThreadID> thread_ids_; 503614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 513614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko // Prohibit copy and assign. 523614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko SuspendedThreadsList(const SuspendedThreadsList&); 533614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko void operator=(const SuspendedThreadsList&); 543614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko}; 553614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 563614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenkotypedef void (*StopTheWorldCallback)( 573614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko const SuspendedThreadsList &suspended_threads_list, 583614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko void *argument); 593614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 603614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// Suspend all threads in the current process and run the callback on the list 613614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// of suspended threads. This function will resume the threads before returning. 623614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// The callback should not call any libc functions. 636d036065e2ba85d9ad2a141596693b026f7ebbccAlexey Samsonov// This function should NOT be called from multiple threads simultaneously. 643614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenkovoid StopTheWorld(StopTheWorldCallback callback, void *argument); 653614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 663614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko} // namespace __sanitizer 673614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko 683614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#endif // SANITIZER_STOPTHEWORLD_H 69