blob: c4ce8eeb0b3853aa6124bad54f1da265c47846e5 [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{
108 return Error(1, eErrorTypeGeneric);
109}
110
111Error
Stephen Wilson92241ef2011-01-16 19:45:39 +0000112ProcessLinux::WillLaunch(Module* module)
113{
114 Error error;
Stephen Wilson92241ef2011-01-16 19:45:39 +0000115 return error;
116}
117
118Error
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000119ProcessLinux::DoLaunch(Module *module,
120 char const *argv[],
121 char const *envp[],
Stephen Wilson3a804312011-01-04 21:41:31 +0000122 uint32_t launch_flags,
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000123 const char *stdin_path,
124 const char *stdout_path,
Greg Claytonde915be2011-01-23 05:56:20 +0000125 const char *stderr_path,
126 const char *working_directory)
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000127{
128 Error error;
129 assert(m_monitor == NULL);
130
131 SetPrivateState(eStateLaunching);
132 m_monitor = new ProcessMonitor(this, module,
133 argv, envp,
134 stdin_path, stdout_path, stderr_path,
135 error);
136
137 m_module = module;
138
139 if (!error.Success())
140 return error;
141
Stephen Wilson1f004c62011-01-15 00:13:27 +0000142 SetID(m_monitor->GetPID());
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000143 return error;
144}
145
Stephen Wilson92241ef2011-01-16 19:45:39 +0000146void
147ProcessLinux::DidLaunch()
148{
Stephen Wilson92241ef2011-01-16 19:45:39 +0000149}
150
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000151Error
152ProcessLinux::DoResume()
153{
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000154 StateType state = GetPrivateState();
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000155
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000156 assert(state == eStateStopped || state == eStateCrashed);
157
158 // We are about to resume a thread that will cause the process to exit so
159 // set our exit status now. Do not change our state if the inferior
160 // crashed.
161 if (state == eStateStopped)
162 {
163 if (m_in_limbo)
164 SetExitStatus(m_exit_status, NULL);
165 else
166 SetPrivateState(eStateRunning);
167 }
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000168
169 bool did_resume = false;
170 uint32_t thread_count = m_thread_list.GetSize(false);
171 for (uint32_t i = 0; i < thread_count; ++i)
172 {
173 LinuxThread *thread = static_cast<LinuxThread*>(
174 m_thread_list.GetThreadAtIndex(i, false).get());
175 did_resume = thread->Resume() || did_resume;
176 }
177 assert(did_resume && "Process resume failed!");
178
179 return Error();
180}
181
Stephen Wilson01316422011-01-15 00:10:37 +0000182addr_t
183ProcessLinux::GetImageInfoAddress()
184{
185 Target *target = &GetTarget();
186 ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
187 Address addr = obj_file->GetImageInfoAddress();
188
189 if (addr.IsValid())
190 return addr.GetLoadAddress(target);
191 else
192 return LLDB_INVALID_ADDRESS;
193}
194
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000195Error
Stephen Wilson3a804312011-01-04 21:41:31 +0000196ProcessLinux::DoHalt(bool &caused_stop)
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000197{
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000198 Error error;
199
200 if (IsStopped())
201 {
202 caused_stop = false;
203 }
204 else if (kill(GetID(), SIGSTOP))
205 {
206 caused_stop = false;
207 error.SetErrorToErrno();
208 }
209 else
210 {
211 caused_stop = true;
212 }
213
214 return error;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000215}
216
217Error
218ProcessLinux::DoDetach()
219{
220 return Error(1, eErrorTypeGeneric);
221}
222
223Error
224ProcessLinux::DoSignal(int signal)
225{
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000226 Error error;
227
228 if (kill(GetID(), signal))
229 error.SetErrorToErrno();
230
231 return error;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000232}
233
234Error
235ProcessLinux::DoDestroy()
236{
237 Error error;
238
239 if (!HasExited())
240 {
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000241 // Drive the exit event to completion (do not keep the inferior in
242 // limbo).
243 m_exit_now = true;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000244
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000245 if (kill(m_monitor->GetPID(), SIGKILL) && error.Success())
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000246 {
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000247 error.SetErrorToErrno();
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000248 return error;
249 }
250
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000251 SetPrivateState(eStateExited);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000252 }
253
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000254 return error;
255}
256
257void
258ProcessLinux::SendMessage(const ProcessMessage &message)
259{
260 Mutex::Locker lock(m_message_mutex);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000261
262 switch (message.GetKind())
263 {
264 default:
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000265 assert(false && "Unexpected process message!");
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000266 break;
267
Stephen Wilson07fc7a92011-01-19 01:29:39 +0000268 case ProcessMessage::eInvalidMessage:
269 return;
270
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000271 case ProcessMessage::eLimboMessage:
272 m_in_limbo = true;
273 m_exit_status = message.GetExitStatus();
274 if (m_exit_now)
275 {
276 SetPrivateState(eStateExited);
277 m_monitor->Detach();
278 }
279 else
280 SetPrivateState(eStateStopped);
281 break;
282
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000283 case ProcessMessage::eExitMessage:
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000284 m_exit_status = message.GetExitStatus();
285 SetExitStatus(m_exit_status, NULL);
286 break;
287
288 case ProcessMessage::eTraceMessage:
289 case ProcessMessage::eBreakpointMessage:
290 SetPrivateState(eStateStopped);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000291 break;
292
293 case ProcessMessage::eSignalMessage:
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000294 case ProcessMessage::eSignalDeliveredMessage:
295 SetPrivateState(eStateStopped);
296 break;
297
298 case ProcessMessage::eCrashMessage:
299 SetPrivateState(eStateCrashed);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000300 break;
301 }
Stephen Wilson07fc7a92011-01-19 01:29:39 +0000302
303 m_message_queue.push(message);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000304}
305
306void
307ProcessLinux::RefreshStateAfterStop()
308{
309 Mutex::Locker lock(m_message_mutex);
310 if (m_message_queue.empty())
311 return;
312
313 ProcessMessage &message = m_message_queue.front();
314
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000315 // Resolve the thread this message corresponds to and pass it along.
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000316 lldb::tid_t tid = message.GetTID();
317 LinuxThread *thread = static_cast<LinuxThread*>(
318 GetThreadList().FindThreadByID(tid, false).get());
319
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000320 thread->Notify(message);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000321
322 m_message_queue.pop();
323}
324
325bool
326ProcessLinux::IsAlive()
327{
328 StateType state = GetPrivateState();
329 return state != eStateExited && state != eStateInvalid;
330}
331
332size_t
333ProcessLinux::DoReadMemory(addr_t vm_addr,
334 void *buf, size_t size, Error &error)
335{
336 return m_monitor->ReadMemory(vm_addr, buf, size, error);
337}
338
339size_t
340ProcessLinux::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
341 Error &error)
342{
343 return m_monitor->WriteMemory(vm_addr, buf, size, error);
344}
345
346addr_t
347ProcessLinux::DoAllocateMemory(size_t size, uint32_t permissions,
348 Error &error)
349{
Peter Collingbournead115462011-06-03 20:40:44 +0000350 addr_t allocated_addr = LLDB_INVALID_ADDRESS;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000351
Peter Collingbournead115462011-06-03 20:40:44 +0000352 unsigned prot = 0;
353 if (permissions & lldb::ePermissionsReadable)
354 prot |= eMmapProtRead;
355 if (permissions & lldb::ePermissionsWritable)
356 prot |= eMmapProtWrite;
357 if (permissions & lldb::ePermissionsExecutable)
358 prot |= eMmapProtExec;
359
360 if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
361 eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
362 m_addr_to_mmap_size[allocated_addr] = size;
363 error.Clear();
364 } else {
365 allocated_addr = LLDB_INVALID_ADDRESS;
366 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
367 }
368
369 return allocated_addr;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000370}
371
372Error
Peter Collingbournead115462011-06-03 20:40:44 +0000373ProcessLinux::DoDeallocateMemory(lldb::addr_t addr)
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000374{
Peter Collingbournead115462011-06-03 20:40:44 +0000375 Error error;
376 MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
377 if (pos != m_addr_to_mmap_size.end() &&
378 InferiorCallMunmap(this, addr, pos->second))
379 m_addr_to_mmap_size.erase (pos);
380 else
381 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr);
382
383 return error;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000384}
385
386size_t
387ProcessLinux::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
388{
389 static const uint8_t g_i386_opcode[] = { 0xCC };
390
391 ArchSpec arch = GetTarget().GetArchitecture();
392 const uint8_t *opcode = NULL;
393 size_t opcode_size = 0;
394
Stephen Wilsona1f0b722011-02-24 19:17:09 +0000395 switch (arch.GetCore())
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000396 {
397 default:
398 assert(false && "CPU type not supported!");
399 break;
400
Stephen Wilsona1f0b722011-02-24 19:17:09 +0000401 case ArchSpec::eCore_x86_32_i386:
402 case ArchSpec::eCore_x86_64_x86_64:
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000403 opcode = g_i386_opcode;
404 opcode_size = sizeof(g_i386_opcode);
405 break;
406 }
407
408 bp_site->SetTrapOpcode(opcode, opcode_size);
409 return opcode_size;
410}
411
412Error
413ProcessLinux::EnableBreakpoint(BreakpointSite *bp_site)
414{
415 return EnableSoftwareBreakpoint(bp_site);
416}
417
418Error
419ProcessLinux::DisableBreakpoint(BreakpointSite *bp_site)
420{
421 return DisableSoftwareBreakpoint(bp_site);
422}
423
424uint32_t
425ProcessLinux::UpdateThreadListIfNeeded()
426{
427 // Do not allow recursive updates.
428 return m_thread_list.GetSize(false);
429}
430
431ByteOrder
432ProcessLinux::GetByteOrder() const
433{
434 // FIXME: We should be able to extract this value directly. See comment in
435 // ProcessLinux().
436 return m_byte_order;
437}
438
Stephen Wilsond1fbbb42011-03-23 02:14:42 +0000439size_t
440ProcessLinux::PutSTDIN(const char *buf, size_t len, Error &error)
441{
442 ssize_t status;
443 if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
444 {
445 error.SetErrorToErrno();
446 return 0;
447 }
448 return status;
449}
450
451size_t
452ProcessLinux::GetSTDOUT(char *buf, size_t len, Error &error)
453{
454 ssize_t bytes_read;
455
456 // The terminal file descriptor is always in non-block mode.
457 if ((bytes_read = read(m_monitor->GetTerminalFD(), buf, len)) < 0)
458 {
459 if (errno != EAGAIN)
460 error.SetErrorToErrno();
461 return 0;
462 }
463 return bytes_read;
464}
465
466size_t
467ProcessLinux::GetSTDERR(char *buf, size_t len, Error &error)
468{
469 return GetSTDOUT(buf, len, error);
470}
471
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000472UnixSignals &
473ProcessLinux::GetUnixSignals()
474{
475 return m_linux_signals;
476}
Stephen Wilsond1fbbb42011-03-23 02:14:42 +0000477
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000478//------------------------------------------------------------------------------
479// ProcessInterface protocol.
480
481const char *
482ProcessLinux::GetPluginName()
483{
484 return "process.linux";
485}
486
487const char *
488ProcessLinux::GetShortPluginName()
489{
490 return "process.linux";
491}
492
493uint32_t
494ProcessLinux::GetPluginVersion()
495{
496 return 1;
497}
498
499void
500ProcessLinux::GetPluginCommandHelp(const char *command, Stream *strm)
501{
502}
503
504Error
505ProcessLinux::ExecutePluginCommand(Args &command, Stream *strm)
506{
507 return Error(1, eErrorTypeGeneric);
508}
509
510Log *
511ProcessLinux::EnablePluginLogging(Stream *strm, Args &command)
512{
513 return NULL;
514}
515
516//------------------------------------------------------------------------------
517// Utility functions.
518
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000519bool
520ProcessLinux::HasExited()
521{
522 switch (GetPrivateState())
523 {
524 default:
525 break;
526
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000527 case eStateDetached:
528 case eStateExited:
529 return true;
530 }
531
532 return false;
533}
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000534
535bool
536ProcessLinux::IsStopped()
537{
538 switch (GetPrivateState())
539 {
540 default:
541 break;
542
543 case eStateStopped:
544 case eStateCrashed:
545 case eStateSuspended:
546 return true;
547 }
548
549 return false;
550}