blob: 35c365f75c0352bd328e963dbd57cb9a5afeaf7e [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
Jim Ingham761afb82013-05-02 00:27:30 +0000286ProcessPOSIX::DoDetach(bool keep_stopped)
Johnny Chen2341d352012-01-05 21:48:15 +0000287{
288 Error error;
Jim Ingham761afb82013-05-02 00:27:30 +0000289 if (keep_stopped)
290 {
291 // FIXME: If you want to implement keep_stopped on Linux,
292 // this would be the place to do it.
293 error.SetErrorString("Detaching with keep_stopped true is not currently supported on Linux.");
294 return error;
295 }
Johnny Chen2341d352012-01-05 21:48:15 +0000296
297 error = m_monitor->Detach();
298 if (error.Success())
299 SetPrivateState(eStateDetached);
300
301 return error;
302}
303
304Error
305ProcessPOSIX::DoSignal(int signal)
306{
307 Error error;
308
309 if (kill(GetID(), signal))
310 error.SetErrorToErrno();
311
312 return error;
313}
314
315Error
316ProcessPOSIX::DoDestroy()
317{
318 Error error;
319
320 if (!HasExited())
321 {
322 // Drive the exit event to completion (do not keep the inferior in
323 // limbo).
324 m_exit_now = true;
325
Greg Clayton972c4382012-03-30 19:56:32 +0000326 if ((m_monitor == NULL || kill(m_monitor->GetPID(), SIGKILL)) && error.Success())
Johnny Chen2341d352012-01-05 21:48:15 +0000327 {
328 error.SetErrorToErrno();
329 return error;
330 }
331
332 SetPrivateState(eStateExited);
333 }
334
335 return error;
336}
337
338void
339ProcessPOSIX::SendMessage(const ProcessMessage &message)
340{
341 Mutex::Locker lock(m_message_mutex);
342
343 switch (message.GetKind())
344 {
Johnny Chen2341d352012-01-05 21:48:15 +0000345 case ProcessMessage::eInvalidMessage:
346 return;
347
348 case ProcessMessage::eLimboMessage:
349 m_in_limbo = true;
350 m_exit_status = message.GetExitStatus();
351 if (m_exit_now)
352 {
353 SetPrivateState(eStateExited);
354 m_monitor->Detach();
355 }
356 else
357 SetPrivateState(eStateStopped);
358 break;
359
360 case ProcessMessage::eExitMessage:
361 m_exit_status = message.GetExitStatus();
362 SetExitStatus(m_exit_status, NULL);
363 break;
364
365 case ProcessMessage::eTraceMessage:
366 case ProcessMessage::eBreakpointMessage:
367 SetPrivateState(eStateStopped);
368 break;
369
370 case ProcessMessage::eSignalMessage:
371 case ProcessMessage::eSignalDeliveredMessage:
Matt Kopecf1fda372013-01-08 16:30:18 +0000372 {
373 lldb::tid_t tid = message.GetTID();
374 lldb::tid_t pid = GetID();
375 if (tid == pid) {
376 SetPrivateState(eStateStopped);
377 break;
378 } else {
379 // FIXME: Ignore any signals generated by children.
380 return;
381 }
382 }
Johnny Chen2341d352012-01-05 21:48:15 +0000383
384 case ProcessMessage::eCrashMessage:
Andrew Kaylor05a47892012-12-14 18:24:34 +0000385 // FIXME: Update stop reason as per bugzilla 14598
386 SetPrivateState(eStateStopped);
Johnny Chen2341d352012-01-05 21:48:15 +0000387 break;
Matt Kopecf1fda372013-01-08 16:30:18 +0000388
389 case ProcessMessage::eNewThreadMessage:
390 SetPrivateState(eStateStopped);
391 break;
Johnny Chen2341d352012-01-05 21:48:15 +0000392 }
393
394 m_message_queue.push(message);
395}
396
397void
398ProcessPOSIX::RefreshStateAfterStop()
399{
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000400 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
Johnny Chen2341d352012-01-05 21:48:15 +0000401 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
402 log->Printf ("ProcessPOSIX::%s()", __FUNCTION__);
403
404 Mutex::Locker lock(m_message_mutex);
405 if (m_message_queue.empty())
406 return;
407
408 ProcessMessage &message = m_message_queue.front();
409
410 // Resolve the thread this message corresponds to and pass it along.
411 // FIXME: we're really dealing with the pid here. This should get
412 // fixed when this code is fixed to handle multiple threads.
413 lldb::tid_t tid = message.GetTID();
414 if (log)
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000415 log->Printf ("ProcessPOSIX::%s() pid = %" PRIi64, __FUNCTION__, tid);
Johnny Chen2341d352012-01-05 21:48:15 +0000416 POSIXThread *thread = static_cast<POSIXThread*>(
417 GetThreadList().FindThreadByID(tid, false).get());
418
Matt Kopecf1fda372013-01-08 16:30:18 +0000419 if (message.GetKind() == ProcessMessage::eNewThreadMessage) {
420 ThreadSP thread_sp;
421 thread_sp.reset(new POSIXThread(*this, message.GetChildTID()));
422 m_thread_list.AddThread(thread_sp);
423 }
424
Johnny Chen2341d352012-01-05 21:48:15 +0000425 assert(thread);
426 thread->Notify(message);
427
428 m_message_queue.pop();
429}
430
431bool
432ProcessPOSIX::IsAlive()
433{
434 StateType state = GetPrivateState();
Daniel Malea0247cf52013-04-01 19:48:37 +0000435 return state != eStateDetached
436 && state != eStateExited
437 && state != eStateInvalid
438 && state != eStateUnloaded;
Johnny Chen2341d352012-01-05 21:48:15 +0000439}
440
441size_t
442ProcessPOSIX::DoReadMemory(addr_t vm_addr,
443 void *buf, size_t size, Error &error)
444{
445 assert(m_monitor);
446 return m_monitor->ReadMemory(vm_addr, buf, size, error);
447}
448
449size_t
450ProcessPOSIX::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
451 Error &error)
452{
453 assert(m_monitor);
454 return m_monitor->WriteMemory(vm_addr, buf, size, error);
455}
456
457addr_t
458ProcessPOSIX::DoAllocateMemory(size_t size, uint32_t permissions,
459 Error &error)
460{
461 addr_t allocated_addr = LLDB_INVALID_ADDRESS;
462
463 unsigned prot = 0;
464 if (permissions & lldb::ePermissionsReadable)
465 prot |= eMmapProtRead;
466 if (permissions & lldb::ePermissionsWritable)
467 prot |= eMmapProtWrite;
468 if (permissions & lldb::ePermissionsExecutable)
469 prot |= eMmapProtExec;
470
471 if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
472 eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
473 m_addr_to_mmap_size[allocated_addr] = size;
474 error.Clear();
475 } else {
476 allocated_addr = LLDB_INVALID_ADDRESS;
477 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
478 }
479
480 return allocated_addr;
481}
482
483Error
484ProcessPOSIX::DoDeallocateMemory(lldb::addr_t addr)
485{
486 Error error;
487 MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
488 if (pos != m_addr_to_mmap_size.end() &&
489 InferiorCallMunmap(this, addr, pos->second))
490 m_addr_to_mmap_size.erase (pos);
491 else
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000492 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
Johnny Chen2341d352012-01-05 21:48:15 +0000493
494 return error;
495}
496
Matt Kopec4f9103f2013-02-27 20:13:38 +0000497addr_t
498ProcessPOSIX::ResolveIndirectFunction(const Address *address, Error &error)
499{
500 addr_t function_addr = LLDB_INVALID_ADDRESS;
501 if (address == NULL) {
502 error.SetErrorStringWithFormat("unable to determine direct function call for NULL address");
503 } else if (!InferiorCall(this, address, function_addr)) {
504 function_addr = LLDB_INVALID_ADDRESS;
Matt Kopec70125482013-03-01 17:44:31 +0000505 error.SetErrorStringWithFormat("unable to determine direct function call for indirect function %s",
506 address->CalculateSymbolContextSymbol()->GetName().AsCString());
Matt Kopec4f9103f2013-02-27 20:13:38 +0000507 }
508 return function_addr;
509}
510
Johnny Chen2341d352012-01-05 21:48:15 +0000511size_t
512ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
513{
514 static const uint8_t g_i386_opcode[] = { 0xCC };
515
516 ArchSpec arch = GetTarget().GetArchitecture();
517 const uint8_t *opcode = NULL;
518 size_t opcode_size = 0;
519
520 switch (arch.GetCore())
521 {
522 default:
523 assert(false && "CPU type not supported!");
524 break;
525
526 case ArchSpec::eCore_x86_32_i386:
527 case ArchSpec::eCore_x86_64_x86_64:
528 opcode = g_i386_opcode;
529 opcode_size = sizeof(g_i386_opcode);
530 break;
531 }
532
533 bp_site->SetTrapOpcode(opcode, opcode_size);
534 return opcode_size;
535}
536
537Error
Daniel Malea52d8dd92013-02-15 20:23:25 +0000538ProcessPOSIX::EnableBreakpointSite(BreakpointSite *bp_site)
Johnny Chen2341d352012-01-05 21:48:15 +0000539{
540 return EnableSoftwareBreakpoint(bp_site);
541}
542
543Error
Daniel Malea52d8dd92013-02-15 20:23:25 +0000544ProcessPOSIX::DisableBreakpointSite(BreakpointSite *bp_site)
Johnny Chen2341d352012-01-05 21:48:15 +0000545{
546 return DisableSoftwareBreakpoint(bp_site);
547}
548
549uint32_t
550ProcessPOSIX::UpdateThreadListIfNeeded()
551{
552 // Do not allow recursive updates.
553 return m_thread_list.GetSize(false);
554}
555
Greg Claytonc8dd5702012-04-12 19:04:34 +0000556bool
Johnny Chen2341d352012-01-05 21:48:15 +0000557ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
558{
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000559 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
Johnny Chen2341d352012-01-05 21:48:15 +0000560 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000561 log->Printf ("ProcessPOSIX::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID());
Johnny Chen2341d352012-01-05 21:48:15 +0000562
563 // Update the process thread list with this new thread.
564 // FIXME: We should be using tid, not pid.
565 assert(m_monitor);
566 ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
Greg Claytone5eaa302012-02-21 18:40:07 +0000567 if (!thread_sp) {
Greg Clayton5e91e372012-10-12 16:23:23 +0000568 thread_sp.reset(new POSIXThread(*this, GetID()));
Greg Claytone5eaa302012-02-21 18:40:07 +0000569 }
Johnny Chen2341d352012-01-05 21:48:15 +0000570
571 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000572 log->Printf ("ProcessPOSIX::%s() updated pid = %" PRIi64, __FUNCTION__, GetID());
Johnny Chen2341d352012-01-05 21:48:15 +0000573 new_thread_list.AddThread(thread_sp);
574
Greg Claytonc8dd5702012-04-12 19:04:34 +0000575 return new_thread_list.GetSize(false) > 0;
Johnny Chen2341d352012-01-05 21:48:15 +0000576}
577
578ByteOrder
579ProcessPOSIX::GetByteOrder() const
580{
581 // FIXME: We should be able to extract this value directly. See comment in
582 // ProcessPOSIX().
583 return m_byte_order;
584}
585
586size_t
587ProcessPOSIX::PutSTDIN(const char *buf, size_t len, Error &error)
588{
589 ssize_t status;
590 if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
591 {
592 error.SetErrorToErrno();
593 return 0;
594 }
595 return status;
596}
597
Johnny Chen2341d352012-01-05 21:48:15 +0000598UnixSignals &
599ProcessPOSIX::GetUnixSignals()
600{
601 return m_signals;
602}
603
604//------------------------------------------------------------------------------
605// Utility functions.
606
607bool
608ProcessPOSIX::HasExited()
609{
610 switch (GetPrivateState())
611 {
612 default:
613 break;
614
615 case eStateDetached:
616 case eStateExited:
617 return true;
618 }
619
620 return false;
621}
622
623bool
624ProcessPOSIX::IsStopped()
625{
626 switch (GetPrivateState())
627 {
628 default:
629 break;
630
631 case eStateStopped:
632 case eStateCrashed:
633 case eStateSuspended:
634 return true;
635 }
636
637 return false;
638}