blob: a69486559b8a7c37d1165cb93786446796c86308 [file] [log] [blame]
Johnny Chen2341d352012-01-05 21:48:15 +00001//===-- ProcessPOSIX.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
Daniel Malead891f9b2012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Johnny Chen2341d352012-01-05 21:48:15 +000012// C Includes
13#include <errno.h>
14
15// C++ Includes
16// Other libraries and framework includes
Greg Clayton8ac035d2012-09-04 14:55:50 +000017#include "lldb/Core/Module.h"
Johnny Chen2341d352012-01-05 21:48:15 +000018#include "lldb/Core/PluginManager.h"
19#include "lldb/Core/State.h"
Daniel Malea1e44fdd2013-01-08 14:49:22 +000020#include "lldb/Host/FileSpec.h"
Johnny Chen2341d352012-01-05 21:48:15 +000021#include "lldb/Host/Host.h"
22#include "lldb/Symbol/ObjectFile.h"
23#include "lldb/Target/DynamicLoader.h"
24#include "lldb/Target/Target.h"
25
26#include "ProcessPOSIX.h"
27#include "ProcessPOSIXLog.h"
28#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
29#include "ProcessMonitor.h"
30#include "POSIXThread.h"
31
32using namespace lldb;
33using namespace lldb_private;
34
35//------------------------------------------------------------------------------
36// Static functions.
37#if 0
38Process*
39ProcessPOSIX::CreateInstance(Target& target, Listener &listener)
40{
41 return new ProcessPOSIX(target, listener);
42}
43
44
45void
46ProcessPOSIX::Initialize()
47{
48 static bool g_initialized = false;
49
50 if (!g_initialized)
51 {
52 g_initialized = true;
53 PluginManager::RegisterPlugin(GetPluginNameStatic(),
54 GetPluginDescriptionStatic(),
55 CreateInstance);
56
57 Log::Callbacks log_callbacks = {
58 ProcessPOSIXLog::DisableLog,
59 ProcessPOSIXLog::EnableLog,
60 ProcessPOSIXLog::ListLogCategories
61 };
62
63 Log::RegisterLogChannel (ProcessPOSIX::GetPluginNameStatic(), log_callbacks);
64 }
65}
66#endif
67
68//------------------------------------------------------------------------------
69// Constructors and destructors.
70
71ProcessPOSIX::ProcessPOSIX(Target& target, Listener &listener)
72 : Process(target, listener),
Johnny Chen78dae822012-04-14 00:54:42 +000073 m_byte_order(lldb::endian::InlHostByteOrder()),
Johnny Chen2341d352012-01-05 21:48:15 +000074 m_monitor(NULL),
75 m_module(NULL),
76 m_in_limbo(false),
77 m_exit_now(false)
78{
79 // FIXME: Putting this code in the ctor and saving the byte order in a
80 // member variable is a hack to avoid const qual issues in GetByteOrder.
Johnny Chen78dae822012-04-14 00:54:42 +000081 lldb::ModuleSP module = GetTarget().GetExecutableModule();
82 if (module != NULL && module->GetObjectFile() != NULL)
83 m_byte_order = module->GetObjectFile()->GetByteOrder();
Johnny Chen2341d352012-01-05 21:48:15 +000084}
85
86ProcessPOSIX::~ProcessPOSIX()
87{
88 delete m_monitor;
89}
90
91//------------------------------------------------------------------------------
92// Process protocol.
93
94bool
95ProcessPOSIX::CanDebug(Target &target, bool plugin_specified_by_name)
96{
97 // For now we are just making sure the file exists for a given module
98 ModuleSP exe_module_sp(target.GetExecutableModule());
99 if (exe_module_sp.get())
100 return exe_module_sp->GetFileSpec().Exists();
101 return false;
102}
103
104Error
105ProcessPOSIX::DoAttachToProcessWithID(lldb::pid_t pid)
106{
107 Error error;
108 assert(m_monitor == NULL);
109
110 LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
111 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000112 log->Printf ("ProcessPOSIX::%s(pid = %" PRIi64 ")", __FUNCTION__, GetID());
Johnny Chen2341d352012-01-05 21:48:15 +0000113
114 m_monitor = new ProcessMonitor(this, pid, error);
115
116 if (!error.Success())
117 return error;
118
119 SetID(pid);
120 return error;
121}
122
123Error
Greg Claytonc6430772012-09-07 17:51:47 +0000124ProcessPOSIX::DoAttachToProcessWithID (lldb::pid_t pid, const ProcessAttachInfo &attach_info)
125{
126 return DoAttachToProcessWithID(pid);
127}
128
129Error
Johnny Chen2341d352012-01-05 21:48:15 +0000130ProcessPOSIX::WillLaunch(Module* module)
131{
132 Error error;
133 return error;
134}
135
136const char *
137ProcessPOSIX::GetFilePath(
138 const lldb_private::ProcessLaunchInfo::FileAction *file_action,
139 const char *default_path)
140{
141 const char *pts_name = "/dev/pts/";
142 const char *path = NULL;
143
144 if (file_action)
145 {
146 if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen)
147 path = file_action->GetPath();
148 // By default the stdio paths passed in will be pseudo-terminal
149 // (/dev/pts). If so, convert to using a different default path
150 // instead to redirect I/O to the debugger console. This should
151 // also handle user overrides to /dev/null or a different file.
152 if (::strncmp(path, pts_name, ::strlen(pts_name)) == 0)
153 path = default_path;
154 }
155
156 return path;
157}
158
159Error
160ProcessPOSIX::DoLaunch (Module *module,
161 const ProcessLaunchInfo &launch_info)
162{
163 Error error;
164 assert(m_monitor == NULL);
165
Daniel Malea1e44fdd2013-01-08 14:49:22 +0000166 const char* working_dir = launch_info.GetWorkingDirectory();
167 if (working_dir) {
168 FileSpec WorkingDir(working_dir, true);
169 if (!WorkingDir || WorkingDir.GetFileType() != FileSpec::eFileTypeDirectory)
170 {
171 error.SetErrorStringWithFormat("No such file or directory: %s", working_dir);
172 return error;
173 }
174 }
175
Johnny Chen2341d352012-01-05 21:48:15 +0000176 SetPrivateState(eStateLaunching);
177
178 const lldb_private::ProcessLaunchInfo::FileAction *file_action;
179
180 // Default of NULL will mean to use existing open file descriptors
181 const char *stdin_path = NULL;
182 const char *stdout_path = NULL;
183 const char *stderr_path = NULL;
Daniel Malea1e44fdd2013-01-08 14:49:22 +0000184
Johnny Chen2341d352012-01-05 21:48:15 +0000185 file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
186 stdin_path = GetFilePath(file_action, stdin_path);
187
188 file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
189 stdout_path = GetFilePath(file_action, stdout_path);
190
191 file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
192 stderr_path = GetFilePath(file_action, stderr_path);
193
194 m_monitor = new ProcessMonitor (this,
195 module,
196 launch_info.GetArguments().GetConstArgumentVector(),
197 launch_info.GetEnvironmentEntries().GetConstArgumentVector(),
198 stdin_path,
199 stdout_path,
200 stderr_path,
Daniel Malea1e44fdd2013-01-08 14:49:22 +0000201 working_dir,
Johnny Chen2341d352012-01-05 21:48:15 +0000202 error);
203
204 m_module = module;
205
206 if (!error.Success())
207 return error;
208
209 SetID(m_monitor->GetPID());
210 return error;
211}
212
213void
214ProcessPOSIX::DidLaunch()
215{
216}
217
218Error
219ProcessPOSIX::DoResume()
220{
221 StateType state = GetPrivateState();
222
223 assert(state == eStateStopped || state == eStateCrashed);
224
225 // We are about to resume a thread that will cause the process to exit so
226 // set our exit status now. Do not change our state if the inferior
227 // crashed.
228 if (state == eStateStopped)
229 {
230 if (m_in_limbo)
231 SetExitStatus(m_exit_status, NULL);
232 else
233 SetPrivateState(eStateRunning);
234 }
235
236 bool did_resume = false;
237 uint32_t thread_count = m_thread_list.GetSize(false);
238 for (uint32_t i = 0; i < thread_count; ++i)
239 {
240 POSIXThread *thread = static_cast<POSIXThread*>(
241 m_thread_list.GetThreadAtIndex(i, false).get());
242 did_resume = thread->Resume() || did_resume;
243 }
244 assert(did_resume && "Process resume failed!");
245
246 return Error();
247}
248
249addr_t
250ProcessPOSIX::GetImageInfoAddress()
251{
252 Target *target = &GetTarget();
253 ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
254 Address addr = obj_file->GetImageInfoAddress();
255
256 if (addr.IsValid())
257 return addr.GetLoadAddress(target);
258 else
259 return LLDB_INVALID_ADDRESS;
260}
261
262Error
263ProcessPOSIX::DoHalt(bool &caused_stop)
264{
265 Error error;
266
267 if (IsStopped())
268 {
269 caused_stop = false;
270 }
271 else if (kill(GetID(), SIGSTOP))
272 {
273 caused_stop = false;
274 error.SetErrorToErrno();
275 }
276 else
277 {
278 caused_stop = true;
279 }
280
281 return error;
282}
283
284Error
285ProcessPOSIX::DoDetach()
286{
287 Error error;
288
289 error = m_monitor->Detach();
290 if (error.Success())
291 SetPrivateState(eStateDetached);
292
293 return error;
294}
295
296Error
297ProcessPOSIX::DoSignal(int signal)
298{
299 Error error;
300
301 if (kill(GetID(), signal))
302 error.SetErrorToErrno();
303
304 return error;
305}
306
307Error
308ProcessPOSIX::DoDestroy()
309{
310 Error error;
311
312 if (!HasExited())
313 {
314 // Drive the exit event to completion (do not keep the inferior in
315 // limbo).
316 m_exit_now = true;
317
Greg Clayton972c4382012-03-30 19:56:32 +0000318 if ((m_monitor == NULL || kill(m_monitor->GetPID(), SIGKILL)) && error.Success())
Johnny Chen2341d352012-01-05 21:48:15 +0000319 {
320 error.SetErrorToErrno();
321 return error;
322 }
323
324 SetPrivateState(eStateExited);
325 }
326
327 return error;
328}
329
330void
331ProcessPOSIX::SendMessage(const ProcessMessage &message)
332{
333 Mutex::Locker lock(m_message_mutex);
334
335 switch (message.GetKind())
336 {
Johnny Chen2341d352012-01-05 21:48:15 +0000337 case ProcessMessage::eInvalidMessage:
338 return;
339
340 case ProcessMessage::eLimboMessage:
341 m_in_limbo = true;
342 m_exit_status = message.GetExitStatus();
343 if (m_exit_now)
344 {
345 SetPrivateState(eStateExited);
346 m_monitor->Detach();
347 }
348 else
349 SetPrivateState(eStateStopped);
350 break;
351
352 case ProcessMessage::eExitMessage:
353 m_exit_status = message.GetExitStatus();
354 SetExitStatus(m_exit_status, NULL);
355 break;
356
357 case ProcessMessage::eTraceMessage:
358 case ProcessMessage::eBreakpointMessage:
359 SetPrivateState(eStateStopped);
360 break;
361
362 case ProcessMessage::eSignalMessage:
363 case ProcessMessage::eSignalDeliveredMessage:
364 SetPrivateState(eStateStopped);
365 break;
366
367 case ProcessMessage::eCrashMessage:
Andrew Kaylor05a47892012-12-14 18:24:34 +0000368 // FIXME: Update stop reason as per bugzilla 14598
369 SetPrivateState(eStateStopped);
Johnny Chen2341d352012-01-05 21:48:15 +0000370 break;
371 }
372
373 m_message_queue.push(message);
374}
375
376void
377ProcessPOSIX::RefreshStateAfterStop()
378{
379 LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
380 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
381 log->Printf ("ProcessPOSIX::%s()", __FUNCTION__);
382
383 Mutex::Locker lock(m_message_mutex);
384 if (m_message_queue.empty())
385 return;
386
387 ProcessMessage &message = m_message_queue.front();
388
389 // Resolve the thread this message corresponds to and pass it along.
390 // FIXME: we're really dealing with the pid here. This should get
391 // fixed when this code is fixed to handle multiple threads.
392 lldb::tid_t tid = message.GetTID();
393 if (log)
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000394 log->Printf ("ProcessPOSIX::%s() pid = %" PRIi64, __FUNCTION__, tid);
Johnny Chen2341d352012-01-05 21:48:15 +0000395 POSIXThread *thread = static_cast<POSIXThread*>(
396 GetThreadList().FindThreadByID(tid, false).get());
397
398 assert(thread);
399 thread->Notify(message);
400
401 m_message_queue.pop();
402}
403
404bool
405ProcessPOSIX::IsAlive()
406{
407 StateType state = GetPrivateState();
408 return state != eStateDetached && state != eStateExited && state != eStateInvalid;
409}
410
411size_t
412ProcessPOSIX::DoReadMemory(addr_t vm_addr,
413 void *buf, size_t size, Error &error)
414{
415 assert(m_monitor);
416 return m_monitor->ReadMemory(vm_addr, buf, size, error);
417}
418
419size_t
420ProcessPOSIX::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
421 Error &error)
422{
423 assert(m_monitor);
424 return m_monitor->WriteMemory(vm_addr, buf, size, error);
425}
426
427addr_t
428ProcessPOSIX::DoAllocateMemory(size_t size, uint32_t permissions,
429 Error &error)
430{
431 addr_t allocated_addr = LLDB_INVALID_ADDRESS;
432
433 unsigned prot = 0;
434 if (permissions & lldb::ePermissionsReadable)
435 prot |= eMmapProtRead;
436 if (permissions & lldb::ePermissionsWritable)
437 prot |= eMmapProtWrite;
438 if (permissions & lldb::ePermissionsExecutable)
439 prot |= eMmapProtExec;
440
441 if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
442 eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
443 m_addr_to_mmap_size[allocated_addr] = size;
444 error.Clear();
445 } else {
446 allocated_addr = LLDB_INVALID_ADDRESS;
447 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
448 }
449
450 return allocated_addr;
451}
452
453Error
454ProcessPOSIX::DoDeallocateMemory(lldb::addr_t addr)
455{
456 Error error;
457 MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
458 if (pos != m_addr_to_mmap_size.end() &&
459 InferiorCallMunmap(this, addr, pos->second))
460 m_addr_to_mmap_size.erase (pos);
461 else
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000462 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
Johnny Chen2341d352012-01-05 21:48:15 +0000463
464 return error;
465}
466
467size_t
468ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
469{
470 static const uint8_t g_i386_opcode[] = { 0xCC };
471
472 ArchSpec arch = GetTarget().GetArchitecture();
473 const uint8_t *opcode = NULL;
474 size_t opcode_size = 0;
475
476 switch (arch.GetCore())
477 {
478 default:
479 assert(false && "CPU type not supported!");
480 break;
481
482 case ArchSpec::eCore_x86_32_i386:
483 case ArchSpec::eCore_x86_64_x86_64:
484 opcode = g_i386_opcode;
485 opcode_size = sizeof(g_i386_opcode);
486 break;
487 }
488
489 bp_site->SetTrapOpcode(opcode, opcode_size);
490 return opcode_size;
491}
492
493Error
494ProcessPOSIX::EnableBreakpoint(BreakpointSite *bp_site)
495{
496 return EnableSoftwareBreakpoint(bp_site);
497}
498
499Error
500ProcessPOSIX::DisableBreakpoint(BreakpointSite *bp_site)
501{
502 return DisableSoftwareBreakpoint(bp_site);
503}
504
505uint32_t
506ProcessPOSIX::UpdateThreadListIfNeeded()
507{
508 // Do not allow recursive updates.
509 return m_thread_list.GetSize(false);
510}
511
Greg Claytonc8dd5702012-04-12 19:04:34 +0000512bool
Johnny Chen2341d352012-01-05 21:48:15 +0000513ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
514{
515 LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
516 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000517 log->Printf ("ProcessPOSIX::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID());
Johnny Chen2341d352012-01-05 21:48:15 +0000518
519 // Update the process thread list with this new thread.
520 // FIXME: We should be using tid, not pid.
521 assert(m_monitor);
522 ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
Greg Claytone5eaa302012-02-21 18:40:07 +0000523 if (!thread_sp) {
Greg Clayton5e91e372012-10-12 16:23:23 +0000524 thread_sp.reset(new POSIXThread(*this, GetID()));
Greg Claytone5eaa302012-02-21 18:40:07 +0000525 }
Johnny Chen2341d352012-01-05 21:48:15 +0000526
527 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000528 log->Printf ("ProcessPOSIX::%s() updated pid = %" PRIi64, __FUNCTION__, GetID());
Johnny Chen2341d352012-01-05 21:48:15 +0000529 new_thread_list.AddThread(thread_sp);
530
Greg Claytonc8dd5702012-04-12 19:04:34 +0000531 return new_thread_list.GetSize(false) > 0;
Johnny Chen2341d352012-01-05 21:48:15 +0000532}
533
534ByteOrder
535ProcessPOSIX::GetByteOrder() const
536{
537 // FIXME: We should be able to extract this value directly. See comment in
538 // ProcessPOSIX().
539 return m_byte_order;
540}
541
542size_t
543ProcessPOSIX::PutSTDIN(const char *buf, size_t len, Error &error)
544{
545 ssize_t status;
546 if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
547 {
548 error.SetErrorToErrno();
549 return 0;
550 }
551 return status;
552}
553
554size_t
555ProcessPOSIX::GetSTDOUT(char *buf, size_t len, Error &error)
556{
557 ssize_t bytes_read;
558
559 // The terminal file descriptor is always in non-block mode.
560 if ((bytes_read = read(m_monitor->GetTerminalFD(), buf, len)) < 0)
561 {
562 if (errno != EAGAIN)
563 error.SetErrorToErrno();
564 return 0;
565 }
566 return bytes_read;
567}
568
569size_t
570ProcessPOSIX::GetSTDERR(char *buf, size_t len, Error &error)
571{
572 return GetSTDOUT(buf, len, error);
573}
574
575UnixSignals &
576ProcessPOSIX::GetUnixSignals()
577{
578 return m_signals;
579}
580
581//------------------------------------------------------------------------------
582// Utility functions.
583
584bool
585ProcessPOSIX::HasExited()
586{
587 switch (GetPrivateState())
588 {
589 default:
590 break;
591
592 case eStateDetached:
593 case eStateExited:
594 return true;
595 }
596
597 return false;
598}
599
600bool
601ProcessPOSIX::IsStopped()
602{
603 switch (GetPrivateState())
604 {
605 default:
606 break;
607
608 case eStateStopped:
609 case eStateCrashed:
610 case eStateSuspended:
611 return true;
612 }
613
614 return false;
615}