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