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