blob: 980778f0eecd4136e76fa7e9626f6a6ee74f2544 [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:
Matt Kopecf1fda372013-01-08 16:30:18 +0000364 {
365 lldb::tid_t tid = message.GetTID();
366 lldb::tid_t pid = GetID();
367 if (tid == pid) {
368 SetPrivateState(eStateStopped);
369 break;
370 } else {
371 // FIXME: Ignore any signals generated by children.
372 return;
373 }
374 }
Johnny Chen2341d352012-01-05 21:48:15 +0000375
376 case ProcessMessage::eCrashMessage:
Andrew Kaylor05a47892012-12-14 18:24:34 +0000377 // FIXME: Update stop reason as per bugzilla 14598
378 SetPrivateState(eStateStopped);
Johnny Chen2341d352012-01-05 21:48:15 +0000379 break;
Matt Kopecf1fda372013-01-08 16:30:18 +0000380
381 case ProcessMessage::eNewThreadMessage:
382 SetPrivateState(eStateStopped);
383 break;
Johnny Chen2341d352012-01-05 21:48:15 +0000384 }
385
386 m_message_queue.push(message);
387}
388
389void
390ProcessPOSIX::RefreshStateAfterStop()
391{
392 LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
393 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
394 log->Printf ("ProcessPOSIX::%s()", __FUNCTION__);
395
396 Mutex::Locker lock(m_message_mutex);
397 if (m_message_queue.empty())
398 return;
399
400 ProcessMessage &message = m_message_queue.front();
401
402 // Resolve the thread this message corresponds to and pass it along.
403 // FIXME: we're really dealing with the pid here. This should get
404 // fixed when this code is fixed to handle multiple threads.
405 lldb::tid_t tid = message.GetTID();
406 if (log)
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000407 log->Printf ("ProcessPOSIX::%s() pid = %" PRIi64, __FUNCTION__, tid);
Johnny Chen2341d352012-01-05 21:48:15 +0000408 POSIXThread *thread = static_cast<POSIXThread*>(
409 GetThreadList().FindThreadByID(tid, false).get());
410
Matt Kopecf1fda372013-01-08 16:30:18 +0000411 if (message.GetKind() == ProcessMessage::eNewThreadMessage) {
412 ThreadSP thread_sp;
413 thread_sp.reset(new POSIXThread(*this, message.GetChildTID()));
414 m_thread_list.AddThread(thread_sp);
415 }
416
Johnny Chen2341d352012-01-05 21:48:15 +0000417 assert(thread);
418 thread->Notify(message);
419
420 m_message_queue.pop();
421}
422
423bool
424ProcessPOSIX::IsAlive()
425{
426 StateType state = GetPrivateState();
427 return state != eStateDetached && state != eStateExited && state != eStateInvalid;
428}
429
430size_t
431ProcessPOSIX::DoReadMemory(addr_t vm_addr,
432 void *buf, size_t size, Error &error)
433{
434 assert(m_monitor);
435 return m_monitor->ReadMemory(vm_addr, buf, size, error);
436}
437
438size_t
439ProcessPOSIX::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
440 Error &error)
441{
442 assert(m_monitor);
443 return m_monitor->WriteMemory(vm_addr, buf, size, error);
444}
445
446addr_t
447ProcessPOSIX::DoAllocateMemory(size_t size, uint32_t permissions,
448 Error &error)
449{
450 addr_t allocated_addr = LLDB_INVALID_ADDRESS;
451
452 unsigned prot = 0;
453 if (permissions & lldb::ePermissionsReadable)
454 prot |= eMmapProtRead;
455 if (permissions & lldb::ePermissionsWritable)
456 prot |= eMmapProtWrite;
457 if (permissions & lldb::ePermissionsExecutable)
458 prot |= eMmapProtExec;
459
460 if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
461 eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
462 m_addr_to_mmap_size[allocated_addr] = size;
463 error.Clear();
464 } else {
465 allocated_addr = LLDB_INVALID_ADDRESS;
466 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
467 }
468
469 return allocated_addr;
470}
471
472Error
473ProcessPOSIX::DoDeallocateMemory(lldb::addr_t addr)
474{
475 Error error;
476 MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
477 if (pos != m_addr_to_mmap_size.end() &&
478 InferiorCallMunmap(this, addr, pos->second))
479 m_addr_to_mmap_size.erase (pos);
480 else
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000481 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
Johnny Chen2341d352012-01-05 21:48:15 +0000482
483 return error;
484}
485
486size_t
487ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
488{
489 static const uint8_t g_i386_opcode[] = { 0xCC };
490
491 ArchSpec arch = GetTarget().GetArchitecture();
492 const uint8_t *opcode = NULL;
493 size_t opcode_size = 0;
494
495 switch (arch.GetCore())
496 {
497 default:
498 assert(false && "CPU type not supported!");
499 break;
500
501 case ArchSpec::eCore_x86_32_i386:
502 case ArchSpec::eCore_x86_64_x86_64:
503 opcode = g_i386_opcode;
504 opcode_size = sizeof(g_i386_opcode);
505 break;
506 }
507
508 bp_site->SetTrapOpcode(opcode, opcode_size);
509 return opcode_size;
510}
511
512Error
513ProcessPOSIX::EnableBreakpoint(BreakpointSite *bp_site)
514{
515 return EnableSoftwareBreakpoint(bp_site);
516}
517
518Error
519ProcessPOSIX::DisableBreakpoint(BreakpointSite *bp_site)
520{
521 return DisableSoftwareBreakpoint(bp_site);
522}
523
524uint32_t
525ProcessPOSIX::UpdateThreadListIfNeeded()
526{
527 // Do not allow recursive updates.
528 return m_thread_list.GetSize(false);
529}
530
Greg Claytonc8dd5702012-04-12 19:04:34 +0000531bool
Johnny Chen2341d352012-01-05 21:48:15 +0000532ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
533{
534 LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
535 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000536 log->Printf ("ProcessPOSIX::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID());
Johnny Chen2341d352012-01-05 21:48:15 +0000537
538 // Update the process thread list with this new thread.
539 // FIXME: We should be using tid, not pid.
540 assert(m_monitor);
541 ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
Greg Claytone5eaa302012-02-21 18:40:07 +0000542 if (!thread_sp) {
Greg Clayton5e91e372012-10-12 16:23:23 +0000543 thread_sp.reset(new POSIXThread(*this, GetID()));
Greg Claytone5eaa302012-02-21 18:40:07 +0000544 }
Johnny Chen2341d352012-01-05 21:48:15 +0000545
546 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000547 log->Printf ("ProcessPOSIX::%s() updated pid = %" PRIi64, __FUNCTION__, GetID());
Johnny Chen2341d352012-01-05 21:48:15 +0000548 new_thread_list.AddThread(thread_sp);
549
Greg Claytonc8dd5702012-04-12 19:04:34 +0000550 return new_thread_list.GetSize(false) > 0;
Johnny Chen2341d352012-01-05 21:48:15 +0000551}
552
553ByteOrder
554ProcessPOSIX::GetByteOrder() const
555{
556 // FIXME: We should be able to extract this value directly. See comment in
557 // ProcessPOSIX().
558 return m_byte_order;
559}
560
561size_t
562ProcessPOSIX::PutSTDIN(const char *buf, size_t len, Error &error)
563{
564 ssize_t status;
565 if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
566 {
567 error.SetErrorToErrno();
568 return 0;
569 }
570 return status;
571}
572
573size_t
574ProcessPOSIX::GetSTDOUT(char *buf, size_t len, Error &error)
575{
576 ssize_t bytes_read;
577
578 // The terminal file descriptor is always in non-block mode.
579 if ((bytes_read = read(m_monitor->GetTerminalFD(), buf, len)) < 0)
580 {
581 if (errno != EAGAIN)
582 error.SetErrorToErrno();
583 return 0;
584 }
585 return bytes_read;
586}
587
588size_t
589ProcessPOSIX::GetSTDERR(char *buf, size_t len, Error &error)
590{
591 return GetSTDOUT(buf, len, error);
592}
593
594UnixSignals &
595ProcessPOSIX::GetUnixSignals()
596{
597 return m_signals;
598}
599
600//------------------------------------------------------------------------------
601// Utility functions.
602
603bool
604ProcessPOSIX::HasExited()
605{
606 switch (GetPrivateState())
607 {
608 default:
609 break;
610
611 case eStateDetached:
612 case eStateExited:
613 return true;
614 }
615
616 return false;
617}
618
619bool
620ProcessPOSIX::IsStopped()
621{
622 switch (GetPrivateState())
623 {
624 default:
625 break;
626
627 case eStateStopped:
628 case eStateCrashed:
629 case eStateSuspended:
630 return true;
631 }
632
633 return false;
634}