blob: 5b051dff0a87aef524b5fda1d6b0bcf3f63b19d5 [file] [log] [blame]
Stephen Wilsone6f9f662010-07-24 02:19:04 +00001//===-- ProcessLinux.cpp ----------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// C Includes
Stephen Wilson26977162011-03-23 02:14:42 +000011#include <errno.h>
12
Stephen Wilsone6f9f662010-07-24 02:19:04 +000013// C++ Includes
14// Other libraries and framework includes
15#include "lldb/Core/PluginManager.h"
Peter Collingbourne70969ef2011-06-03 20:40:44 +000016#include "lldb/Core/State.h"
Stephen Wilsone6f9f662010-07-24 02:19:04 +000017#include "lldb/Host/Host.h"
18#include "lldb/Symbol/ObjectFile.h"
Stephen Wilson2103e252011-01-16 19:45:39 +000019#include "lldb/Target/DynamicLoader.h"
Stephen Wilsone6f9f662010-07-24 02:19:04 +000020#include "lldb/Target/Target.h"
21
22#include "ProcessLinux.h"
Todd Fialacacde7d2014-09-27 16:54:22 +000023#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
Peter Collingbourne70969ef2011-06-03 20:40:44 +000024#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
Todd Fiala4ceced32014-08-29 17:35:57 +000025#include "Plugins/Process/Utility/LinuxSignals.h"
Stephen Wilsone6f9f662010-07-24 02:19:04 +000026#include "ProcessMonitor.h"
Michael Sartain9f822cd2013-07-31 23:27:46 +000027#include "LinuxThread.h"
Stephen Wilsone6f9f662010-07-24 02:19:04 +000028
29using namespace lldb;
30using namespace lldb_private;
31
Todd Fiala4ceced32014-08-29 17:35:57 +000032namespace
33{
34 UnixSignalsSP&
35 GetStaticLinuxSignalsSP ()
36 {
37 static UnixSignalsSP s_unix_signals_sp (new process_linux::LinuxSignals ());
38 return s_unix_signals_sp;
39 }
40}
41
Stephen Wilsone6f9f662010-07-24 02:19:04 +000042//------------------------------------------------------------------------------
43// Static functions.
44
Greg Clayton0c90ef42012-02-21 18:40:07 +000045ProcessSP
Ashok Thirumurthi4f01ff82013-07-17 16:06:12 +000046ProcessLinux::CreateInstance(Target &target, Listener &listener, const FileSpec *core_file)
Stephen Wilsone6f9f662010-07-24 02:19:04 +000047{
Ashok Thirumurthi4f01ff82013-07-17 16:06:12 +000048 return ProcessSP(new ProcessLinux(target, listener, (FileSpec *)core_file));
Stephen Wilsone6f9f662010-07-24 02:19:04 +000049}
50
51void
52ProcessLinux::Initialize()
53{
54 static bool g_initialized = false;
55
56 if (!g_initialized)
57 {
Johnny Chen6dcbeae2011-10-11 21:21:57 +000058 g_initialized = true;
Stephen Wilsone6f9f662010-07-24 02:19:04 +000059 PluginManager::RegisterPlugin(GetPluginNameStatic(),
60 GetPluginDescriptionStatic(),
61 CreateInstance);
Johnny Chen6dcbeae2011-10-11 21:21:57 +000062
63 Log::Callbacks log_callbacks = {
Johnny Chen30213ff2012-01-05 19:17:38 +000064 ProcessPOSIXLog::DisableLog,
65 ProcessPOSIXLog::EnableLog,
66 ProcessPOSIXLog::ListLogCategories
Johnny Chen6dcbeae2011-10-11 21:21:57 +000067 };
68
69 Log::RegisterLogChannel (ProcessLinux::GetPluginNameStatic(), log_callbacks);
Johnny Chen30213ff2012-01-05 19:17:38 +000070 ProcessPOSIXLog::RegisterPluginName(GetPluginNameStatic());
Stephen Wilsone6f9f662010-07-24 02:19:04 +000071 }
72}
73
Stephen Wilsone6f9f662010-07-24 02:19:04 +000074//------------------------------------------------------------------------------
75// Constructors and destructors.
76
Ashok Thirumurthi4f01ff82013-07-17 16:06:12 +000077ProcessLinux::ProcessLinux(Target& target, Listener &listener, FileSpec *core_file)
Todd Fiala4ceced32014-08-29 17:35:57 +000078 : ProcessPOSIX(target, listener, GetStaticLinuxSignalsSP ()), m_core_file(core_file), m_stopping_threads(false)
Stephen Wilsone6f9f662010-07-24 02:19:04 +000079{
Greg Clayton386ff182011-11-05 01:09:16 +000080#if 0
Stephen Wilsone6f9f662010-07-24 02:19:04 +000081 // FIXME: Putting this code in the ctor and saving the byte order in a
82 // member variable is a hack to avoid const qual issues in GetByteOrder.
83 ObjectFile *obj_file = GetTarget().GetExecutableModule()->GetObjectFile();
84 m_byte_order = obj_file->GetByteOrder();
Greg Clayton386ff182011-11-05 01:09:16 +000085#else
86 // XXX: Will work only for local processes.
87 m_byte_order = lldb::endian::InlHostByteOrder();
88#endif
Stephen Wilsone6f9f662010-07-24 02:19:04 +000089}
90
Stephen Wilson2103e252011-01-16 19:45:39 +000091void
Johnny Chen30213ff2012-01-05 19:17:38 +000092ProcessLinux::Terminate()
Stephen Wilson2103e252011-01-16 19:45:39 +000093{
Stephen Wilson2103e252011-01-16 19:45:39 +000094}
Michael Sartain9f822cd2013-07-31 23:27:46 +000095
Greg Clayton57abc5d2013-05-10 21:47:16 +000096lldb_private::ConstString
Johnny Chen30213ff2012-01-05 19:17:38 +000097ProcessLinux::GetPluginNameStatic()
Stephen Wilsone6f9f662010-07-24 02:19:04 +000098{
Greg Clayton57abc5d2013-05-10 21:47:16 +000099 static ConstString g_name("linux");
100 return g_name;
Stephen Wilsone6f9f662010-07-24 02:19:04 +0000101}
102
Johnny Chen30213ff2012-01-05 19:17:38 +0000103const char *
104ProcessLinux::GetPluginDescriptionStatic()
Stephen Wilsonc4391cb2011-01-15 00:10:37 +0000105{
Johnny Chen30213ff2012-01-05 19:17:38 +0000106 return "Process plugin for Linux";
Stephen Wilsonc4391cb2011-01-15 00:10:37 +0000107}
108
Stephen Wilsone6f9f662010-07-24 02:19:04 +0000109
Greg Claytonc3c0b0e2012-04-12 19:04:34 +0000110bool
Johnny Chen48d042b2011-10-10 23:11:50 +0000111ProcessLinux::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
112{
Matt Kopec650648f2013-01-08 16:30:18 +0000113 new_thread_list = old_thread_list;
Greg Claytonc3c0b0e2012-04-12 19:04:34 +0000114 return new_thread_list.GetSize(false) > 0;
Johnny Chen48d042b2011-10-10 23:11:50 +0000115}
116
Stephen Wilson26977162011-03-23 02:14:42 +0000117
Stephen Wilsone6f9f662010-07-24 02:19:04 +0000118//------------------------------------------------------------------------------
119// ProcessInterface protocol.
120
Greg Clayton57abc5d2013-05-10 21:47:16 +0000121lldb_private::ConstString
Stephen Wilsone6f9f662010-07-24 02:19:04 +0000122ProcessLinux::GetPluginName()
123{
Greg Clayton57abc5d2013-05-10 21:47:16 +0000124 return GetPluginNameStatic();
Stephen Wilsone6f9f662010-07-24 02:19:04 +0000125}
126
127uint32_t
128ProcessLinux::GetPluginVersion()
129{
130 return 1;
131}
132
133void
134ProcessLinux::GetPluginCommandHelp(const char *command, Stream *strm)
135{
136}
137
138Error
139ProcessLinux::ExecutePluginCommand(Args &command, Stream *strm)
140{
141 return Error(1, eErrorTypeGeneric);
142}
143
144Log *
145ProcessLinux::EnablePluginLogging(Stream *strm, Args &command)
146{
147 return NULL;
148}
Andrew Kaylor93132f52013-05-28 23:04:25 +0000149
Ed Maste7dcb77d2013-08-30 13:11:30 +0000150Error
151ProcessLinux::DoDetach(bool keep_stopped)
152{
153 Error error;
154 if (keep_stopped)
155 {
156 // FIXME: If you want to implement keep_stopped,
157 // this would be the place to do it.
158 error.SetErrorString("Detaching with keep_stopped true is not currently supported on Linux.");
159 return error;
160 }
161
162 Mutex::Locker lock(m_thread_list.GetMutex());
163
164 uint32_t thread_count = m_thread_list.GetSize(false);
165 for (uint32_t i = 0; i < thread_count; ++i)
166 {
167 POSIXThread *thread = static_cast<POSIXThread*>(
168 m_thread_list.GetThreadAtIndex(i, false).get());
169 error = m_monitor->Detach(thread->GetID());
170 }
171
172 if (error.Success())
173 SetPrivateState(eStateDetached);
174
175 return error;
176}
177
178
Andrew Kaylor93132f52013-05-28 23:04:25 +0000179// ProcessPOSIX override
180void
181ProcessLinux::StopAllThreads(lldb::tid_t stop_tid)
182{
183 // If a breakpoint occurs while we're stopping threads, we'll get back
184 // here, but we don't want to do it again. Only the MonitorChildProcess
185 // thread calls this function, so we don't need to protect this flag.
186 if (m_stopping_threads)
187 return;
188 m_stopping_threads = true;
189
190 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
191 if (log)
192 log->Printf ("ProcessLinux::%s() stopping all threads", __FUNCTION__);
193
194 // Walk the thread list and stop the other threads. The thread that caused
195 // the stop should already be marked as stopped before we get here.
196 Mutex::Locker thread_list_lock(m_thread_list.GetMutex());
197
198 uint32_t thread_count = m_thread_list.GetSize(false);
199 for (uint32_t i = 0; i < thread_count; ++i)
200 {
201 POSIXThread *thread = static_cast<POSIXThread*>(
202 m_thread_list.GetThreadAtIndex(i, false).get());
203 assert(thread);
204 lldb::tid_t tid = thread->GetID();
205 if (!StateIsStoppedState(thread->GetState(), false))
206 m_monitor->StopThread(tid);
207 }
208
209 m_stopping_threads = false;
210
211 if (log)
212 log->Printf ("ProcessLinux::%s() finished", __FUNCTION__);
213}
Ashok Thirumurthi4f01ff82013-07-17 16:06:12 +0000214
Michael Sartain9f822cd2013-07-31 23:27:46 +0000215// ProcessPOSIX override
216POSIXThread *
217ProcessLinux::CreateNewPOSIXThread(lldb_private::Process &process, lldb::tid_t tid)
218{
219 return new LinuxThread(process, tid);
220}
221
Ashok Thirumurthi4f01ff82013-07-17 16:06:12 +0000222bool
223ProcessLinux::CanDebug(Target &target, bool plugin_specified_by_name)
224{
225 if (plugin_specified_by_name)
226 return true;
227
228 /* If core file is specified then let elf-core plugin handle it */
229 if (m_core_file)
230 return false;
231
232 return ProcessPOSIX::CanDebug(target, plugin_specified_by_name);
233}
234