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