blob: 137fa46eddc667e07261162de4ebb849b8fdc56d [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
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000110 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
Johnny Chen2341d352012-01-05 21:48:15 +0000111 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
Matt Kopeca7cd95d2013-03-14 21:35:26 +0000209 SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
210
Johnny Chen2341d352012-01-05 21:48:15 +0000211 SetID(m_monitor->GetPID());
212 return error;
213}
214
215void
216ProcessPOSIX::DidLaunch()
217{
218}
219
220Error
221ProcessPOSIX::DoResume()
222{
223 StateType state = GetPrivateState();
224
225 assert(state == eStateStopped || state == eStateCrashed);
226
227 // We are about to resume a thread that will cause the process to exit so
228 // set our exit status now. Do not change our state if the inferior
229 // crashed.
230 if (state == eStateStopped)
231 {
232 if (m_in_limbo)
233 SetExitStatus(m_exit_status, NULL);
234 else
235 SetPrivateState(eStateRunning);
236 }
237
238 bool did_resume = false;
239 uint32_t thread_count = m_thread_list.GetSize(false);
240 for (uint32_t i = 0; i < thread_count; ++i)
241 {
242 POSIXThread *thread = static_cast<POSIXThread*>(
243 m_thread_list.GetThreadAtIndex(i, false).get());
244 did_resume = thread->Resume() || did_resume;
245 }
246 assert(did_resume && "Process resume failed!");
247
248 return Error();
249}
250
251addr_t
252ProcessPOSIX::GetImageInfoAddress()
253{
254 Target *target = &GetTarget();
255 ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
256 Address addr = obj_file->GetImageInfoAddress();
257
258 if (addr.IsValid())
259 return addr.GetLoadAddress(target);
260 else
261 return LLDB_INVALID_ADDRESS;
262}
263
264Error
265ProcessPOSIX::DoHalt(bool &caused_stop)
266{
267 Error error;
268
269 if (IsStopped())
270 {
271 caused_stop = false;
272 }
273 else if (kill(GetID(), SIGSTOP))
274 {
275 caused_stop = false;
276 error.SetErrorToErrno();
277 }
278 else
279 {
280 caused_stop = true;
281 }
Johnny Chen2341d352012-01-05 21:48:15 +0000282 return error;
283}
284
285Error
286ProcessPOSIX::DoDetach()
287{
288 Error error;
289
290 error = m_monitor->Detach();
291 if (error.Success())
292 SetPrivateState(eStateDetached);
293
294 return error;
295}
296
297Error
298ProcessPOSIX::DoSignal(int signal)
299{
300 Error error;
301
302 if (kill(GetID(), signal))
303 error.SetErrorToErrno();
304
305 return error;
306}
307
308Error
309ProcessPOSIX::DoDestroy()
310{
311 Error error;
312
313 if (!HasExited())
314 {
315 // Drive the exit event to completion (do not keep the inferior in
316 // limbo).
317 m_exit_now = true;
318
Greg Clayton972c4382012-03-30 19:56:32 +0000319 if ((m_monitor == NULL || kill(m_monitor->GetPID(), SIGKILL)) && error.Success())
Johnny Chen2341d352012-01-05 21:48:15 +0000320 {
321 error.SetErrorToErrno();
322 return error;
323 }
324
325 SetPrivateState(eStateExited);
326 }
327
328 return error;
329}
330
331void
332ProcessPOSIX::SendMessage(const ProcessMessage &message)
333{
334 Mutex::Locker lock(m_message_mutex);
335
336 switch (message.GetKind())
337 {
Johnny Chen2341d352012-01-05 21:48:15 +0000338 case ProcessMessage::eInvalidMessage:
339 return;
340
341 case ProcessMessage::eLimboMessage:
342 m_in_limbo = true;
343 m_exit_status = message.GetExitStatus();
344 if (m_exit_now)
345 {
346 SetPrivateState(eStateExited);
347 m_monitor->Detach();
348 }
349 else
350 SetPrivateState(eStateStopped);
351 break;
352
353 case ProcessMessage::eExitMessage:
354 m_exit_status = message.GetExitStatus();
355 SetExitStatus(m_exit_status, NULL);
356 break;
357
358 case ProcessMessage::eTraceMessage:
359 case ProcessMessage::eBreakpointMessage:
360 SetPrivateState(eStateStopped);
361 break;
362
363 case ProcessMessage::eSignalMessage:
364 case ProcessMessage::eSignalDeliveredMessage:
Matt Kopecf1fda372013-01-08 16:30:18 +0000365 {
366 lldb::tid_t tid = message.GetTID();
367 lldb::tid_t pid = GetID();
368 if (tid == pid) {
369 SetPrivateState(eStateStopped);
370 break;
371 } else {
372 // FIXME: Ignore any signals generated by children.
373 return;
374 }
375 }
Johnny Chen2341d352012-01-05 21:48:15 +0000376
377 case ProcessMessage::eCrashMessage:
Andrew Kaylor05a47892012-12-14 18:24:34 +0000378 // FIXME: Update stop reason as per bugzilla 14598
379 SetPrivateState(eStateStopped);
Johnny Chen2341d352012-01-05 21:48:15 +0000380 break;
Matt Kopecf1fda372013-01-08 16:30:18 +0000381
382 case ProcessMessage::eNewThreadMessage:
383 SetPrivateState(eStateStopped);
384 break;
Johnny Chen2341d352012-01-05 21:48:15 +0000385 }
386
387 m_message_queue.push(message);
388}
389
390void
391ProcessPOSIX::RefreshStateAfterStop()
392{
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000393 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
Johnny Chen2341d352012-01-05 21:48:15 +0000394 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
395 log->Printf ("ProcessPOSIX::%s()", __FUNCTION__);
396
397 Mutex::Locker lock(m_message_mutex);
398 if (m_message_queue.empty())
399 return;
400
401 ProcessMessage &message = m_message_queue.front();
402
403 // Resolve the thread this message corresponds to and pass it along.
404 // FIXME: we're really dealing with the pid here. This should get
405 // fixed when this code is fixed to handle multiple threads.
406 lldb::tid_t tid = message.GetTID();
407 if (log)
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000408 log->Printf ("ProcessPOSIX::%s() pid = %" PRIi64, __FUNCTION__, tid);
Johnny Chen2341d352012-01-05 21:48:15 +0000409 POSIXThread *thread = static_cast<POSIXThread*>(
410 GetThreadList().FindThreadByID(tid, false).get());
411
Matt Kopecf1fda372013-01-08 16:30:18 +0000412 if (message.GetKind() == ProcessMessage::eNewThreadMessage) {
413 ThreadSP thread_sp;
414 thread_sp.reset(new POSIXThread(*this, message.GetChildTID()));
415 m_thread_list.AddThread(thread_sp);
416 }
417
Johnny Chen2341d352012-01-05 21:48:15 +0000418 assert(thread);
419 thread->Notify(message);
420
421 m_message_queue.pop();
422}
423
424bool
425ProcessPOSIX::IsAlive()
426{
427 StateType state = GetPrivateState();
Daniel Malea0247cf52013-04-01 19:48:37 +0000428 return state != eStateDetached
429 && state != eStateExited
430 && state != eStateInvalid
431 && state != eStateUnloaded;
Johnny Chen2341d352012-01-05 21:48:15 +0000432}
433
434size_t
435ProcessPOSIX::DoReadMemory(addr_t vm_addr,
436 void *buf, size_t size, Error &error)
437{
438 assert(m_monitor);
439 return m_monitor->ReadMemory(vm_addr, buf, size, error);
440}
441
442size_t
443ProcessPOSIX::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
444 Error &error)
445{
446 assert(m_monitor);
447 return m_monitor->WriteMemory(vm_addr, buf, size, error);
448}
449
450addr_t
451ProcessPOSIX::DoAllocateMemory(size_t size, uint32_t permissions,
452 Error &error)
453{
454 addr_t allocated_addr = LLDB_INVALID_ADDRESS;
455
456 unsigned prot = 0;
457 if (permissions & lldb::ePermissionsReadable)
458 prot |= eMmapProtRead;
459 if (permissions & lldb::ePermissionsWritable)
460 prot |= eMmapProtWrite;
461 if (permissions & lldb::ePermissionsExecutable)
462 prot |= eMmapProtExec;
463
464 if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
465 eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
466 m_addr_to_mmap_size[allocated_addr] = size;
467 error.Clear();
468 } else {
469 allocated_addr = LLDB_INVALID_ADDRESS;
470 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
471 }
472
473 return allocated_addr;
474}
475
476Error
477ProcessPOSIX::DoDeallocateMemory(lldb::addr_t addr)
478{
479 Error error;
480 MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
481 if (pos != m_addr_to_mmap_size.end() &&
482 InferiorCallMunmap(this, addr, pos->second))
483 m_addr_to_mmap_size.erase (pos);
484 else
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000485 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
Johnny Chen2341d352012-01-05 21:48:15 +0000486
487 return error;
488}
489
Matt Kopec4f9103f2013-02-27 20:13:38 +0000490addr_t
491ProcessPOSIX::ResolveIndirectFunction(const Address *address, Error &error)
492{
493 addr_t function_addr = LLDB_INVALID_ADDRESS;
494 if (address == NULL) {
495 error.SetErrorStringWithFormat("unable to determine direct function call for NULL address");
496 } else if (!InferiorCall(this, address, function_addr)) {
497 function_addr = LLDB_INVALID_ADDRESS;
Matt Kopec70125482013-03-01 17:44:31 +0000498 error.SetErrorStringWithFormat("unable to determine direct function call for indirect function %s",
499 address->CalculateSymbolContextSymbol()->GetName().AsCString());
Matt Kopec4f9103f2013-02-27 20:13:38 +0000500 }
501 return function_addr;
502}
503
Johnny Chen2341d352012-01-05 21:48:15 +0000504size_t
505ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
506{
507 static const uint8_t g_i386_opcode[] = { 0xCC };
508
509 ArchSpec arch = GetTarget().GetArchitecture();
510 const uint8_t *opcode = NULL;
511 size_t opcode_size = 0;
512
513 switch (arch.GetCore())
514 {
515 default:
516 assert(false && "CPU type not supported!");
517 break;
518
519 case ArchSpec::eCore_x86_32_i386:
520 case ArchSpec::eCore_x86_64_x86_64:
521 opcode = g_i386_opcode;
522 opcode_size = sizeof(g_i386_opcode);
523 break;
524 }
525
526 bp_site->SetTrapOpcode(opcode, opcode_size);
527 return opcode_size;
528}
529
530Error
Daniel Malea52d8dd92013-02-15 20:23:25 +0000531ProcessPOSIX::EnableBreakpointSite(BreakpointSite *bp_site)
Johnny Chen2341d352012-01-05 21:48:15 +0000532{
533 return EnableSoftwareBreakpoint(bp_site);
534}
535
536Error
Daniel Malea52d8dd92013-02-15 20:23:25 +0000537ProcessPOSIX::DisableBreakpointSite(BreakpointSite *bp_site)
Johnny Chen2341d352012-01-05 21:48:15 +0000538{
539 return DisableSoftwareBreakpoint(bp_site);
540}
541
542uint32_t
543ProcessPOSIX::UpdateThreadListIfNeeded()
544{
545 // Do not allow recursive updates.
546 return m_thread_list.GetSize(false);
547}
548
Greg Claytonc8dd5702012-04-12 19:04:34 +0000549bool
Johnny Chen2341d352012-01-05 21:48:15 +0000550ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
551{
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000552 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
Johnny Chen2341d352012-01-05 21:48:15 +0000553 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000554 log->Printf ("ProcessPOSIX::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID());
Johnny Chen2341d352012-01-05 21:48:15 +0000555
556 // Update the process thread list with this new thread.
557 // FIXME: We should be using tid, not pid.
558 assert(m_monitor);
559 ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
Greg Claytone5eaa302012-02-21 18:40:07 +0000560 if (!thread_sp) {
Greg Clayton5e91e372012-10-12 16:23:23 +0000561 thread_sp.reset(new POSIXThread(*this, GetID()));
Greg Claytone5eaa302012-02-21 18:40:07 +0000562 }
Johnny Chen2341d352012-01-05 21:48:15 +0000563
564 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000565 log->Printf ("ProcessPOSIX::%s() updated pid = %" PRIi64, __FUNCTION__, GetID());
Johnny Chen2341d352012-01-05 21:48:15 +0000566 new_thread_list.AddThread(thread_sp);
567
Greg Claytonc8dd5702012-04-12 19:04:34 +0000568 return new_thread_list.GetSize(false) > 0;
Johnny Chen2341d352012-01-05 21:48:15 +0000569}
570
571ByteOrder
572ProcessPOSIX::GetByteOrder() const
573{
574 // FIXME: We should be able to extract this value directly. See comment in
575 // ProcessPOSIX().
576 return m_byte_order;
577}
578
579size_t
580ProcessPOSIX::PutSTDIN(const char *buf, size_t len, Error &error)
581{
582 ssize_t status;
583 if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
584 {
585 error.SetErrorToErrno();
586 return 0;
587 }
588 return status;
589}
590
Johnny Chen2341d352012-01-05 21:48:15 +0000591UnixSignals &
592ProcessPOSIX::GetUnixSignals()
593{
594 return m_signals;
595}
596
597//------------------------------------------------------------------------------
598// Utility functions.
599
600bool
601ProcessPOSIX::HasExited()
602{
603 switch (GetPrivateState())
604 {
605 default:
606 break;
607
608 case eStateDetached:
609 case eStateExited:
610 return true;
611 }
612
613 return false;
614}
615
616bool
617ProcessPOSIX::IsStopped()
618{
619 switch (GetPrivateState())
620 {
621 default:
622 break;
623
624 case eStateStopped:
625 case eStateCrashed:
626 case eStateSuspended:
627 return true;
628 }
629
630 return false;
631}