MachThreadList.cpp revision 7cbdcfb0cefcfd877b507ff2d83e51a1bde3fcc7
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===-- MachThreadList.cpp --------------------------------------*- C++ -*-===// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Created by Greg Clayton on 6/19/07. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "MachThreadList.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/sysctl.h> 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "DNBLog.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "DNBThreadResumeActions.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "MachProcess.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MachThreadList::MachThreadList() : 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_threads(), 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_threads_mutex(PTHREAD_MUTEX_RECURSIVE) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MachThreadList::~MachThreadList() 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)nub_state_t 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MachThreadList::GetState(thread_t tid) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MachThreadSP thread_sp (GetThreadByID (tid)); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (thread_sp) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return thread_sp->GetState(); 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return eStateInvalid; 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char * 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MachThreadList::GetName (thread_t tid) 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MachThreadSP thread_sp (GetThreadByID (tid)); 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (thread_sp) 46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return thread_sp->GetName(); 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return NULL; 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)nub_thread_t 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MachThreadList::SetCurrentThread(thread_t tid) 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MachThreadSP thread_sp (GetThreadByID (tid)); 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (thread_sp) 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) m_current_thread = thread_sp; 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return tid; 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return INVALID_NUB_THREAD; 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)MachThreadList::GetThreadStoppedReason(nub_thread_t tid, struct DNBThreadStopInfo *stop_info) const 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){ 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MachThreadSP thread_sp (GetThreadByID (tid)); 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (thread_sp) 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return thread_sp->GetStopException().GetStopInfo(stop_info); 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)MachThreadList::GetIdentifierInfo (nub_thread_t tid, thread_identifier_info_data_t *ident_info) 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT; 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return ::thread_info (tid, THREAD_IDENTIFIER_INFO, (thread_info_t)ident_info, &count) == KERN_SUCCESS; 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MachThreadList::DumpThreadStoppedReason (nub_thread_t tid) const 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){ 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MachThreadSP thread_sp (GetThreadByID (tid)); 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (thread_sp) 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) thread_sp->GetStopException().DumpStopReason(); 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char * 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MachThreadList::GetThreadInfo (nub_thread_t tid) const 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){ 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MachThreadSP thread_sp (GetThreadByID (tid)); 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (thread_sp) 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return thread_sp->GetBasicInfoAsString(); 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return NULL; 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MachThreadSP 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)MachThreadList::GetThreadByID (nub_thread_t tid) const 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex); 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MachThreadSP thread_sp; 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const size_t num_threads = m_threads.size(); 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t idx = 0; idx < num_threads; ++idx) 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (m_threads[idx]->ThreadID() == tid) 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) thread_sp = m_threads[idx]; 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return thread_sp; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MachThreadList::GetRegisterValue ( nub_thread_t tid, uint32_t reg_set_idx, uint32_t reg_idx, DNBRegisterValue *reg_value ) const 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MachThreadSP thread_sp (GetThreadByID (tid)); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (thread_sp) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return thread_sp->GetRegisterValue(reg_set_idx, reg_idx, reg_value); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool 124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)MachThreadList::SetRegisterValue ( nub_thread_t tid, uint32_t reg_set_idx, uint32_t reg_idx, const DNBRegisterValue *reg_value ) const 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MachThreadSP thread_sp (GetThreadByID (tid)); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (thread_sp) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return thread_sp->SetRegisterValue(reg_set_idx, reg_idx, reg_value); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return false; 1317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)nub_size_t 1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)MachThreadList::GetRegisterContext (nub_thread_t tid, void *buf, size_t buf_len) 1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles){ 1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) MachThreadSP thread_sp (GetThreadByID (tid)); 1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (thread_sp) 1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return thread_sp->GetRegisterContext (buf, buf_len); 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)nub_size_t 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)MachThreadList::SetRegisterContext (nub_thread_t tid, const void *buf, size_t buf_len) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MachThreadSP thread_sp (GetThreadByID (tid)); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (thread_sp) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return thread_sp->SetRegisterContext (buf, buf_len); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)nub_size_t 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MachThreadList::NumThreads () const 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return m_threads.size(); 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)nub_thread_t 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MachThreadList::ThreadIDAtIndex (nub_size_t idx) const 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex); 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (idx < m_threads.size()) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return m_threads[idx]->ThreadID(); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return INVALID_NUB_THREAD; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)nub_thread_t 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MachThreadList::CurrentThreadID ( ) 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MachThreadSP thread_sp; 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CurrentThread(thread_sp); 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (thread_sp.get()) 173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return thread_sp->ThreadID(); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return INVALID_NUB_THREAD; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MachThreadList::NotifyException(MachException::Data& exc) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MachThreadSP thread_sp (GetThreadByID (exc.thread_port)); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (thread_sp) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_sp->NotifyException(exc); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MachThreadList::Clear() 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_threads.clear(); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32_t 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MachThreadList::UpdateThreadList(MachProcess *process, bool update, MachThreadList::collection *new_threads) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // locker will keep a mutex locked until it goes out of scope 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DNBLogThreadedIf (LOG_THREAD, "MachThreadList::UpdateThreadList (pid = %4.4x, update = %u) process stop count = %u", process->ProcessID(), update, process->StopCount()); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined (__i386__) || defined (__x86_64__) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (process->StopCount() == 0) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process->ProcessID() }; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kinfo_proc processInfo; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t bufsize = sizeof(processInfo); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_64_bit = false; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sysctl(mib, (unsigned)(sizeof(mib)/sizeof(int)), &processInfo, &bufsize, NULL, 0) == 0 && bufsize > 0) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (processInfo.kp_proc.p_flag & P_LP64) 213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) is_64_bit = true; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_64_bit) 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DNBArchProtocol::SetArchitecture(CPU_TYPE_X86_64); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DNBArchProtocol::SetArchitecture(CPU_TYPE_I386); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (m_threads.empty() || update) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_array_t thread_list = NULL; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mach_msg_type_number_t thread_list_count = 0; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) task_t task = process->Task().TaskPort(); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DNBError err(::task_threads (task, &thread_list, &thread_list_count), DNBError::MachKernel); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail()) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err.LogThreaded("::task_threads ( task = 0x%4.4x, thread_list => %p, thread_list_count => %u )", task, thread_list, thread_list_count); 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (err.Error() == KERN_SUCCESS && thread_list_count > 0) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MachThreadList::collection currThreads; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t idx; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Iterator through the current thread list and see which threads 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we already have in our list (keep them), which ones we don't 23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // (add them), and which ones are not around anymore (remove them). 23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (idx = 0; idx < thread_list_count; ++idx) 24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const thread_t tid = thread_list[idx]; 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MachThreadSP thread_sp (GetThreadByID (tid)); 24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (thread_sp) 24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) { 24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Keep the existing thread class 24790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) currThreads.push_back(thread_sp); 24890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 24990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) else 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We don't have this thread, lets add it. 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_sp.reset(new MachThread(process, tid)); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Add the new thread regardless of its is user ready state... 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure the thread is ready to be displayed and shown to users 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // before we add this thread to our list... 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (thread_sp->IsUserReady()) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (new_threads) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_threads->push_back(thread_sp); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) currThreads.push_back(thread_sp); 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) m_threads.swap(currThreads); 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) m_current_thread.reset(); 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Free the vm memory given to us by ::task_threads() 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) vm_size_t thread_list_size = (vm_size_t) (thread_list_count * sizeof (thread_t)); 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ::vm_deallocate (::mach_task_self(), 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (vm_address_t)thread_list, 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_list_size); 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return m_threads.size(); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MachThreadList::CurrentThread (MachThreadSP& thread_sp) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // locker will keep a mutex locked until it goes out of scope 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (m_current_thread.get() == NULL) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Figure out which thread is going to be our current thread. 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is currently done by finding the first thread in the list 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // that has a valid exception. 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32_t num_threads = m_threads.size(); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t idx = 0; idx < num_threads; ++idx) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (m_threads[idx]->GetStopException().IsValid()) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_current_thread = m_threads[idx]; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 300d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 301d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch thread_sp = m_current_thread; 302d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MachThreadList::Dump() const 30623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles){ 30723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex); 30823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const uint32_t num_threads = m_threads.size(); 30923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) for (uint32_t idx = 0; idx < num_threads; ++idx) 31023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) { 31123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) m_threads[idx]->Dump(idx); 31223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 313d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 314d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MachThreadList::ProcessWillResume(MachProcess *process, const DNBThreadResumeActions &thread_actions) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update our thread list, because sometimes libdispatch or the kernel 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will spawn threads while a task is suspended. 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MachThreadList::collection new_threads; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First figure out if we were planning on running only one thread, and if so force that thread to resume. 326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool run_one_thread; 327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) nub_thread_t solo_thread = INVALID_NUB_THREAD; 328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (thread_actions.GetSize() > 0 329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) && thread_actions.NumActionsWithState(eStateStepping) + thread_actions.NumActionsWithState (eStateRunning) == 1) 330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) { 331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) run_one_thread = true; 332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const DNBThreadResumeAction *action_ptr = thread_actions.GetFirst(); 333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) size_t num_actions = thread_actions.GetSize(); 334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (size_t i = 0; i < num_actions; i++, action_ptr++) 335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) { 336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (action_ptr->state == eStateStepping || action_ptr->state == eStateRunning) 337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) { 338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) solo_thread = action_ptr->tid; 339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) run_one_thread = false; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateThreadList(process, true, &new_threads); 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DNBThreadResumeAction resume_new_threads = { -1U, eStateRunning, 0, INVALID_NUB_ADDRESS }; 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we are planning to run only one thread, any new threads should be suspended. 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (run_one_thread) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resume_new_threads.state = eStateSuspended; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const uint32_t num_new_threads = new_threads.size(); 35423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const uint32_t num_threads = m_threads.size(); 35523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) for (uint32_t idx = 0; idx < num_threads; ++idx) 35623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) { 35723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) MachThread *thread = m_threads[idx].get(); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool handled = false; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t new_idx = 0; new_idx < num_new_threads; ++new_idx) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (thread == new_threads[new_idx].get()) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread->ThreadWillResume(&resume_new_threads); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handled = true; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!handled) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DNBThreadResumeAction *thread_action = thread_actions.GetActionForThread (thread->ThreadID(), true); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There must always be a thread action for every thread. 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert (thread_action); 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool others_stopped = false; 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (solo_thread == thread->ThreadID()) 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) others_stopped = true; 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread->ThreadWillResume (thread_action, others_stopped); 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (new_threads.size()) 382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (uint32_t idx = 0; idx < num_new_threads; ++idx) 384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DNBLogThreadedIf (LOG_THREAD, "MachThreadList::ProcessWillResume (pid = %4.4x) stop-id=%u, resuming newly discovered thread: 0x%4.4x, thread-is-user-ready=%i)", 3863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) process->ProcessID(), 3873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) process->StopCount(), 3883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) new_threads[idx]->ThreadID(), 389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new_threads[idx]->IsUserReady()); 390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)uint32_t 395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)MachThreadList::ProcessDidStop(MachProcess *process) 396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex); 398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Update our thread list 399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const uint32_t num_threads = UpdateThreadList(process, true); 400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (uint32_t idx = 0; idx < num_threads; ++idx) 4013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { 4023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) m_threads[idx]->ThreadDidStop(); 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return num_threads; 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//---------------------------------------------------------------------- 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Check each thread in our thread list to see if we should notify our 409a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// client of the current halt in execution. 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Breakpoints can have callback functions associated with them than 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// can return true to stop, or false to continue executing the inferior. 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// RETURNS 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// true if we should stop and notify our clients 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// false if we should resume our child process and skip notification 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//---------------------------------------------------------------------- 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MachThreadList::ShouldStop(bool &step_more) 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t should_stop = false; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32_t num_threads = m_threads.size(); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t idx = 0; !should_stop && idx < num_threads; ++idx) 42523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) { 42623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) should_stop = m_threads[idx]->ShouldStop(step_more); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return should_stop; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MachThreadList::NotifyBreakpointChanged (const DNBBreakpoint *bp) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32_t num_threads = m_threads.size(); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t idx = 0; idx < num_threads; ++idx) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m_threads[idx]->NotifyBreakpointChanged(bp); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32_t 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MachThreadList::EnableHardwareBreakpoint (const DNBBreakpoint* bp) const 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bp != NULL) 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 449a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) MachThreadSP thread_sp (GetThreadByID (bp->ThreadID())); 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (thread_sp) 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return thread_sp->EnableHardwareBreakpoint(bp); 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return INVALID_NUB_HW_INDEX; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MachThreadList::DisableHardwareBreakpoint (const DNBBreakpoint* bp) const 458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (bp != NULL) 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MachThreadSP thread_sp (GetThreadByID (bp->ThreadID())); 462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (thread_sp) 463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return thread_sp->DisableHardwareBreakpoint(bp); 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// DNBWatchpointSet() -> MachProcess::CreateWatchpoint() -> MachProcess::EnableWatchpoint() 469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// -> MachThreadList::EnableHardwareWatchpoint(). 470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)uint32_t 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MachThreadList::EnableHardwareWatchpoint (const DNBBreakpoint* wp) const 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (wp != NULL) 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t hw_index; 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32_t num_threads = m_threads.size(); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t idx = 0; idx < num_threads; ++idx) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((hw_index = m_threads[idx]->EnableHardwareWatchpoint(wp)) == INVALID_NUB_HW_INDEX) 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return INVALID_NUB_HW_INDEX; 482a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use an arbitrary thread to signal the completion of our transaction. 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_threads) 485a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) m_threads[0]->HardwareWatchpointStateChanged(); 486a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return hw_index; 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return INVALID_NUB_HW_INDEX; 489eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool 492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochMachThreadList::DisableHardwareWatchpoint (const DNBBreakpoint* wp) const 493eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch{ 494eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (wp != NULL) 495eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { 496eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex); 497eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const uint32_t num_threads = m_threads.size(); 498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (uint32_t idx = 0; idx < num_threads; ++idx) 499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { 500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!m_threads[idx]->DisableHardwareWatchpoint(wp)) 501eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 502c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch } 503c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // Use an arbitrary thread to signal the completion of our transaction. 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_threads) 505eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch m_threads[0]->HardwareWatchpointStateChanged(); 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)uint32_t 512a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)MachThreadList::NumSupportedHardwareWatchpoints () const 5133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){ 5143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex); 5153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const uint32_t num_threads = m_threads.size(); 5163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Use an arbitrary thread to retrieve the number of supported hardware watchpoints. 5173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (num_threads) 5183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return m_threads[0]->NumSupportedHardwareWatchpoints(); 5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 5213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)uint32_t 5233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)MachThreadList::GetThreadIndexForThreadStoppedWithSignal (const int signo) const 5243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){ 5253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex); 5263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) uint32_t should_stop = false; 5273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const uint32_t num_threads = m_threads.size(); 5283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (uint32_t idx = 0; !should_stop && idx < num_threads; ++idx) 5293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { 5303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (m_threads[idx]->GetStopException().SoftSignal () == signo) 5311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return idx; 5323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return UINT32_MAX; 5343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)