blob: cffb1f6f43c6fd73c31ed9cf43f51ebbaff8f2bd [file] [log] [blame]
Stephen Wilsonf6f40332010-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 Wilsond1fbbb42011-03-23 02:14:42 +000011#include <errno.h>
12
Stephen Wilsonf6f40332010-07-24 02:19:04 +000013// C++ Includes
14// Other libraries and framework includes
15#include "lldb/Core/PluginManager.h"
Peter Collingbournead115462011-06-03 20:40:44 +000016#include "lldb/Core/State.h"
Stephen Wilsonf6f40332010-07-24 02:19:04 +000017#include "lldb/Host/Host.h"
18#include "lldb/Symbol/ObjectFile.h"
Stephen Wilson92241ef2011-01-16 19:45:39 +000019#include "lldb/Target/DynamicLoader.h"
Stephen Wilsonf6f40332010-07-24 02:19:04 +000020#include "lldb/Target/Target.h"
21
22#include "ProcessLinux.h"
Johnny Chenac51e9f2011-10-11 21:21:57 +000023#include "ProcessLinuxLog.h"
Peter Collingbournead115462011-06-03 20:40:44 +000024#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
Stephen Wilsonf6f40332010-07-24 02:19:04 +000025#include "ProcessMonitor.h"
26#include "LinuxThread.h"
27
28using namespace lldb;
29using namespace lldb_private;
30
31//------------------------------------------------------------------------------
32// Static functions.
33
34Process*
35ProcessLinux::CreateInstance(Target& target, Listener &listener)
36{
37 return new ProcessLinux(target, listener);
38}
39
40void
41ProcessLinux::Initialize()
42{
43 static bool g_initialized = false;
44
45 if (!g_initialized)
46 {
Johnny Chenac51e9f2011-10-11 21:21:57 +000047 g_initialized = true;
Stephen Wilsonf6f40332010-07-24 02:19:04 +000048 PluginManager::RegisterPlugin(GetPluginNameStatic(),
49 GetPluginDescriptionStatic(),
50 CreateInstance);
Johnny Chenac51e9f2011-10-11 21:21:57 +000051
52 Log::Callbacks log_callbacks = {
53 ProcessLinuxLog::DisableLog,
54 ProcessLinuxLog::EnableLog,
55 ProcessLinuxLog::ListLogCategories
56 };
57
58 Log::RegisterLogChannel (ProcessLinux::GetPluginNameStatic(), log_callbacks);
Stephen Wilsonf6f40332010-07-24 02:19:04 +000059 }
60}
61
62void
63ProcessLinux::Terminate()
64{
65}
66
67const char *
68ProcessLinux::GetPluginNameStatic()
69{
70 return "plugin.process.linux";
71}
72
73const char *
74ProcessLinux::GetPluginDescriptionStatic()
75{
76 return "Process plugin for Linux";
77}
78
79
80//------------------------------------------------------------------------------
81// Constructors and destructors.
82
83ProcessLinux::ProcessLinux(Target& target, Listener &listener)
84 : Process(target, listener),
85 m_monitor(NULL),
Stephen Wilson67d9f7e2011-03-30 15:55:52 +000086 m_module(NULL),
87 m_in_limbo(false),
88 m_exit_now(false)
Stephen Wilsonf6f40332010-07-24 02:19:04 +000089{
90 // FIXME: Putting this code in the ctor and saving the byte order in a
91 // member variable is a hack to avoid const qual issues in GetByteOrder.
92 ObjectFile *obj_file = GetTarget().GetExecutableModule()->GetObjectFile();
93 m_byte_order = obj_file->GetByteOrder();
94}
95
96ProcessLinux::~ProcessLinux()
97{
98 delete m_monitor;
99}
100
101//------------------------------------------------------------------------------
102// Process protocol.
103
104bool
Peter Collingbourne47556982011-07-22 19:12:53 +0000105ProcessLinux::CanDebug(Target &target, bool plugin_specified_by_name)
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000106{
107 // For now we are just making sure the file exists for a given module
108 ModuleSP exe_module_sp(target.GetExecutableModule());
109 if (exe_module_sp.get())
110 return exe_module_sp->GetFileSpec().Exists();
111 return false;
112}
113
114Error
115ProcessLinux::DoAttachToProcessWithID(lldb::pid_t pid)
116{
Johnny Chen9bab8d42011-06-14 19:19:50 +0000117 Error error;
118 assert(m_monitor == NULL);
119
Johnny Chenac51e9f2011-10-11 21:21:57 +0000120 LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_PROCESS));
121 if (log && log->GetMask().Test(LINUX_LOG_VERBOSE))
122 log->Printf ("ProcessLinux::%s (pid = %i)", __FUNCTION__, GetID());
123
Johnny Chen9bab8d42011-06-14 19:19:50 +0000124 m_monitor = new ProcessMonitor(this, pid, error);
125
126 if (!error.Success())
127 return error;
128
129 SetID(pid);
130 return error;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000131}
132
133Error
Stephen Wilson92241ef2011-01-16 19:45:39 +0000134ProcessLinux::WillLaunch(Module* module)
135{
136 Error error;
Stephen Wilson92241ef2011-01-16 19:45:39 +0000137 return error;
138}
139
140Error
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000141ProcessLinux::DoLaunch(Module *module,
142 char const *argv[],
143 char const *envp[],
Stephen Wilson3a804312011-01-04 21:41:31 +0000144 uint32_t launch_flags,
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000145 const char *stdin_path,
146 const char *stdout_path,
Greg Claytonde915be2011-01-23 05:56:20 +0000147 const char *stderr_path,
148 const char *working_directory)
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000149{
150 Error error;
151 assert(m_monitor == NULL);
152
153 SetPrivateState(eStateLaunching);
154 m_monitor = new ProcessMonitor(this, module,
155 argv, envp,
156 stdin_path, stdout_path, stderr_path,
157 error);
158
159 m_module = module;
160
161 if (!error.Success())
162 return error;
163
Stephen Wilson1f004c62011-01-15 00:13:27 +0000164 SetID(m_monitor->GetPID());
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000165 return error;
166}
167
Stephen Wilson92241ef2011-01-16 19:45:39 +0000168void
169ProcessLinux::DidLaunch()
170{
Stephen Wilson92241ef2011-01-16 19:45:39 +0000171}
172
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000173Error
174ProcessLinux::DoResume()
175{
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000176 StateType state = GetPrivateState();
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000177
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000178 assert(state == eStateStopped || state == eStateCrashed);
179
180 // We are about to resume a thread that will cause the process to exit so
181 // set our exit status now. Do not change our state if the inferior
182 // crashed.
183 if (state == eStateStopped)
184 {
185 if (m_in_limbo)
186 SetExitStatus(m_exit_status, NULL);
187 else
188 SetPrivateState(eStateRunning);
189 }
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000190
191 bool did_resume = false;
192 uint32_t thread_count = m_thread_list.GetSize(false);
193 for (uint32_t i = 0; i < thread_count; ++i)
194 {
195 LinuxThread *thread = static_cast<LinuxThread*>(
196 m_thread_list.GetThreadAtIndex(i, false).get());
197 did_resume = thread->Resume() || did_resume;
198 }
199 assert(did_resume && "Process resume failed!");
200
201 return Error();
202}
203
Stephen Wilson01316422011-01-15 00:10:37 +0000204addr_t
205ProcessLinux::GetImageInfoAddress()
206{
207 Target *target = &GetTarget();
208 ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
209 Address addr = obj_file->GetImageInfoAddress();
210
211 if (addr.IsValid())
212 return addr.GetLoadAddress(target);
213 else
214 return LLDB_INVALID_ADDRESS;
215}
216
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000217Error
Stephen Wilson3a804312011-01-04 21:41:31 +0000218ProcessLinux::DoHalt(bool &caused_stop)
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000219{
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000220 Error error;
221
222 if (IsStopped())
223 {
224 caused_stop = false;
225 }
226 else if (kill(GetID(), SIGSTOP))
227 {
228 caused_stop = false;
229 error.SetErrorToErrno();
230 }
231 else
232 {
233 caused_stop = true;
234 }
235
236 return error;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000237}
238
239Error
240ProcessLinux::DoDetach()
241{
242 return Error(1, eErrorTypeGeneric);
243}
244
245Error
246ProcessLinux::DoSignal(int signal)
247{
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000248 Error error;
249
250 if (kill(GetID(), signal))
251 error.SetErrorToErrno();
252
253 return error;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000254}
255
256Error
257ProcessLinux::DoDestroy()
258{
259 Error error;
260
261 if (!HasExited())
262 {
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000263 // Drive the exit event to completion (do not keep the inferior in
264 // limbo).
265 m_exit_now = true;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000266
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000267 if (kill(m_monitor->GetPID(), SIGKILL) && error.Success())
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000268 {
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000269 error.SetErrorToErrno();
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000270 return error;
271 }
272
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000273 SetPrivateState(eStateExited);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000274 }
275
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000276 return error;
277}
278
279void
280ProcessLinux::SendMessage(const ProcessMessage &message)
281{
282 Mutex::Locker lock(m_message_mutex);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000283
284 switch (message.GetKind())
285 {
286 default:
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000287 assert(false && "Unexpected process message!");
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000288 break;
289
Stephen Wilson07fc7a92011-01-19 01:29:39 +0000290 case ProcessMessage::eInvalidMessage:
291 return;
292
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000293 case ProcessMessage::eLimboMessage:
294 m_in_limbo = true;
295 m_exit_status = message.GetExitStatus();
296 if (m_exit_now)
297 {
298 SetPrivateState(eStateExited);
299 m_monitor->Detach();
300 }
301 else
302 SetPrivateState(eStateStopped);
303 break;
304
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000305 case ProcessMessage::eExitMessage:
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000306 m_exit_status = message.GetExitStatus();
307 SetExitStatus(m_exit_status, NULL);
308 break;
309
310 case ProcessMessage::eTraceMessage:
311 case ProcessMessage::eBreakpointMessage:
312 SetPrivateState(eStateStopped);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000313 break;
314
315 case ProcessMessage::eSignalMessage:
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000316 case ProcessMessage::eSignalDeliveredMessage:
317 SetPrivateState(eStateStopped);
318 break;
319
320 case ProcessMessage::eCrashMessage:
321 SetPrivateState(eStateCrashed);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000322 break;
323 }
Stephen Wilson07fc7a92011-01-19 01:29:39 +0000324
325 m_message_queue.push(message);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000326}
327
328void
329ProcessLinux::RefreshStateAfterStop()
330{
331 Mutex::Locker lock(m_message_mutex);
332 if (m_message_queue.empty())
333 return;
334
335 ProcessMessage &message = m_message_queue.front();
336
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000337 // Resolve the thread this message corresponds to and pass it along.
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000338 lldb::tid_t tid = message.GetTID();
339 LinuxThread *thread = static_cast<LinuxThread*>(
340 GetThreadList().FindThreadByID(tid, false).get());
341
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000342 thread->Notify(message);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000343
344 m_message_queue.pop();
345}
346
347bool
348ProcessLinux::IsAlive()
349{
350 StateType state = GetPrivateState();
351 return state != eStateExited && state != eStateInvalid;
352}
353
354size_t
355ProcessLinux::DoReadMemory(addr_t vm_addr,
356 void *buf, size_t size, Error &error)
357{
358 return m_monitor->ReadMemory(vm_addr, buf, size, error);
359}
360
361size_t
362ProcessLinux::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
363 Error &error)
364{
365 return m_monitor->WriteMemory(vm_addr, buf, size, error);
366}
367
368addr_t
369ProcessLinux::DoAllocateMemory(size_t size, uint32_t permissions,
370 Error &error)
371{
Peter Collingbournead115462011-06-03 20:40:44 +0000372 addr_t allocated_addr = LLDB_INVALID_ADDRESS;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000373
Peter Collingbournead115462011-06-03 20:40:44 +0000374 unsigned prot = 0;
375 if (permissions & lldb::ePermissionsReadable)
376 prot |= eMmapProtRead;
377 if (permissions & lldb::ePermissionsWritable)
378 prot |= eMmapProtWrite;
379 if (permissions & lldb::ePermissionsExecutable)
380 prot |= eMmapProtExec;
381
382 if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
383 eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
384 m_addr_to_mmap_size[allocated_addr] = size;
385 error.Clear();
386 } else {
387 allocated_addr = LLDB_INVALID_ADDRESS;
388 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
389 }
390
391 return allocated_addr;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000392}
393
394Error
Peter Collingbournead115462011-06-03 20:40:44 +0000395ProcessLinux::DoDeallocateMemory(lldb::addr_t addr)
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000396{
Peter Collingbournead115462011-06-03 20:40:44 +0000397 Error error;
398 MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
399 if (pos != m_addr_to_mmap_size.end() &&
400 InferiorCallMunmap(this, addr, pos->second))
401 m_addr_to_mmap_size.erase (pos);
402 else
403 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr);
404
405 return error;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000406}
407
408size_t
409ProcessLinux::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
410{
411 static const uint8_t g_i386_opcode[] = { 0xCC };
412
413 ArchSpec arch = GetTarget().GetArchitecture();
414 const uint8_t *opcode = NULL;
415 size_t opcode_size = 0;
416
Stephen Wilsona1f0b722011-02-24 19:17:09 +0000417 switch (arch.GetCore())
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000418 {
419 default:
420 assert(false && "CPU type not supported!");
421 break;
422
Stephen Wilsona1f0b722011-02-24 19:17:09 +0000423 case ArchSpec::eCore_x86_32_i386:
424 case ArchSpec::eCore_x86_64_x86_64:
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000425 opcode = g_i386_opcode;
426 opcode_size = sizeof(g_i386_opcode);
427 break;
428 }
429
430 bp_site->SetTrapOpcode(opcode, opcode_size);
431 return opcode_size;
432}
433
434Error
435ProcessLinux::EnableBreakpoint(BreakpointSite *bp_site)
436{
437 return EnableSoftwareBreakpoint(bp_site);
438}
439
440Error
441ProcessLinux::DisableBreakpoint(BreakpointSite *bp_site)
442{
443 return DisableSoftwareBreakpoint(bp_site);
444}
445
446uint32_t
447ProcessLinux::UpdateThreadListIfNeeded()
448{
449 // Do not allow recursive updates.
450 return m_thread_list.GetSize(false);
451}
452
Johnny Chenb8f74aa2011-10-10 23:11:50 +0000453uint32_t
454ProcessLinux::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
455{
456 // FIXME: Should this be implemented?
Johnny Chenac51e9f2011-10-11 21:21:57 +0000457 LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD));
458 if (log && log->GetMask().Test(LINUX_LOG_VERBOSE))
459 log->Printf ("ProcessLinux::%s (pid = %i)", __FUNCTION__, GetID());
460
Johnny Chenb8f74aa2011-10-10 23:11:50 +0000461 return 0;
462}
463
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000464ByteOrder
465ProcessLinux::GetByteOrder() const
466{
467 // FIXME: We should be able to extract this value directly. See comment in
468 // ProcessLinux().
469 return m_byte_order;
470}
471
Stephen Wilsond1fbbb42011-03-23 02:14:42 +0000472size_t
473ProcessLinux::PutSTDIN(const char *buf, size_t len, Error &error)
474{
475 ssize_t status;
476 if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
477 {
478 error.SetErrorToErrno();
479 return 0;
480 }
481 return status;
482}
483
484size_t
485ProcessLinux::GetSTDOUT(char *buf, size_t len, Error &error)
486{
487 ssize_t bytes_read;
488
489 // The terminal file descriptor is always in non-block mode.
490 if ((bytes_read = read(m_monitor->GetTerminalFD(), buf, len)) < 0)
491 {
492 if (errno != EAGAIN)
493 error.SetErrorToErrno();
494 return 0;
495 }
496 return bytes_read;
497}
498
499size_t
500ProcessLinux::GetSTDERR(char *buf, size_t len, Error &error)
501{
502 return GetSTDOUT(buf, len, error);
503}
504
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000505UnixSignals &
506ProcessLinux::GetUnixSignals()
507{
508 return m_linux_signals;
509}
Stephen Wilsond1fbbb42011-03-23 02:14:42 +0000510
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000511//------------------------------------------------------------------------------
512// ProcessInterface protocol.
513
514const char *
515ProcessLinux::GetPluginName()
516{
517 return "process.linux";
518}
519
520const char *
521ProcessLinux::GetShortPluginName()
522{
523 return "process.linux";
524}
525
526uint32_t
527ProcessLinux::GetPluginVersion()
528{
529 return 1;
530}
531
532void
533ProcessLinux::GetPluginCommandHelp(const char *command, Stream *strm)
534{
535}
536
537Error
538ProcessLinux::ExecutePluginCommand(Args &command, Stream *strm)
539{
540 return Error(1, eErrorTypeGeneric);
541}
542
543Log *
544ProcessLinux::EnablePluginLogging(Stream *strm, Args &command)
545{
546 return NULL;
547}
548
549//------------------------------------------------------------------------------
550// Utility functions.
551
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000552bool
553ProcessLinux::HasExited()
554{
555 switch (GetPrivateState())
556 {
557 default:
558 break;
559
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000560 case eStateDetached:
561 case eStateExited:
562 return true;
563 }
564
565 return false;
566}
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000567
568bool
569ProcessLinux::IsStopped()
570{
571 switch (GetPrivateState())
572 {
573 default:
574 break;
575
576 case eStateStopped:
577 case eStateCrashed:
578 case eStateSuspended:
579 return true;
580 }
581
582 return false;
583}