blob: 323b863147246add66d7bcf620b90c543f1772ae [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))
Johnny Chen3bf3a9d2011-10-18 18:09:30 +0000122 log->Printf ("ProcessLinux::%s(pid = %i)", __FUNCTION__, GetID());
Johnny Chenac51e9f2011-10-11 21:21:57 +0000123
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{
Johnny Chen3bf3a9d2011-10-18 18:09:30 +0000331 LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_PROCESS));
332 if (log && log->GetMask().Test(LINUX_LOG_VERBOSE))
333 log->Printf ("ProcessLinux::%s()", __FUNCTION__);
334
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000335 Mutex::Locker lock(m_message_mutex);
336 if (m_message_queue.empty())
337 return;
338
339 ProcessMessage &message = m_message_queue.front();
340
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000341 // Resolve the thread this message corresponds to and pass it along.
Johnny Chen3bf3a9d2011-10-18 18:09:30 +0000342 // FIXME: we're really dealing with the pid here. This should get
343 // fixed when this code is fixed to handle multiple threads.
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000344 lldb::tid_t tid = message.GetTID();
Johnny Chen3bf3a9d2011-10-18 18:09:30 +0000345 if (log)
346 log->Printf ("ProcessLinux::%s() pid = %i", __FUNCTION__, tid);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000347 LinuxThread *thread = static_cast<LinuxThread*>(
348 GetThreadList().FindThreadByID(tid, false).get());
349
Johnny Chen3bf3a9d2011-10-18 18:09:30 +0000350 assert(thread);
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000351 thread->Notify(message);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000352
353 m_message_queue.pop();
354}
355
356bool
357ProcessLinux::IsAlive()
358{
359 StateType state = GetPrivateState();
360 return state != eStateExited && state != eStateInvalid;
361}
362
363size_t
364ProcessLinux::DoReadMemory(addr_t vm_addr,
365 void *buf, size_t size, Error &error)
366{
Johnny Chen3bf3a9d2011-10-18 18:09:30 +0000367 assert(m_monitor);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000368 return m_monitor->ReadMemory(vm_addr, buf, size, error);
369}
370
371size_t
372ProcessLinux::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
373 Error &error)
374{
Johnny Chen3bf3a9d2011-10-18 18:09:30 +0000375 assert(m_monitor);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000376 return m_monitor->WriteMemory(vm_addr, buf, size, error);
377}
378
379addr_t
380ProcessLinux::DoAllocateMemory(size_t size, uint32_t permissions,
381 Error &error)
382{
Peter Collingbournead115462011-06-03 20:40:44 +0000383 addr_t allocated_addr = LLDB_INVALID_ADDRESS;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000384
Peter Collingbournead115462011-06-03 20:40:44 +0000385 unsigned prot = 0;
386 if (permissions & lldb::ePermissionsReadable)
387 prot |= eMmapProtRead;
388 if (permissions & lldb::ePermissionsWritable)
389 prot |= eMmapProtWrite;
390 if (permissions & lldb::ePermissionsExecutable)
391 prot |= eMmapProtExec;
392
393 if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
394 eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
395 m_addr_to_mmap_size[allocated_addr] = size;
396 error.Clear();
397 } else {
398 allocated_addr = LLDB_INVALID_ADDRESS;
399 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
400 }
401
402 return allocated_addr;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000403}
404
405Error
Peter Collingbournead115462011-06-03 20:40:44 +0000406ProcessLinux::DoDeallocateMemory(lldb::addr_t addr)
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000407{
Peter Collingbournead115462011-06-03 20:40:44 +0000408 Error error;
409 MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
410 if (pos != m_addr_to_mmap_size.end() &&
411 InferiorCallMunmap(this, addr, pos->second))
412 m_addr_to_mmap_size.erase (pos);
413 else
414 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr);
415
416 return error;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000417}
418
419size_t
420ProcessLinux::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
421{
422 static const uint8_t g_i386_opcode[] = { 0xCC };
423
424 ArchSpec arch = GetTarget().GetArchitecture();
425 const uint8_t *opcode = NULL;
426 size_t opcode_size = 0;
427
Stephen Wilsona1f0b722011-02-24 19:17:09 +0000428 switch (arch.GetCore())
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000429 {
430 default:
431 assert(false && "CPU type not supported!");
432 break;
433
Stephen Wilsona1f0b722011-02-24 19:17:09 +0000434 case ArchSpec::eCore_x86_32_i386:
435 case ArchSpec::eCore_x86_64_x86_64:
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000436 opcode = g_i386_opcode;
437 opcode_size = sizeof(g_i386_opcode);
438 break;
439 }
440
441 bp_site->SetTrapOpcode(opcode, opcode_size);
442 return opcode_size;
443}
444
445Error
446ProcessLinux::EnableBreakpoint(BreakpointSite *bp_site)
447{
448 return EnableSoftwareBreakpoint(bp_site);
449}
450
451Error
452ProcessLinux::DisableBreakpoint(BreakpointSite *bp_site)
453{
454 return DisableSoftwareBreakpoint(bp_site);
455}
456
457uint32_t
458ProcessLinux::UpdateThreadListIfNeeded()
459{
460 // Do not allow recursive updates.
461 return m_thread_list.GetSize(false);
462}
463
Johnny Chenb8f74aa2011-10-10 23:11:50 +0000464uint32_t
465ProcessLinux::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
466{
Johnny Chenac51e9f2011-10-11 21:21:57 +0000467 LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD));
468 if (log && log->GetMask().Test(LINUX_LOG_VERBOSE))
Johnny Chen3bf3a9d2011-10-18 18:09:30 +0000469 log->Printf ("ProcessLinux::%s() (pid = %i)", __FUNCTION__, GetID());
Johnny Chenac51e9f2011-10-11 21:21:57 +0000470
Johnny Chen3bf3a9d2011-10-18 18:09:30 +0000471 // Update the process thread list with this new thread.
472 // FIXME: We should be using tid, not pid.
473 assert(m_monitor);
474 ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
475 if (!thread_sp)
476 thread_sp.reset(new LinuxThread(*this, GetID()));
477
478 if (log && log->GetMask().Test(LINUX_LOG_VERBOSE))
479 log->Printf ("ProcessLinux::%s() updated pid = %i", __FUNCTION__, GetID());
480 new_thread_list.AddThread(thread_sp);
481
482 return new_thread_list.GetSize(false);
Johnny Chenb8f74aa2011-10-10 23:11:50 +0000483}
484
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000485ByteOrder
486ProcessLinux::GetByteOrder() const
487{
488 // FIXME: We should be able to extract this value directly. See comment in
489 // ProcessLinux().
490 return m_byte_order;
491}
492
Stephen Wilsond1fbbb42011-03-23 02:14:42 +0000493size_t
494ProcessLinux::PutSTDIN(const char *buf, size_t len, Error &error)
495{
496 ssize_t status;
497 if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
498 {
499 error.SetErrorToErrno();
500 return 0;
501 }
502 return status;
503}
504
505size_t
506ProcessLinux::GetSTDOUT(char *buf, size_t len, Error &error)
507{
508 ssize_t bytes_read;
509
510 // The terminal file descriptor is always in non-block mode.
511 if ((bytes_read = read(m_monitor->GetTerminalFD(), buf, len)) < 0)
512 {
513 if (errno != EAGAIN)
514 error.SetErrorToErrno();
515 return 0;
516 }
517 return bytes_read;
518}
519
520size_t
521ProcessLinux::GetSTDERR(char *buf, size_t len, Error &error)
522{
523 return GetSTDOUT(buf, len, error);
524}
525
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000526UnixSignals &
527ProcessLinux::GetUnixSignals()
528{
529 return m_linux_signals;
530}
Stephen Wilsond1fbbb42011-03-23 02:14:42 +0000531
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000532//------------------------------------------------------------------------------
533// ProcessInterface protocol.
534
535const char *
536ProcessLinux::GetPluginName()
537{
538 return "process.linux";
539}
540
541const char *
542ProcessLinux::GetShortPluginName()
543{
544 return "process.linux";
545}
546
547uint32_t
548ProcessLinux::GetPluginVersion()
549{
550 return 1;
551}
552
553void
554ProcessLinux::GetPluginCommandHelp(const char *command, Stream *strm)
555{
556}
557
558Error
559ProcessLinux::ExecutePluginCommand(Args &command, Stream *strm)
560{
561 return Error(1, eErrorTypeGeneric);
562}
563
564Log *
565ProcessLinux::EnablePluginLogging(Stream *strm, Args &command)
566{
567 return NULL;
568}
569
570//------------------------------------------------------------------------------
571// Utility functions.
572
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000573bool
574ProcessLinux::HasExited()
575{
576 switch (GetPrivateState())
577 {
578 default:
579 break;
580
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000581 case eStateDetached:
582 case eStateExited:
583 return true;
584 }
585
586 return false;
587}
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000588
589bool
590ProcessLinux::IsStopped()
591{
592 switch (GetPrivateState())
593 {
594 default:
595 break;
596
597 case eStateStopped:
598 case eStateCrashed:
599 case eStateSuspended:
600 return true;
601 }
602
603 return false;
604}