ProcessFreeBSD.cpp revision 276479
1254721Semaste//===-- ProcessFreeBSD.cpp ----------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste// C Includes 11254721Semaste#include <errno.h> 12254721Semaste 13254721Semaste// C++ Includes 14254721Semaste// Other libraries and framework includes 15254721Semaste#include "lldb/Core/PluginManager.h" 16254721Semaste#include "lldb/Core/State.h" 17254721Semaste#include "lldb/Host/Host.h" 18254721Semaste#include "lldb/Symbol/ObjectFile.h" 19254721Semaste#include "lldb/Target/DynamicLoader.h" 20254721Semaste#include "lldb/Target/Target.h" 21254721Semaste 22254721Semaste#include "ProcessFreeBSD.h" 23254721Semaste#include "ProcessPOSIXLog.h" 24254721Semaste#include "Plugins/Process/Utility/InferiorCallPOSIX.h" 25276479Sdim#include "Plugins/Process/Utility/FreeBSDSignals.h" 26254721Semaste#include "ProcessMonitor.h" 27258892Semaste#include "FreeBSDThread.h" 28254721Semaste 29254721Semasteusing namespace lldb; 30254721Semasteusing namespace lldb_private; 31254721Semaste 32276479Sdimnamespace 33276479Sdim{ 34276479Sdim UnixSignalsSP& 35276479Sdim GetFreeBSDSignals () 36276479Sdim { 37276479Sdim static UnixSignalsSP s_freebsd_signals_sp (new FreeBSDSignals ()); 38276479Sdim return s_freebsd_signals_sp; 39276479Sdim } 40276479Sdim} 41276479Sdim 42254721Semaste//------------------------------------------------------------------------------ 43254721Semaste// Static functions. 44254721Semaste 45254721Semastelldb::ProcessSP 46254721SemasteProcessFreeBSD::CreateInstance(Target& target, 47254721Semaste Listener &listener, 48254721Semaste const FileSpec *crash_file_path) 49254721Semaste{ 50254721Semaste lldb::ProcessSP process_sp; 51254721Semaste if (crash_file_path == NULL) 52254721Semaste process_sp.reset(new ProcessFreeBSD (target, listener)); 53254721Semaste return process_sp; 54254721Semaste} 55254721Semaste 56254721Semastevoid 57254721SemasteProcessFreeBSD::Initialize() 58254721Semaste{ 59254721Semaste static bool g_initialized = false; 60254721Semaste 61254721Semaste if (!g_initialized) 62254721Semaste { 63254721Semaste PluginManager::RegisterPlugin(GetPluginNameStatic(), 64254721Semaste GetPluginDescriptionStatic(), 65254721Semaste CreateInstance); 66254721Semaste Log::Callbacks log_callbacks = { 67254721Semaste ProcessPOSIXLog::DisableLog, 68254721Semaste ProcessPOSIXLog::EnableLog, 69254721Semaste ProcessPOSIXLog::ListLogCategories 70254721Semaste }; 71254721Semaste 72254721Semaste Log::RegisterLogChannel (ProcessFreeBSD::GetPluginNameStatic(), log_callbacks); 73254721Semaste ProcessPOSIXLog::RegisterPluginName(GetPluginNameStatic()); 74254721Semaste g_initialized = true; 75254721Semaste } 76254721Semaste} 77254721Semaste 78254721Semastelldb_private::ConstString 79254721SemasteProcessFreeBSD::GetPluginNameStatic() 80254721Semaste{ 81254721Semaste static ConstString g_name("freebsd"); 82254721Semaste return g_name; 83254721Semaste} 84254721Semaste 85254721Semasteconst char * 86254721SemasteProcessFreeBSD::GetPluginDescriptionStatic() 87254721Semaste{ 88254721Semaste return "Process plugin for FreeBSD"; 89254721Semaste} 90254721Semaste 91254721Semaste//------------------------------------------------------------------------------ 92254721Semaste// ProcessInterface protocol. 93254721Semaste 94254721Semastelldb_private::ConstString 95254721SemasteProcessFreeBSD::GetPluginName() 96254721Semaste{ 97254721Semaste return GetPluginNameStatic(); 98254721Semaste} 99254721Semaste 100254721Semasteuint32_t 101254721SemasteProcessFreeBSD::GetPluginVersion() 102254721Semaste{ 103254721Semaste return 1; 104254721Semaste} 105254721Semaste 106254721Semastevoid 107254721SemasteProcessFreeBSD::GetPluginCommandHelp(const char *command, Stream *strm) 108254721Semaste{ 109254721Semaste} 110254721Semaste 111254721SemasteError 112254721SemasteProcessFreeBSD::ExecutePluginCommand(Args &command, Stream *strm) 113254721Semaste{ 114254721Semaste return Error(1, eErrorTypeGeneric); 115254721Semaste} 116254721Semaste 117254721SemasteLog * 118254721SemasteProcessFreeBSD::EnablePluginLogging(Stream *strm, Args &command) 119254721Semaste{ 120254721Semaste return NULL; 121254721Semaste} 122254721Semaste 123254721Semaste//------------------------------------------------------------------------------ 124254721Semaste// Constructors and destructors. 125254721Semaste 126254721SemasteProcessFreeBSD::ProcessFreeBSD(Target& target, Listener &listener) 127276479Sdim : ProcessPOSIX(target, listener, GetFreeBSDSignals ()), 128276479Sdim m_resume_signo(0) 129254721Semaste{ 130254721Semaste} 131254721Semaste 132254721Semastevoid 133254721SemasteProcessFreeBSD::Terminate() 134254721Semaste{ 135254721Semaste} 136254721Semaste 137258054SemasteError 138258054SemasteProcessFreeBSD::DoDetach(bool keep_stopped) 139258054Semaste{ 140258054Semaste Error error; 141258054Semaste if (keep_stopped) 142258054Semaste { 143258054Semaste error.SetErrorString("Detaching with keep_stopped true is not currently supported on FreeBSD."); 144258054Semaste return error; 145258054Semaste } 146258054Semaste 147258054Semaste error = m_monitor->Detach(GetID()); 148258054Semaste 149258054Semaste if (error.Success()) 150258054Semaste SetPrivateState(eStateDetached); 151258054Semaste 152258054Semaste return error; 153258054Semaste} 154258054Semaste 155258892SemasteError 156258892SemasteProcessFreeBSD::DoResume() 157258892Semaste{ 158258892Semaste Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); 159258892Semaste 160258892Semaste SetPrivateState(eStateRunning); 161258892Semaste 162258892Semaste Mutex::Locker lock(m_thread_list.GetMutex()); 163258892Semaste bool do_step = false; 164258892Semaste 165258892Semaste for (tid_collection::const_iterator t_pos = m_run_tids.begin(), t_end = m_run_tids.end(); t_pos != t_end; ++t_pos) 166258892Semaste { 167258892Semaste m_monitor->ThreadSuspend(*t_pos, false); 168258892Semaste } 169258892Semaste for (tid_collection::const_iterator t_pos = m_step_tids.begin(), t_end = m_step_tids.end(); t_pos != t_end; ++t_pos) 170258892Semaste { 171258892Semaste m_monitor->ThreadSuspend(*t_pos, false); 172258892Semaste do_step = true; 173258892Semaste } 174258892Semaste for (tid_collection::const_iterator t_pos = m_suspend_tids.begin(), t_end = m_suspend_tids.end(); t_pos != t_end; ++t_pos) 175258892Semaste { 176258892Semaste m_monitor->ThreadSuspend(*t_pos, true); 177258892Semaste // XXX Cannot PT_CONTINUE properly with suspended threads. 178258892Semaste do_step = true; 179258892Semaste } 180258892Semaste 181258892Semaste if (log) 182276479Sdim log->Printf("process %" PRIu64 " resuming (%s)", GetID(), do_step ? "step" : "continue"); 183258892Semaste if (do_step) 184276479Sdim m_monitor->SingleStep(GetID(), m_resume_signo); 185258892Semaste else 186276479Sdim m_monitor->Resume(GetID(), m_resume_signo); 187258892Semaste 188258892Semaste return Error(); 189258892Semaste} 190258892Semaste 191254721Semastebool 192254721SemasteProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) 193254721Semaste{ 194258892Semaste Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); 195258892Semaste if (log) 196258892Semaste log->Printf("ProcessFreeBSD::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID()); 197258054Semaste 198258892Semaste std::vector<lldb::pid_t> tds; 199258892Semaste if (!GetMonitor().GetCurrentThreadIDs(tds)) 200258892Semaste { 201258892Semaste return false; 202258054Semaste } 203258054Semaste 204258892Semaste ThreadList old_thread_list_copy(old_thread_list); 205258892Semaste for (size_t i = 0; i < tds.size(); ++i) 206258892Semaste { 207258892Semaste tid_t tid = tds[i]; 208258892Semaste ThreadSP thread_sp (old_thread_list_copy.RemoveThreadByID(tid, false)); 209258892Semaste if (!thread_sp) 210258892Semaste { 211258892Semaste thread_sp.reset(new FreeBSDThread(*this, tid)); 212258892Semaste if (log) 213258892Semaste log->Printf("ProcessFreeBSD::%s new tid = %" PRIu64, __FUNCTION__, tid); 214258892Semaste } 215258892Semaste else 216258892Semaste { 217258892Semaste if (log) 218258892Semaste log->Printf("ProcessFreeBSD::%s existing tid = %" PRIu64, __FUNCTION__, tid); 219258892Semaste } 220258892Semaste new_thread_list.AddThread(thread_sp); 221258892Semaste } 222258892Semaste for (size_t i = 0; i < old_thread_list_copy.GetSize(false); ++i) 223258892Semaste { 224258892Semaste ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false)); 225258892Semaste if (old_thread_sp) 226258892Semaste { 227258892Semaste if (log) 228258892Semaste log->Printf("ProcessFreeBSD::%s remove tid", __FUNCTION__); 229258892Semaste } 230258892Semaste } 231258054Semaste 232258892Semaste return true; 233258892Semaste} 234258054Semaste 235258892SemasteError 236258892SemasteProcessFreeBSD::WillResume() 237258892Semaste{ 238276479Sdim m_resume_signo = 0; 239258892Semaste m_suspend_tids.clear(); 240258892Semaste m_run_tids.clear(); 241258892Semaste m_step_tids.clear(); 242258892Semaste return ProcessPOSIX::WillResume(); 243254721Semaste} 244258892Semaste 245258892Semastevoid 246258892SemasteProcessFreeBSD::SendMessage(const ProcessMessage &message) 247258892Semaste{ 248258892Semaste Mutex::Locker lock(m_message_mutex); 249258892Semaste 250258892Semaste switch (message.GetKind()) 251258892Semaste { 252258892Semaste case ProcessMessage::eInvalidMessage: 253258892Semaste return; 254258892Semaste 255258892Semaste case ProcessMessage::eAttachMessage: 256258892Semaste SetPrivateState(eStateStopped); 257258892Semaste return; 258258892Semaste 259258892Semaste case ProcessMessage::eLimboMessage: 260258892Semaste case ProcessMessage::eExitMessage: 261258892Semaste m_exit_status = message.GetExitStatus(); 262258892Semaste SetExitStatus(m_exit_status, NULL); 263258892Semaste break; 264258892Semaste 265258892Semaste case ProcessMessage::eSignalMessage: 266258892Semaste case ProcessMessage::eSignalDeliveredMessage: 267258892Semaste case ProcessMessage::eBreakpointMessage: 268258892Semaste case ProcessMessage::eTraceMessage: 269258892Semaste case ProcessMessage::eWatchpointMessage: 270258892Semaste case ProcessMessage::eCrashMessage: 271258892Semaste SetPrivateState(eStateStopped); 272258892Semaste break; 273258892Semaste 274258892Semaste case ProcessMessage::eNewThreadMessage: 275258892Semaste assert(0 && "eNewThreadMessage unexpected on FreeBSD"); 276258892Semaste break; 277258892Semaste 278258892Semaste case ProcessMessage::eExecMessage: 279258892Semaste SetPrivateState(eStateStopped); 280258892Semaste break; 281258892Semaste } 282258892Semaste 283258892Semaste m_message_queue.push(message); 284258892Semaste} 285