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