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