ProcessFreeBSD.cpp revision 258892
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" 25254721Semaste#include "ProcessMonitor.h" 26258892Semaste#include "FreeBSDThread.h" 27254721Semaste 28254721Semasteusing namespace lldb; 29254721Semasteusing namespace lldb_private; 30254721Semaste 31254721Semaste//------------------------------------------------------------------------------ 32254721Semaste// Static functions. 33254721Semaste 34254721Semastelldb::ProcessSP 35254721SemasteProcessFreeBSD::CreateInstance(Target& target, 36254721Semaste Listener &listener, 37254721Semaste const FileSpec *crash_file_path) 38254721Semaste{ 39254721Semaste lldb::ProcessSP process_sp; 40254721Semaste if (crash_file_path == NULL) 41254721Semaste process_sp.reset(new ProcessFreeBSD (target, listener)); 42254721Semaste return process_sp; 43254721Semaste} 44254721Semaste 45254721Semastevoid 46254721SemasteProcessFreeBSD::Initialize() 47254721Semaste{ 48254721Semaste static bool g_initialized = false; 49254721Semaste 50254721Semaste if (!g_initialized) 51254721Semaste { 52254721Semaste PluginManager::RegisterPlugin(GetPluginNameStatic(), 53254721Semaste GetPluginDescriptionStatic(), 54254721Semaste CreateInstance); 55254721Semaste Log::Callbacks log_callbacks = { 56254721Semaste ProcessPOSIXLog::DisableLog, 57254721Semaste ProcessPOSIXLog::EnableLog, 58254721Semaste ProcessPOSIXLog::ListLogCategories 59254721Semaste }; 60254721Semaste 61254721Semaste Log::RegisterLogChannel (ProcessFreeBSD::GetPluginNameStatic(), log_callbacks); 62254721Semaste ProcessPOSIXLog::RegisterPluginName(GetPluginNameStatic()); 63254721Semaste g_initialized = true; 64254721Semaste } 65254721Semaste} 66254721Semaste 67254721Semastelldb_private::ConstString 68254721SemasteProcessFreeBSD::GetPluginNameStatic() 69254721Semaste{ 70254721Semaste static ConstString g_name("freebsd"); 71254721Semaste return g_name; 72254721Semaste} 73254721Semaste 74254721Semasteconst char * 75254721SemasteProcessFreeBSD::GetPluginDescriptionStatic() 76254721Semaste{ 77254721Semaste return "Process plugin for FreeBSD"; 78254721Semaste} 79254721Semaste 80254721Semaste//------------------------------------------------------------------------------ 81254721Semaste// ProcessInterface protocol. 82254721Semaste 83254721Semastelldb_private::ConstString 84254721SemasteProcessFreeBSD::GetPluginName() 85254721Semaste{ 86254721Semaste return GetPluginNameStatic(); 87254721Semaste} 88254721Semaste 89254721Semasteuint32_t 90254721SemasteProcessFreeBSD::GetPluginVersion() 91254721Semaste{ 92254721Semaste return 1; 93254721Semaste} 94254721Semaste 95254721Semastevoid 96254721SemasteProcessFreeBSD::GetPluginCommandHelp(const char *command, Stream *strm) 97254721Semaste{ 98254721Semaste} 99254721Semaste 100254721SemasteError 101254721SemasteProcessFreeBSD::ExecutePluginCommand(Args &command, Stream *strm) 102254721Semaste{ 103254721Semaste return Error(1, eErrorTypeGeneric); 104254721Semaste} 105254721Semaste 106254721SemasteLog * 107254721SemasteProcessFreeBSD::EnablePluginLogging(Stream *strm, Args &command) 108254721Semaste{ 109254721Semaste return NULL; 110254721Semaste} 111254721Semaste 112254721Semaste//------------------------------------------------------------------------------ 113254721Semaste// Constructors and destructors. 114254721Semaste 115254721SemasteProcessFreeBSD::ProcessFreeBSD(Target& target, Listener &listener) 116254721Semaste : ProcessPOSIX(target, listener) 117254721Semaste{ 118254721Semaste} 119254721Semaste 120254721Semastevoid 121254721SemasteProcessFreeBSD::Terminate() 122254721Semaste{ 123254721Semaste} 124254721Semaste 125258054SemasteError 126258054SemasteProcessFreeBSD::DoDetach(bool keep_stopped) 127258054Semaste{ 128258054Semaste Error error; 129258054Semaste if (keep_stopped) 130258054Semaste { 131258054Semaste error.SetErrorString("Detaching with keep_stopped true is not currently supported on FreeBSD."); 132258054Semaste return error; 133258054Semaste } 134258054Semaste 135258054Semaste error = m_monitor->Detach(GetID()); 136258054Semaste 137258054Semaste if (error.Success()) 138258054Semaste SetPrivateState(eStateDetached); 139258054Semaste 140258054Semaste return error; 141258054Semaste} 142258054Semaste 143258892SemasteError 144258892SemasteProcessFreeBSD::DoResume() 145258892Semaste{ 146258892Semaste Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); 147258892Semaste 148258892Semaste // FreeBSD's ptrace() uses 0 to indicate "no signal is to be sent." 149258892Semaste int resume_signal = 0; 150258892Semaste 151258892Semaste SetPrivateState(eStateRunning); 152258892Semaste 153258892Semaste Mutex::Locker lock(m_thread_list.GetMutex()); 154258892Semaste bool do_step = false; 155258892Semaste 156258892Semaste for (tid_collection::const_iterator t_pos = m_run_tids.begin(), t_end = m_run_tids.end(); t_pos != t_end; ++t_pos) 157258892Semaste { 158258892Semaste m_monitor->ThreadSuspend(*t_pos, false); 159258892Semaste } 160258892Semaste for (tid_collection::const_iterator t_pos = m_step_tids.begin(), t_end = m_step_tids.end(); t_pos != t_end; ++t_pos) 161258892Semaste { 162258892Semaste m_monitor->ThreadSuspend(*t_pos, false); 163258892Semaste do_step = true; 164258892Semaste } 165258892Semaste for (tid_collection::const_iterator t_pos = m_suspend_tids.begin(), t_end = m_suspend_tids.end(); t_pos != t_end; ++t_pos) 166258892Semaste { 167258892Semaste m_monitor->ThreadSuspend(*t_pos, true); 168258892Semaste // XXX Cannot PT_CONTINUE properly with suspended threads. 169258892Semaste do_step = true; 170258892Semaste } 171258892Semaste 172258892Semaste if (log) 173258892Semaste log->Printf("process %lu resuming (%s)", GetID(), do_step ? "step" : "continue"); 174258892Semaste if (do_step) 175258892Semaste m_monitor->SingleStep(GetID(), resume_signal); 176258892Semaste else 177258892Semaste m_monitor->Resume(GetID(), resume_signal); 178258892Semaste 179258892Semaste return Error(); 180258892Semaste} 181258892Semaste 182254721Semastebool 183254721SemasteProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) 184254721Semaste{ 185258892Semaste Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); 186258892Semaste if (log) 187258892Semaste log->Printf("ProcessFreeBSD::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID()); 188258054Semaste 189258892Semaste std::vector<lldb::pid_t> tds; 190258892Semaste if (!GetMonitor().GetCurrentThreadIDs(tds)) 191258892Semaste { 192258892Semaste return false; 193258054Semaste } 194258054Semaste 195258892Semaste ThreadList old_thread_list_copy(old_thread_list); 196258892Semaste for (size_t i = 0; i < tds.size(); ++i) 197258892Semaste { 198258892Semaste tid_t tid = tds[i]; 199258892Semaste ThreadSP thread_sp (old_thread_list_copy.RemoveThreadByID(tid, false)); 200258892Semaste if (!thread_sp) 201258892Semaste { 202258892Semaste thread_sp.reset(new FreeBSDThread(*this, tid)); 203258892Semaste if (log) 204258892Semaste log->Printf("ProcessFreeBSD::%s new tid = %" PRIu64, __FUNCTION__, tid); 205258892Semaste } 206258892Semaste else 207258892Semaste { 208258892Semaste if (log) 209258892Semaste log->Printf("ProcessFreeBSD::%s existing tid = %" PRIu64, __FUNCTION__, tid); 210258892Semaste } 211258892Semaste new_thread_list.AddThread(thread_sp); 212258892Semaste } 213258892Semaste for (size_t i = 0; i < old_thread_list_copy.GetSize(false); ++i) 214258892Semaste { 215258892Semaste ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false)); 216258892Semaste if (old_thread_sp) 217258892Semaste { 218258892Semaste if (log) 219258892Semaste log->Printf("ProcessFreeBSD::%s remove tid", __FUNCTION__); 220258892Semaste } 221258892Semaste } 222258054Semaste 223258892Semaste return true; 224258892Semaste} 225258054Semaste 226258892SemasteError 227258892SemasteProcessFreeBSD::WillResume() 228258892Semaste{ 229258892Semaste m_suspend_tids.clear(); 230258892Semaste m_run_tids.clear(); 231258892Semaste m_step_tids.clear(); 232258892Semaste return ProcessPOSIX::WillResume(); 233254721Semaste} 234258892Semaste 235258892Semastevoid 236258892SemasteProcessFreeBSD::SendMessage(const ProcessMessage &message) 237258892Semaste{ 238258892Semaste Mutex::Locker lock(m_message_mutex); 239258892Semaste 240258892Semaste switch (message.GetKind()) 241258892Semaste { 242258892Semaste case ProcessMessage::eInvalidMessage: 243258892Semaste return; 244258892Semaste 245258892Semaste case ProcessMessage::eAttachMessage: 246258892Semaste SetPrivateState(eStateStopped); 247258892Semaste return; 248258892Semaste 249258892Semaste case ProcessMessage::eLimboMessage: 250258892Semaste case ProcessMessage::eExitMessage: 251258892Semaste m_exit_status = message.GetExitStatus(); 252258892Semaste SetExitStatus(m_exit_status, NULL); 253258892Semaste break; 254258892Semaste 255258892Semaste case ProcessMessage::eSignalMessage: 256258892Semaste case ProcessMessage::eSignalDeliveredMessage: 257258892Semaste case ProcessMessage::eBreakpointMessage: 258258892Semaste case ProcessMessage::eTraceMessage: 259258892Semaste case ProcessMessage::eWatchpointMessage: 260258892Semaste case ProcessMessage::eCrashMessage: 261258892Semaste SetPrivateState(eStateStopped); 262258892Semaste break; 263258892Semaste 264258892Semaste case ProcessMessage::eNewThreadMessage: 265258892Semaste assert(0 && "eNewThreadMessage unexpected on FreeBSD"); 266258892Semaste break; 267258892Semaste 268258892Semaste case ProcessMessage::eExecMessage: 269258892Semaste SetPrivateState(eStateStopped); 270258892Semaste break; 271258892Semaste } 272258892Semaste 273258892Semaste m_message_queue.push(message); 274258892Semaste} 275258892Semaste 276