blob: 3e3feafbc91fd8edbe6a35dd1d6333be16c0d04c [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 Fiala348fb382014-10-10 00:09:16 +000023#include "Plugins/Platform/Linux/PlatformLinux.h"
Todd Fialacacde7d2014-09-27 16:54:22 +000024#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
Peter Collingbourne70969ef2011-06-03 20:40:44 +000025#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
Todd Fiala4ceced32014-08-29 17:35:57 +000026#include "Plugins/Process/Utility/LinuxSignals.h"
Stephen Wilsone6f9f662010-07-24 02:19:04 +000027#include "ProcessMonitor.h"
Michael Sartain9f822cd2013-07-31 23:27:46 +000028#include "LinuxThread.h"
Stephen Wilsone6f9f662010-07-24 02:19:04 +000029
30using namespace lldb;
31using namespace lldb_private;
32
Todd Fiala4ceced32014-08-29 17:35:57 +000033namespace
34{
35 UnixSignalsSP&
36 GetStaticLinuxSignalsSP ()
37 {
38 static UnixSignalsSP s_unix_signals_sp (new process_linux::LinuxSignals ());
39 return s_unix_signals_sp;
40 }
41}
42
Stephen Wilsone6f9f662010-07-24 02:19:04 +000043//------------------------------------------------------------------------------
44// Static functions.
45
Greg Clayton0c90ef42012-02-21 18:40:07 +000046ProcessSP
Ashok Thirumurthi4f01ff82013-07-17 16:06:12 +000047ProcessLinux::CreateInstance(Target &target, Listener &listener, const FileSpec *core_file)
Stephen Wilsone6f9f662010-07-24 02:19:04 +000048{
Ashok Thirumurthi4f01ff82013-07-17 16:06:12 +000049 return ProcessSP(new ProcessLinux(target, listener, (FileSpec *)core_file));
Stephen Wilsone6f9f662010-07-24 02:19:04 +000050}
51
52void
53ProcessLinux::Initialize()
54{
55 static bool g_initialized = false;
56
57 if (!g_initialized)
58 {
Johnny Chen6dcbeae2011-10-11 21:21:57 +000059 g_initialized = true;
Stephen Wilsone6f9f662010-07-24 02:19:04 +000060 PluginManager::RegisterPlugin(GetPluginNameStatic(),
61 GetPluginDescriptionStatic(),
62 CreateInstance);
Johnny Chen6dcbeae2011-10-11 21:21:57 +000063
64 Log::Callbacks log_callbacks = {
Johnny Chen30213ff2012-01-05 19:17:38 +000065 ProcessPOSIXLog::DisableLog,
66 ProcessPOSIXLog::EnableLog,
67 ProcessPOSIXLog::ListLogCategories
Johnny Chen6dcbeae2011-10-11 21:21:57 +000068 };
69
70 Log::RegisterLogChannel (ProcessLinux::GetPluginNameStatic(), log_callbacks);
Johnny Chen30213ff2012-01-05 19:17:38 +000071 ProcessPOSIXLog::RegisterPluginName(GetPluginNameStatic());
Stephen Wilsone6f9f662010-07-24 02:19:04 +000072 }
73}
74
Stephen Wilsone6f9f662010-07-24 02:19:04 +000075//------------------------------------------------------------------------------
76// Constructors and destructors.
77
Ashok Thirumurthi4f01ff82013-07-17 16:06:12 +000078ProcessLinux::ProcessLinux(Target& target, Listener &listener, FileSpec *core_file)
Todd Fiala4ceced32014-08-29 17:35:57 +000079 : ProcessPOSIX(target, listener, GetStaticLinuxSignalsSP ()), m_core_file(core_file), m_stopping_threads(false)
Stephen Wilsone6f9f662010-07-24 02:19:04 +000080{
Greg Clayton386ff182011-11-05 01:09:16 +000081#if 0
Stephen Wilsone6f9f662010-07-24 02:19:04 +000082 // FIXME: Putting this code in the ctor and saving the byte order in a
83 // member variable is a hack to avoid const qual issues in GetByteOrder.
84 ObjectFile *obj_file = GetTarget().GetExecutableModule()->GetObjectFile();
85 m_byte_order = obj_file->GetByteOrder();
Greg Clayton386ff182011-11-05 01:09:16 +000086#else
87 // XXX: Will work only for local processes.
88 m_byte_order = lldb::endian::InlHostByteOrder();
89#endif
Stephen Wilsone6f9f662010-07-24 02:19:04 +000090}
91
Stephen Wilson2103e252011-01-16 19:45:39 +000092void
Johnny Chen30213ff2012-01-05 19:17:38 +000093ProcessLinux::Terminate()
Stephen Wilson2103e252011-01-16 19:45:39 +000094{
Stephen Wilson2103e252011-01-16 19:45:39 +000095}
Michael Sartain9f822cd2013-07-31 23:27:46 +000096
Greg Clayton57abc5d2013-05-10 21:47:16 +000097lldb_private::ConstString
Johnny Chen30213ff2012-01-05 19:17:38 +000098ProcessLinux::GetPluginNameStatic()
Stephen Wilsone6f9f662010-07-24 02:19:04 +000099{
Greg Clayton57abc5d2013-05-10 21:47:16 +0000100 static ConstString g_name("linux");
101 return g_name;
Stephen Wilsone6f9f662010-07-24 02:19:04 +0000102}
103
Johnny Chen30213ff2012-01-05 19:17:38 +0000104const char *
105ProcessLinux::GetPluginDescriptionStatic()
Stephen Wilsonc4391cb2011-01-15 00:10:37 +0000106{
Johnny Chen30213ff2012-01-05 19:17:38 +0000107 return "Process plugin for Linux";
Stephen Wilsonc4391cb2011-01-15 00:10:37 +0000108}
109
Stephen Wilsone6f9f662010-07-24 02:19:04 +0000110
Greg Claytonc3c0b0e2012-04-12 19:04:34 +0000111bool
Johnny Chen48d042b2011-10-10 23:11:50 +0000112ProcessLinux::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
113{
Matt Kopec650648f2013-01-08 16:30:18 +0000114 new_thread_list = old_thread_list;
Greg Claytonc3c0b0e2012-04-12 19:04:34 +0000115 return new_thread_list.GetSize(false) > 0;
Johnny Chen48d042b2011-10-10 23:11:50 +0000116}
117
Stephen Wilson26977162011-03-23 02:14:42 +0000118
Stephen Wilsone6f9f662010-07-24 02:19:04 +0000119//------------------------------------------------------------------------------
120// ProcessInterface protocol.
121
Greg Clayton57abc5d2013-05-10 21:47:16 +0000122lldb_private::ConstString
Stephen Wilsone6f9f662010-07-24 02:19:04 +0000123ProcessLinux::GetPluginName()
124{
Greg Clayton57abc5d2013-05-10 21:47:16 +0000125 return GetPluginNameStatic();
Stephen Wilsone6f9f662010-07-24 02:19:04 +0000126}
127
128uint32_t
129ProcessLinux::GetPluginVersion()
130{
131 return 1;
132}
133
134void
135ProcessLinux::GetPluginCommandHelp(const char *command, Stream *strm)
136{
137}
138
139Error
140ProcessLinux::ExecutePluginCommand(Args &command, Stream *strm)
141{
142 return Error(1, eErrorTypeGeneric);
143}
144
145Log *
146ProcessLinux::EnablePluginLogging(Stream *strm, Args &command)
147{
148 return NULL;
149}
Andrew Kaylor93132f52013-05-28 23:04:25 +0000150
Ed Maste7dcb77d2013-08-30 13:11:30 +0000151Error
152ProcessLinux::DoDetach(bool keep_stopped)
153{
154 Error error;
155 if (keep_stopped)
156 {
157 // FIXME: If you want to implement keep_stopped,
158 // this would be the place to do it.
159 error.SetErrorString("Detaching with keep_stopped true is not currently supported on Linux.");
160 return error;
161 }
162
163 Mutex::Locker lock(m_thread_list.GetMutex());
164
165 uint32_t thread_count = m_thread_list.GetSize(false);
166 for (uint32_t i = 0; i < thread_count; ++i)
167 {
168 POSIXThread *thread = static_cast<POSIXThread*>(
169 m_thread_list.GetThreadAtIndex(i, false).get());
170 error = m_monitor->Detach(thread->GetID());
171 }
172
173 if (error.Success())
174 SetPrivateState(eStateDetached);
175
176 return error;
177}
178
179
Andrew Kaylor93132f52013-05-28 23:04:25 +0000180// ProcessPOSIX override
181void
182ProcessLinux::StopAllThreads(lldb::tid_t stop_tid)
183{
184 // If a breakpoint occurs while we're stopping threads, we'll get back
185 // here, but we don't want to do it again. Only the MonitorChildProcess
186 // thread calls this function, so we don't need to protect this flag.
187 if (m_stopping_threads)
188 return;
189 m_stopping_threads = true;
190
191 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
192 if (log)
193 log->Printf ("ProcessLinux::%s() stopping all threads", __FUNCTION__);
194
195 // Walk the thread list and stop the other threads. The thread that caused
196 // the stop should already be marked as stopped before we get here.
197 Mutex::Locker thread_list_lock(m_thread_list.GetMutex());
198
199 uint32_t thread_count = m_thread_list.GetSize(false);
200 for (uint32_t i = 0; i < thread_count; ++i)
201 {
202 POSIXThread *thread = static_cast<POSIXThread*>(
203 m_thread_list.GetThreadAtIndex(i, false).get());
204 assert(thread);
205 lldb::tid_t tid = thread->GetID();
206 if (!StateIsStoppedState(thread->GetState(), false))
207 m_monitor->StopThread(tid);
208 }
209
210 m_stopping_threads = false;
211
212 if (log)
213 log->Printf ("ProcessLinux::%s() finished", __FUNCTION__);
214}
Ashok Thirumurthi4f01ff82013-07-17 16:06:12 +0000215
Michael Sartain9f822cd2013-07-31 23:27:46 +0000216// ProcessPOSIX override
217POSIXThread *
218ProcessLinux::CreateNewPOSIXThread(lldb_private::Process &process, lldb::tid_t tid)
219{
220 return new LinuxThread(process, tid);
221}
222
Ashok Thirumurthi4f01ff82013-07-17 16:06:12 +0000223bool
224ProcessLinux::CanDebug(Target &target, bool plugin_specified_by_name)
225{
226 if (plugin_specified_by_name)
227 return true;
228
229 /* If core file is specified then let elf-core plugin handle it */
230 if (m_core_file)
231 return false;
232
Todd Fiala348fb382014-10-10 00:09:16 +0000233 // If we're using llgs for local debugging, we must not say that this process
234 // is used for debugging.
235 if (PlatformLinux::UseLlgsForLocalDebugging ())
236 return false;
237
Ashok Thirumurthi4f01ff82013-07-17 16:06:12 +0000238 return ProcessPOSIX::CanDebug(target, plugin_specified_by_name);
239}
240