blob: e6940fe70391b74989bb10a83603740ca2578871 [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"
Peter Collingbournead115462011-06-03 20:40:44 +000023#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
Stephen Wilsonf6f40332010-07-24 02:19:04 +000024#include "ProcessMonitor.h"
25#include "LinuxThread.h"
26
27using namespace lldb;
28using namespace lldb_private;
29
30//------------------------------------------------------------------------------
31// Static functions.
32
33Process*
34ProcessLinux::CreateInstance(Target& target, Listener &listener)
35{
36 return new ProcessLinux(target, listener);
37}
38
39void
40ProcessLinux::Initialize()
41{
42 static bool g_initialized = false;
43
44 if (!g_initialized)
45 {
46 PluginManager::RegisterPlugin(GetPluginNameStatic(),
47 GetPluginDescriptionStatic(),
48 CreateInstance);
49 g_initialized = true;
50 }
51}
52
53void
54ProcessLinux::Terminate()
55{
56}
57
58const char *
59ProcessLinux::GetPluginNameStatic()
60{
61 return "plugin.process.linux";
62}
63
64const char *
65ProcessLinux::GetPluginDescriptionStatic()
66{
67 return "Process plugin for Linux";
68}
69
70
71//------------------------------------------------------------------------------
72// Constructors and destructors.
73
74ProcessLinux::ProcessLinux(Target& target, Listener &listener)
75 : Process(target, listener),
76 m_monitor(NULL),
Stephen Wilson67d9f7e2011-03-30 15:55:52 +000077 m_module(NULL),
78 m_in_limbo(false),
79 m_exit_now(false)
Stephen Wilsonf6f40332010-07-24 02:19:04 +000080{
81 // 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();
85}
86
87ProcessLinux::~ProcessLinux()
88{
89 delete m_monitor;
90}
91
92//------------------------------------------------------------------------------
93// Process protocol.
94
95bool
96ProcessLinux::CanDebug(Target &target)
97{
98 // For now we are just making sure the file exists for a given module
99 ModuleSP exe_module_sp(target.GetExecutableModule());
100 if (exe_module_sp.get())
101 return exe_module_sp->GetFileSpec().Exists();
102 return false;
103}
104
105Error
106ProcessLinux::DoAttachToProcessWithID(lldb::pid_t pid)
107{
Johnny Chen9bab8d42011-06-14 19:19:50 +0000108 Error error;
109 assert(m_monitor == NULL);
110
111 m_monitor = new ProcessMonitor(this, pid, error);
112
113 if (!error.Success())
114 return error;
115
116 SetID(pid);
117 return error;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000118}
119
120Error
Stephen Wilson92241ef2011-01-16 19:45:39 +0000121ProcessLinux::WillLaunch(Module* module)
122{
123 Error error;
Stephen Wilson92241ef2011-01-16 19:45:39 +0000124 return error;
125}
126
127Error
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000128ProcessLinux::DoLaunch(Module *module,
129 char const *argv[],
130 char const *envp[],
Stephen Wilson3a804312011-01-04 21:41:31 +0000131 uint32_t launch_flags,
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000132 const char *stdin_path,
133 const char *stdout_path,
Greg Claytonde915be2011-01-23 05:56:20 +0000134 const char *stderr_path,
135 const char *working_directory)
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000136{
137 Error error;
138 assert(m_monitor == NULL);
139
140 SetPrivateState(eStateLaunching);
141 m_monitor = new ProcessMonitor(this, module,
142 argv, envp,
143 stdin_path, stdout_path, stderr_path,
144 error);
145
146 m_module = module;
147
148 if (!error.Success())
149 return error;
150
Stephen Wilson1f004c62011-01-15 00:13:27 +0000151 SetID(m_monitor->GetPID());
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000152 return error;
153}
154
Stephen Wilson92241ef2011-01-16 19:45:39 +0000155void
156ProcessLinux::DidLaunch()
157{
Stephen Wilson92241ef2011-01-16 19:45:39 +0000158}
159
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000160Error
161ProcessLinux::DoResume()
162{
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000163 StateType state = GetPrivateState();
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000164
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000165 assert(state == eStateStopped || state == eStateCrashed);
166
167 // We are about to resume a thread that will cause the process to exit so
168 // set our exit status now. Do not change our state if the inferior
169 // crashed.
170 if (state == eStateStopped)
171 {
172 if (m_in_limbo)
173 SetExitStatus(m_exit_status, NULL);
174 else
175 SetPrivateState(eStateRunning);
176 }
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000177
178 bool did_resume = false;
179 uint32_t thread_count = m_thread_list.GetSize(false);
180 for (uint32_t i = 0; i < thread_count; ++i)
181 {
182 LinuxThread *thread = static_cast<LinuxThread*>(
183 m_thread_list.GetThreadAtIndex(i, false).get());
184 did_resume = thread->Resume() || did_resume;
185 }
186 assert(did_resume && "Process resume failed!");
187
188 return Error();
189}
190
Stephen Wilson01316422011-01-15 00:10:37 +0000191addr_t
192ProcessLinux::GetImageInfoAddress()
193{
194 Target *target = &GetTarget();
195 ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
196 Address addr = obj_file->GetImageInfoAddress();
197
198 if (addr.IsValid())
199 return addr.GetLoadAddress(target);
200 else
201 return LLDB_INVALID_ADDRESS;
202}
203
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000204Error
Stephen Wilson3a804312011-01-04 21:41:31 +0000205ProcessLinux::DoHalt(bool &caused_stop)
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000206{
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000207 Error error;
208
209 if (IsStopped())
210 {
211 caused_stop = false;
212 }
213 else if (kill(GetID(), SIGSTOP))
214 {
215 caused_stop = false;
216 error.SetErrorToErrno();
217 }
218 else
219 {
220 caused_stop = true;
221 }
222
223 return error;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000224}
225
226Error
227ProcessLinux::DoDetach()
228{
229 return Error(1, eErrorTypeGeneric);
230}
231
232Error
233ProcessLinux::DoSignal(int signal)
234{
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000235 Error error;
236
237 if (kill(GetID(), signal))
238 error.SetErrorToErrno();
239
240 return error;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000241}
242
243Error
244ProcessLinux::DoDestroy()
245{
246 Error error;
247
248 if (!HasExited())
249 {
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000250 // Drive the exit event to completion (do not keep the inferior in
251 // limbo).
252 m_exit_now = true;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000253
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000254 if (kill(m_monitor->GetPID(), SIGKILL) && error.Success())
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000255 {
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000256 error.SetErrorToErrno();
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000257 return error;
258 }
259
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000260 SetPrivateState(eStateExited);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000261 }
262
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000263 return error;
264}
265
266void
267ProcessLinux::SendMessage(const ProcessMessage &message)
268{
269 Mutex::Locker lock(m_message_mutex);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000270
271 switch (message.GetKind())
272 {
273 default:
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000274 assert(false && "Unexpected process message!");
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000275 break;
276
Stephen Wilson07fc7a92011-01-19 01:29:39 +0000277 case ProcessMessage::eInvalidMessage:
278 return;
279
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000280 case ProcessMessage::eLimboMessage:
281 m_in_limbo = true;
282 m_exit_status = message.GetExitStatus();
283 if (m_exit_now)
284 {
285 SetPrivateState(eStateExited);
286 m_monitor->Detach();
287 }
288 else
289 SetPrivateState(eStateStopped);
290 break;
291
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000292 case ProcessMessage::eExitMessage:
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000293 m_exit_status = message.GetExitStatus();
294 SetExitStatus(m_exit_status, NULL);
295 break;
296
297 case ProcessMessage::eTraceMessage:
298 case ProcessMessage::eBreakpointMessage:
299 SetPrivateState(eStateStopped);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000300 break;
301
302 case ProcessMessage::eSignalMessage:
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000303 case ProcessMessage::eSignalDeliveredMessage:
304 SetPrivateState(eStateStopped);
305 break;
306
307 case ProcessMessage::eCrashMessage:
308 SetPrivateState(eStateCrashed);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000309 break;
310 }
Stephen Wilson07fc7a92011-01-19 01:29:39 +0000311
312 m_message_queue.push(message);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000313}
314
315void
316ProcessLinux::RefreshStateAfterStop()
317{
318 Mutex::Locker lock(m_message_mutex);
319 if (m_message_queue.empty())
320 return;
321
322 ProcessMessage &message = m_message_queue.front();
323
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000324 // Resolve the thread this message corresponds to and pass it along.
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000325 lldb::tid_t tid = message.GetTID();
326 LinuxThread *thread = static_cast<LinuxThread*>(
327 GetThreadList().FindThreadByID(tid, false).get());
328
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000329 thread->Notify(message);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000330
331 m_message_queue.pop();
332}
333
334bool
335ProcessLinux::IsAlive()
336{
337 StateType state = GetPrivateState();
338 return state != eStateExited && state != eStateInvalid;
339}
340
341size_t
342ProcessLinux::DoReadMemory(addr_t vm_addr,
343 void *buf, size_t size, Error &error)
344{
345 return m_monitor->ReadMemory(vm_addr, buf, size, error);
346}
347
348size_t
349ProcessLinux::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
350 Error &error)
351{
352 return m_monitor->WriteMemory(vm_addr, buf, size, error);
353}
354
355addr_t
356ProcessLinux::DoAllocateMemory(size_t size, uint32_t permissions,
357 Error &error)
358{
Peter Collingbournead115462011-06-03 20:40:44 +0000359 addr_t allocated_addr = LLDB_INVALID_ADDRESS;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000360
Peter Collingbournead115462011-06-03 20:40:44 +0000361 unsigned prot = 0;
362 if (permissions & lldb::ePermissionsReadable)
363 prot |= eMmapProtRead;
364 if (permissions & lldb::ePermissionsWritable)
365 prot |= eMmapProtWrite;
366 if (permissions & lldb::ePermissionsExecutable)
367 prot |= eMmapProtExec;
368
369 if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
370 eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
371 m_addr_to_mmap_size[allocated_addr] = size;
372 error.Clear();
373 } else {
374 allocated_addr = LLDB_INVALID_ADDRESS;
375 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
376 }
377
378 return allocated_addr;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000379}
380
381Error
Peter Collingbournead115462011-06-03 20:40:44 +0000382ProcessLinux::DoDeallocateMemory(lldb::addr_t addr)
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000383{
Peter Collingbournead115462011-06-03 20:40:44 +0000384 Error error;
385 MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
386 if (pos != m_addr_to_mmap_size.end() &&
387 InferiorCallMunmap(this, addr, pos->second))
388 m_addr_to_mmap_size.erase (pos);
389 else
390 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr);
391
392 return error;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000393}
394
395size_t
396ProcessLinux::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
397{
398 static const uint8_t g_i386_opcode[] = { 0xCC };
399
400 ArchSpec arch = GetTarget().GetArchitecture();
401 const uint8_t *opcode = NULL;
402 size_t opcode_size = 0;
403
Stephen Wilsona1f0b722011-02-24 19:17:09 +0000404 switch (arch.GetCore())
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000405 {
406 default:
407 assert(false && "CPU type not supported!");
408 break;
409
Stephen Wilsona1f0b722011-02-24 19:17:09 +0000410 case ArchSpec::eCore_x86_32_i386:
411 case ArchSpec::eCore_x86_64_x86_64:
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000412 opcode = g_i386_opcode;
413 opcode_size = sizeof(g_i386_opcode);
414 break;
415 }
416
417 bp_site->SetTrapOpcode(opcode, opcode_size);
418 return opcode_size;
419}
420
421Error
422ProcessLinux::EnableBreakpoint(BreakpointSite *bp_site)
423{
424 return EnableSoftwareBreakpoint(bp_site);
425}
426
427Error
428ProcessLinux::DisableBreakpoint(BreakpointSite *bp_site)
429{
430 return DisableSoftwareBreakpoint(bp_site);
431}
432
433uint32_t
434ProcessLinux::UpdateThreadListIfNeeded()
435{
436 // Do not allow recursive updates.
437 return m_thread_list.GetSize(false);
438}
439
440ByteOrder
441ProcessLinux::GetByteOrder() const
442{
443 // FIXME: We should be able to extract this value directly. See comment in
444 // ProcessLinux().
445 return m_byte_order;
446}
447
Stephen Wilsond1fbbb42011-03-23 02:14:42 +0000448size_t
449ProcessLinux::PutSTDIN(const char *buf, size_t len, Error &error)
450{
451 ssize_t status;
452 if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
453 {
454 error.SetErrorToErrno();
455 return 0;
456 }
457 return status;
458}
459
460size_t
461ProcessLinux::GetSTDOUT(char *buf, size_t len, Error &error)
462{
463 ssize_t bytes_read;
464
465 // The terminal file descriptor is always in non-block mode.
466 if ((bytes_read = read(m_monitor->GetTerminalFD(), buf, len)) < 0)
467 {
468 if (errno != EAGAIN)
469 error.SetErrorToErrno();
470 return 0;
471 }
472 return bytes_read;
473}
474
475size_t
476ProcessLinux::GetSTDERR(char *buf, size_t len, Error &error)
477{
478 return GetSTDOUT(buf, len, error);
479}
480
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000481UnixSignals &
482ProcessLinux::GetUnixSignals()
483{
484 return m_linux_signals;
485}
Stephen Wilsond1fbbb42011-03-23 02:14:42 +0000486
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000487//------------------------------------------------------------------------------
488// ProcessInterface protocol.
489
490const char *
491ProcessLinux::GetPluginName()
492{
493 return "process.linux";
494}
495
496const char *
497ProcessLinux::GetShortPluginName()
498{
499 return "process.linux";
500}
501
502uint32_t
503ProcessLinux::GetPluginVersion()
504{
505 return 1;
506}
507
508void
509ProcessLinux::GetPluginCommandHelp(const char *command, Stream *strm)
510{
511}
512
513Error
514ProcessLinux::ExecutePluginCommand(Args &command, Stream *strm)
515{
516 return Error(1, eErrorTypeGeneric);
517}
518
519Log *
520ProcessLinux::EnablePluginLogging(Stream *strm, Args &command)
521{
522 return NULL;
523}
524
525//------------------------------------------------------------------------------
526// Utility functions.
527
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000528bool
529ProcessLinux::HasExited()
530{
531 switch (GetPrivateState())
532 {
533 default:
534 break;
535
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000536 case eStateDetached:
537 case eStateExited:
538 return true;
539 }
540
541 return false;
542}
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000543
544bool
545ProcessLinux::IsStopped()
546{
547 switch (GetPrivateState())
548 {
549 default:
550 break;
551
552 case eStateStopped:
553 case eStateCrashed:
554 case eStateSuspended:
555 return true;
556 }
557
558 return false;
559}