blob: 5e6604458addbc66dc7822c4116d6bb477b72b09 [file] [log] [blame]
Johnny Chen9ed5b492012-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 Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Johnny Chen9ed5b492012-01-05 21:48:15 +000012// C Includes
13#include <errno.h>
14
15// C++ Includes
16// Other libraries and framework includes
Matt Kopece9ea0da2013-05-07 19:29:28 +000017#include "lldb/Breakpoint/Watchpoint.h"
Greg Claytondcbfd192012-09-04 14:55:50 +000018#include "lldb/Core/Module.h"
Johnny Chen9ed5b492012-01-05 21:48:15 +000019#include "lldb/Core/PluginManager.h"
20#include "lldb/Core/State.h"
Daniel Malea6217d2a2013-01-08 14:49:22 +000021#include "lldb/Host/FileSpec.h"
Johnny Chen9ed5b492012-01-05 21:48:15 +000022#include "lldb/Host/Host.h"
23#include "lldb/Symbol/ObjectFile.h"
24#include "lldb/Target/DynamicLoader.h"
Andrew Kaylorbf9b4c12013-05-07 22:46:38 +000025#include "lldb/Target/Platform.h"
Johnny Chen9ed5b492012-01-05 21:48:15 +000026#include "lldb/Target/Target.h"
27
28#include "ProcessPOSIX.h"
29#include "ProcessPOSIXLog.h"
30#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
31#include "ProcessMonitor.h"
32#include "POSIXThread.h"
33
34using namespace lldb;
35using namespace lldb_private;
36
37//------------------------------------------------------------------------------
38// Static functions.
39#if 0
40Process*
41ProcessPOSIX::CreateInstance(Target& target, Listener &listener)
42{
43 return new ProcessPOSIX(target, listener);
44}
45
46
47void
48ProcessPOSIX::Initialize()
49{
50 static bool g_initialized = false;
51
52 if (!g_initialized)
53 {
54 g_initialized = true;
55 PluginManager::RegisterPlugin(GetPluginNameStatic(),
56 GetPluginDescriptionStatic(),
57 CreateInstance);
58
59 Log::Callbacks log_callbacks = {
60 ProcessPOSIXLog::DisableLog,
61 ProcessPOSIXLog::EnableLog,
62 ProcessPOSIXLog::ListLogCategories
63 };
64
65 Log::RegisterLogChannel (ProcessPOSIX::GetPluginNameStatic(), log_callbacks);
66 }
67}
68#endif
69
70//------------------------------------------------------------------------------
71// Constructors and destructors.
72
73ProcessPOSIX::ProcessPOSIX(Target& target, Listener &listener)
74 : Process(target, listener),
Johnny Chen7b9f93a2012-04-14 00:54:42 +000075 m_byte_order(lldb::endian::InlHostByteOrder()),
Johnny Chen9ed5b492012-01-05 21:48:15 +000076 m_monitor(NULL),
77 m_module(NULL),
Andrew Kaylor93132f52013-05-28 23:04:25 +000078 m_message_mutex (Mutex::eMutexTypeRecursive),
Matt Kopecb2910442013-07-09 15:09:45 +000079 m_exit_now(false),
80 m_seen_initial_stop()
Johnny Chen9ed5b492012-01-05 21:48:15 +000081{
82 // FIXME: Putting this code in the ctor and saving the byte order in a
83 // member variable is a hack to avoid const qual issues in GetByteOrder.
Johnny Chen7b9f93a2012-04-14 00:54:42 +000084 lldb::ModuleSP module = GetTarget().GetExecutableModule();
Michael Sartaina7499c92013-07-01 19:45:50 +000085 if (module && module->GetObjectFile())
Johnny Chen7b9f93a2012-04-14 00:54:42 +000086 m_byte_order = module->GetObjectFile()->GetByteOrder();
Johnny Chen9ed5b492012-01-05 21:48:15 +000087}
88
89ProcessPOSIX::~ProcessPOSIX()
90{
91 delete m_monitor;
92}
93
94//------------------------------------------------------------------------------
95// Process protocol.
Andrew Kaylorbc68b432013-07-10 21:57:27 +000096void
97ProcessPOSIX::Finalize()
98{
99 Process::Finalize();
100
101 if (m_monitor)
102 m_monitor->StopMonitor();
103}
Johnny Chen9ed5b492012-01-05 21:48:15 +0000104
105bool
106ProcessPOSIX::CanDebug(Target &target, bool plugin_specified_by_name)
107{
108 // For now we are just making sure the file exists for a given module
109 ModuleSP exe_module_sp(target.GetExecutableModule());
110 if (exe_module_sp.get())
111 return exe_module_sp->GetFileSpec().Exists();
Andrew Kaylorbf9b4c12013-05-07 22:46:38 +0000112 // If there is no executable module, we return true since we might be preparing to attach.
113 return true;
Johnny Chen9ed5b492012-01-05 21:48:15 +0000114}
115
116Error
117ProcessPOSIX::DoAttachToProcessWithID(lldb::pid_t pid)
118{
119 Error error;
120 assert(m_monitor == NULL);
121
Ashok Thirumurthi01186352013-03-28 16:02:31 +0000122 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
Johnny Chen9ed5b492012-01-05 21:48:15 +0000123 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malead01b2952012-11-29 21:49:15 +0000124 log->Printf ("ProcessPOSIX::%s(pid = %" PRIi64 ")", __FUNCTION__, GetID());
Johnny Chen9ed5b492012-01-05 21:48:15 +0000125
Andrew Kaylor6578cb62013-07-09 22:36:48 +0000126 m_monitor = new ProcessMonitor(this, pid, error);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000127
128 if (!error.Success())
129 return error;
130
Andrew Kaylorbf9b4c12013-05-07 22:46:38 +0000131 PlatformSP platform_sp (m_target.GetPlatform ());
132 assert (platform_sp.get());
133 if (!platform_sp)
134 return error; // FIXME: Detatch?
135
136 // Find out what we can about this process
137 ProcessInstanceInfo process_info;
138 platform_sp->GetProcessInfo (pid, process_info);
139
140 // Resolve the executable module
141 ModuleSP exe_module_sp;
142 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
143 error = platform_sp->ResolveExecutable(process_info.GetExecutableFile(),
144 m_target.GetArchitecture(),
145 exe_module_sp,
146 executable_search_paths.GetSize() ? &executable_search_paths : NULL);
Ed Mastebe0b55d2013-07-04 18:25:34 +0000147 if (!error.Success())
148 return error;
Andrew Kaylorbf9b4c12013-05-07 22:46:38 +0000149
150 // Fix the target architecture if necessary
151 const ArchSpec &module_arch = exe_module_sp->GetArchitecture();
152 if (module_arch.IsValid() && !m_target.GetArchitecture().IsExactMatch(module_arch))
153 m_target.SetArchitecture(module_arch);
154
155 // Initialize the target module list
156 m_target.SetExecutableModule (exe_module_sp, true);
157
Andrew Kaylorbf9b4c12013-05-07 22:46:38 +0000158 SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
159
Johnny Chen9ed5b492012-01-05 21:48:15 +0000160 SetID(pid);
Andrew Kaylorbf9b4c12013-05-07 22:46:38 +0000161
Johnny Chen9ed5b492012-01-05 21:48:15 +0000162 return error;
163}
164
165Error
Greg Claytone2186ed2012-09-07 17:51:47 +0000166ProcessPOSIX::DoAttachToProcessWithID (lldb::pid_t pid, const ProcessAttachInfo &attach_info)
167{
168 return DoAttachToProcessWithID(pid);
169}
170
171Error
Johnny Chen9ed5b492012-01-05 21:48:15 +0000172ProcessPOSIX::WillLaunch(Module* module)
173{
174 Error error;
175 return error;
176}
177
178const char *
179ProcessPOSIX::GetFilePath(
180 const lldb_private::ProcessLaunchInfo::FileAction *file_action,
181 const char *default_path)
182{
183 const char *pts_name = "/dev/pts/";
184 const char *path = NULL;
185
186 if (file_action)
187 {
188 if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen)
189 path = file_action->GetPath();
190 // By default the stdio paths passed in will be pseudo-terminal
191 // (/dev/pts). If so, convert to using a different default path
192 // instead to redirect I/O to the debugger console. This should
193 // also handle user overrides to /dev/null or a different file.
194 if (::strncmp(path, pts_name, ::strlen(pts_name)) == 0)
195 path = default_path;
196 }
197
198 return path;
199}
200
201Error
202ProcessPOSIX::DoLaunch (Module *module,
203 const ProcessLaunchInfo &launch_info)
204{
205 Error error;
206 assert(m_monitor == NULL);
207
Daniel Malea6217d2a2013-01-08 14:49:22 +0000208 const char* working_dir = launch_info.GetWorkingDirectory();
209 if (working_dir) {
210 FileSpec WorkingDir(working_dir, true);
211 if (!WorkingDir || WorkingDir.GetFileType() != FileSpec::eFileTypeDirectory)
212 {
213 error.SetErrorStringWithFormat("No such file or directory: %s", working_dir);
214 return error;
215 }
216 }
217
Johnny Chen9ed5b492012-01-05 21:48:15 +0000218 SetPrivateState(eStateLaunching);
219
220 const lldb_private::ProcessLaunchInfo::FileAction *file_action;
221
222 // Default of NULL will mean to use existing open file descriptors
223 const char *stdin_path = NULL;
224 const char *stdout_path = NULL;
225 const char *stderr_path = NULL;
Daniel Malea6217d2a2013-01-08 14:49:22 +0000226
Johnny Chen9ed5b492012-01-05 21:48:15 +0000227 file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
228 stdin_path = GetFilePath(file_action, stdin_path);
229
230 file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
231 stdout_path = GetFilePath(file_action, stdout_path);
232
233 file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
234 stderr_path = GetFilePath(file_action, stderr_path);
235
Andrew Kaylor6578cb62013-07-09 22:36:48 +0000236 m_monitor = new ProcessMonitor (this,
Johnny Chen9ed5b492012-01-05 21:48:15 +0000237 module,
238 launch_info.GetArguments().GetConstArgumentVector(),
239 launch_info.GetEnvironmentEntries().GetConstArgumentVector(),
240 stdin_path,
241 stdout_path,
242 stderr_path,
Daniel Malea6217d2a2013-01-08 14:49:22 +0000243 working_dir,
Johnny Chen9ed5b492012-01-05 21:48:15 +0000244 error);
245
246 m_module = module;
247
248 if (!error.Success())
249 return error;
250
Matt Kopec9eb40a92013-03-14 21:35:26 +0000251 SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
252
Johnny Chen9ed5b492012-01-05 21:48:15 +0000253 SetID(m_monitor->GetPID());
254 return error;
255}
256
257void
258ProcessPOSIX::DidLaunch()
259{
260}
261
262Error
263ProcessPOSIX::DoResume()
264{
265 StateType state = GetPrivateState();
266
Matt Kopeceb7f2312013-06-26 18:46:08 +0000267 assert(state == eStateStopped);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000268
Matt Kopeceb7f2312013-06-26 18:46:08 +0000269 SetPrivateState(eStateRunning);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000270
271 bool did_resume = false;
Daniel Maleaa2cb9c42013-07-24 21:44:30 +0000272
273 Mutex::Locker lock(m_thread_list.GetMutex());
274
Johnny Chen9ed5b492012-01-05 21:48:15 +0000275 uint32_t thread_count = m_thread_list.GetSize(false);
276 for (uint32_t i = 0; i < thread_count; ++i)
277 {
278 POSIXThread *thread = static_cast<POSIXThread*>(
279 m_thread_list.GetThreadAtIndex(i, false).get());
280 did_resume = thread->Resume() || did_resume;
281 }
282 assert(did_resume && "Process resume failed!");
283
284 return Error();
285}
286
287addr_t
288ProcessPOSIX::GetImageInfoAddress()
289{
290 Target *target = &GetTarget();
291 ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
292 Address addr = obj_file->GetImageInfoAddress();
293
294 if (addr.IsValid())
295 return addr.GetLoadAddress(target);
296 else
297 return LLDB_INVALID_ADDRESS;
298}
299
300Error
301ProcessPOSIX::DoHalt(bool &caused_stop)
302{
303 Error error;
304
305 if (IsStopped())
306 {
307 caused_stop = false;
308 }
309 else if (kill(GetID(), SIGSTOP))
310 {
311 caused_stop = false;
312 error.SetErrorToErrno();
313 }
314 else
315 {
316 caused_stop = true;
317 }
Johnny Chen9ed5b492012-01-05 21:48:15 +0000318 return error;
319}
320
321Error
Johnny Chen9ed5b492012-01-05 21:48:15 +0000322ProcessPOSIX::DoSignal(int signal)
323{
324 Error error;
325
326 if (kill(GetID(), signal))
327 error.SetErrorToErrno();
328
329 return error;
330}
331
332Error
333ProcessPOSIX::DoDestroy()
334{
335 Error error;
336
337 if (!HasExited())
338 {
339 // Drive the exit event to completion (do not keep the inferior in
340 // limbo).
341 m_exit_now = true;
342
Greg Claytonab950c32012-03-30 19:56:32 +0000343 if ((m_monitor == NULL || kill(m_monitor->GetPID(), SIGKILL)) && error.Success())
Johnny Chen9ed5b492012-01-05 21:48:15 +0000344 {
345 error.SetErrorToErrno();
346 return error;
347 }
348
349 SetPrivateState(eStateExited);
350 }
351
352 return error;
353}
354
355void
356ProcessPOSIX::SendMessage(const ProcessMessage &message)
357{
358 Mutex::Locker lock(m_message_mutex);
359
Daniel Maleaa2cb9c42013-07-24 21:44:30 +0000360 Mutex::Locker thread_lock(m_thread_list.GetMutex());
361
Andrew Kaylor93132f52013-05-28 23:04:25 +0000362 POSIXThread *thread = static_cast<POSIXThread*>(
363 m_thread_list.FindThreadByID(message.GetTID(), false).get());
364
Johnny Chen9ed5b492012-01-05 21:48:15 +0000365 switch (message.GetKind())
366 {
Johnny Chen9ed5b492012-01-05 21:48:15 +0000367 case ProcessMessage::eInvalidMessage:
368 return;
369
Ed Mastee5441432013-09-03 23:55:30 +0000370 case ProcessMessage::eAttachMessage:
371 SetPrivateState(eStateStopped);
372 return;
373
Johnny Chen9ed5b492012-01-05 21:48:15 +0000374 case ProcessMessage::eLimboMessage:
Andrew Kaylor93132f52013-05-28 23:04:25 +0000375 assert(thread);
376 thread->SetState(eStateStopped);
377 if (message.GetTID() == GetID())
Johnny Chen9ed5b492012-01-05 21:48:15 +0000378 {
Andrew Kaylor93132f52013-05-28 23:04:25 +0000379 m_exit_status = message.GetExitStatus();
380 if (m_exit_now)
381 {
382 SetPrivateState(eStateExited);
Matt Kopec085d6ce2013-05-31 22:00:07 +0000383 m_monitor->Detach(GetID());
Andrew Kaylor93132f52013-05-28 23:04:25 +0000384 }
385 else
386 {
387 StopAllThreads(message.GetTID());
388 SetPrivateState(eStateStopped);
389 }
Johnny Chen9ed5b492012-01-05 21:48:15 +0000390 }
391 else
Andrew Kaylor93132f52013-05-28 23:04:25 +0000392 {
393 StopAllThreads(message.GetTID());
Johnny Chen9ed5b492012-01-05 21:48:15 +0000394 SetPrivateState(eStateStopped);
Andrew Kaylor93132f52013-05-28 23:04:25 +0000395 }
Johnny Chen9ed5b492012-01-05 21:48:15 +0000396 break;
397
398 case ProcessMessage::eExitMessage:
Andrew Kaylor93132f52013-05-28 23:04:25 +0000399 assert(thread);
400 thread->SetState(eStateExited);
401 // FIXME: I'm not sure we need to do this.
402 if (message.GetTID() == GetID())
403 {
404 m_exit_status = message.GetExitStatus();
405 SetExitStatus(m_exit_status, NULL);
406 }
Matt Kopecb2910442013-07-09 15:09:45 +0000407 else if (!IsAThreadRunning())
408 SetPrivateState(eStateStopped);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000409 break;
410
Matt Kopecb2910442013-07-09 15:09:45 +0000411 case ProcessMessage::eSignalMessage:
412 case ProcessMessage::eSignalDeliveredMessage:
413 if (message.GetSignal() == SIGSTOP &&
414 AddThreadForInitialStopIfNeeded(message.GetTID()))
415 return;
416 // Intentional fall-through
417
Johnny Chen9ed5b492012-01-05 21:48:15 +0000418 case ProcessMessage::eBreakpointMessage:
Andrew Kaylor93132f52013-05-28 23:04:25 +0000419 case ProcessMessage::eTraceMessage:
Matt Kopece9ea0da2013-05-07 19:29:28 +0000420 case ProcessMessage::eWatchpointMessage:
Andrew Kaylor93132f52013-05-28 23:04:25 +0000421 case ProcessMessage::eCrashMessage:
422 assert(thread);
423 thread->SetState(eStateStopped);
424 StopAllThreads(message.GetTID());
Johnny Chen9ed5b492012-01-05 21:48:15 +0000425 SetPrivateState(eStateStopped);
426 break;
Andrew Kaylord4d54992013-09-17 00:30:24 +0000427
428 case ProcessMessage::eNewThreadMessage:
429 {
430 lldb::tid_t new_tid = message.GetChildTID();
431 if (WaitingForInitialStop(new_tid))
432 {
433 m_monitor->WaitForInitialTIDStop(new_tid);
434 }
435 assert(thread);
436 thread->SetState(eStateStopped);
437 StopAllThreads(message.GetTID());
438 SetPrivateState(eStateStopped);
439 break;
440 }
Johnny Chen9ed5b492012-01-05 21:48:15 +0000441 }
442
443 m_message_queue.push(message);
444}
445
Andrew Kaylor93132f52013-05-28 23:04:25 +0000446void
447ProcessPOSIX::StopAllThreads(lldb::tid_t stop_tid)
448{
449 // FIXME: Will this work the same way on FreeBSD and Linux?
450}
451
Matt Kopecb2910442013-07-09 15:09:45 +0000452bool
453ProcessPOSIX::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid)
454{
455 bool added_to_set = false;
456 ThreadStopSet::iterator it = m_seen_initial_stop.find(stop_tid);
457 if (it == m_seen_initial_stop.end())
458 {
459 m_seen_initial_stop.insert(stop_tid);
460 added_to_set = true;
461 }
462 return added_to_set;
463}
464
Andrew Kaylord4d54992013-09-17 00:30:24 +0000465bool
466ProcessPOSIX::WaitingForInitialStop(lldb::tid_t stop_tid)
467{
468 return (m_seen_initial_stop.find(stop_tid) == m_seen_initial_stop.end());
469}
470
Michael Sartain9f822cd2013-07-31 23:27:46 +0000471POSIXThread *
472ProcessPOSIX::CreateNewPOSIXThread(lldb_private::Process &process, lldb::tid_t tid)
473{
474 return new POSIXThread(process, tid);
475}
476
Johnny Chen9ed5b492012-01-05 21:48:15 +0000477void
478ProcessPOSIX::RefreshStateAfterStop()
479{
Ashok Thirumurthi01186352013-03-28 16:02:31 +0000480 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
Johnny Chen9ed5b492012-01-05 21:48:15 +0000481 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Andrew Kaylor93132f52013-05-28 23:04:25 +0000482 log->Printf ("ProcessPOSIX::%s(), message_queue size = %d", __FUNCTION__, (int)m_message_queue.size());
Johnny Chen9ed5b492012-01-05 21:48:15 +0000483
484 Mutex::Locker lock(m_message_mutex);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000485
Andrew Kaylor93132f52013-05-28 23:04:25 +0000486 // This method used to only handle one message. Changing it to loop allows
487 // it to handle the case where we hit a breakpoint while handling a different
488 // breakpoint.
489 while (!m_message_queue.empty())
490 {
491 ProcessMessage &message = m_message_queue.front();
Johnny Chen9ed5b492012-01-05 21:48:15 +0000492
Andrew Kaylor93132f52013-05-28 23:04:25 +0000493 // Resolve the thread this message corresponds to and pass it along.
494 lldb::tid_t tid = message.GetTID();
495 if (log)
496 log->Printf ("ProcessPOSIX::%s(), message_queue size = %d, pid = %" PRIi64, __FUNCTION__, (int)m_message_queue.size(), tid);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000497
Andrew Kaylor93132f52013-05-28 23:04:25 +0000498 if (message.GetKind() == ProcessMessage::eNewThreadMessage)
499 {
500 if (log)
501 log->Printf ("ProcessPOSIX::%s() adding thread, tid = %" PRIi64, __FUNCTION__, message.GetChildTID());
Matt Kopecfb6ab542013-07-10 20:53:11 +0000502 lldb::tid_t child_tid = message.GetChildTID();
Andrew Kaylor93132f52013-05-28 23:04:25 +0000503 ThreadSP thread_sp;
Michael Sartain9f822cd2013-07-31 23:27:46 +0000504 thread_sp.reset(CreateNewPOSIXThread(*this, child_tid));
Matt Kopecfb6ab542013-07-10 20:53:11 +0000505
Daniel Maleaa2cb9c42013-07-24 21:44:30 +0000506 Mutex::Locker lock(m_thread_list.GetMutex());
507
Andrew Kaylor93132f52013-05-28 23:04:25 +0000508 m_thread_list.AddThread(thread_sp);
509 }
510
511 m_thread_list.RefreshStateAfterStop();
512
Ed Maste685fea92013-08-29 20:40:11 +0000513 POSIXThread *thread = static_cast<POSIXThread*>(
514 GetThreadList().FindThreadByID(tid, false).get());
Andrew Kaylor93132f52013-05-28 23:04:25 +0000515 if (thread)
516 thread->Notify(message);
517
518 if (message.GetKind() == ProcessMessage::eExitMessage)
519 {
520 // FIXME: We should tell the user about this, but the limbo message is probably better for that.
521 if (log)
522 log->Printf ("ProcessPOSIX::%s() removing thread, tid = %" PRIi64, __FUNCTION__, tid);
Daniel Maleaa2cb9c42013-07-24 21:44:30 +0000523
524 Mutex::Locker lock(m_thread_list.GetMutex());
525
Andrew Kaylor93132f52013-05-28 23:04:25 +0000526 ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false);
527 thread_sp.reset();
Matt Kopecb2910442013-07-09 15:09:45 +0000528 m_seen_initial_stop.erase(tid);
Andrew Kaylor93132f52013-05-28 23:04:25 +0000529 }
530
531 m_message_queue.pop();
Matt Kopec650648f2013-01-08 16:30:18 +0000532 }
Johnny Chen9ed5b492012-01-05 21:48:15 +0000533}
534
535bool
536ProcessPOSIX::IsAlive()
537{
538 StateType state = GetPrivateState();
Daniel Malea335bf6f2013-04-01 19:48:37 +0000539 return state != eStateDetached
540 && state != eStateExited
541 && state != eStateInvalid
542 && state != eStateUnloaded;
Johnny Chen9ed5b492012-01-05 21:48:15 +0000543}
544
545size_t
546ProcessPOSIX::DoReadMemory(addr_t vm_addr,
547 void *buf, size_t size, Error &error)
548{
549 assert(m_monitor);
550 return m_monitor->ReadMemory(vm_addr, buf, size, error);
551}
552
553size_t
554ProcessPOSIX::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
555 Error &error)
556{
557 assert(m_monitor);
558 return m_monitor->WriteMemory(vm_addr, buf, size, error);
559}
560
561addr_t
562ProcessPOSIX::DoAllocateMemory(size_t size, uint32_t permissions,
563 Error &error)
564{
565 addr_t allocated_addr = LLDB_INVALID_ADDRESS;
566
567 unsigned prot = 0;
568 if (permissions & lldb::ePermissionsReadable)
569 prot |= eMmapProtRead;
570 if (permissions & lldb::ePermissionsWritable)
571 prot |= eMmapProtWrite;
572 if (permissions & lldb::ePermissionsExecutable)
573 prot |= eMmapProtExec;
574
575 if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
576 eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
577 m_addr_to_mmap_size[allocated_addr] = size;
578 error.Clear();
579 } else {
580 allocated_addr = LLDB_INVALID_ADDRESS;
581 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
582 }
583
584 return allocated_addr;
585}
586
587Error
588ProcessPOSIX::DoDeallocateMemory(lldb::addr_t addr)
589{
590 Error error;
591 MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
592 if (pos != m_addr_to_mmap_size.end() &&
593 InferiorCallMunmap(this, addr, pos->second))
594 m_addr_to_mmap_size.erase (pos);
595 else
Daniel Malead01b2952012-11-29 21:49:15 +0000596 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000597
598 return error;
599}
600
Matt Kopec00049b82013-02-27 20:13:38 +0000601addr_t
602ProcessPOSIX::ResolveIndirectFunction(const Address *address, Error &error)
603{
604 addr_t function_addr = LLDB_INVALID_ADDRESS;
605 if (address == NULL) {
606 error.SetErrorStringWithFormat("unable to determine direct function call for NULL address");
607 } else if (!InferiorCall(this, address, function_addr)) {
608 function_addr = LLDB_INVALID_ADDRESS;
Matt Kopec66fd4b12013-03-01 17:44:31 +0000609 error.SetErrorStringWithFormat("unable to determine direct function call for indirect function %s",
610 address->CalculateSymbolContextSymbol()->GetName().AsCString());
Matt Kopec00049b82013-02-27 20:13:38 +0000611 }
612 return function_addr;
613}
614
Johnny Chen9ed5b492012-01-05 21:48:15 +0000615size_t
616ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
617{
618 static const uint8_t g_i386_opcode[] = { 0xCC };
619
620 ArchSpec arch = GetTarget().GetArchitecture();
621 const uint8_t *opcode = NULL;
622 size_t opcode_size = 0;
623
624 switch (arch.GetCore())
625 {
626 default:
627 assert(false && "CPU type not supported!");
628 break;
629
630 case ArchSpec::eCore_x86_32_i386:
631 case ArchSpec::eCore_x86_64_x86_64:
632 opcode = g_i386_opcode;
633 opcode_size = sizeof(g_i386_opcode);
634 break;
635 }
636
637 bp_site->SetTrapOpcode(opcode, opcode_size);
638 return opcode_size;
639}
640
641Error
Daniel Maleab7eec012013-02-15 20:23:25 +0000642ProcessPOSIX::EnableBreakpointSite(BreakpointSite *bp_site)
Johnny Chen9ed5b492012-01-05 21:48:15 +0000643{
644 return EnableSoftwareBreakpoint(bp_site);
645}
646
647Error
Daniel Maleab7eec012013-02-15 20:23:25 +0000648ProcessPOSIX::DisableBreakpointSite(BreakpointSite *bp_site)
Johnny Chen9ed5b492012-01-05 21:48:15 +0000649{
650 return DisableSoftwareBreakpoint(bp_site);
651}
652
Matt Kopece9ea0da2013-05-07 19:29:28 +0000653Error
654ProcessPOSIX::EnableWatchpoint(Watchpoint *wp, bool notify)
655{
656 Error error;
657 if (wp)
658 {
659 user_id_t watchID = wp->GetID();
660 addr_t addr = wp->GetLoadAddress();
661 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
662 if (log)
663 log->Printf ("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64 ")",
664 watchID);
665 if (wp->IsEnabled())
666 {
667 if (log)
668 log->Printf("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64
669 ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
670 watchID, (uint64_t)addr);
671 return error;
672 }
673
Matt Kopec6f961232013-06-03 17:40:20 +0000674 // Try to find a vacant watchpoint slot in the inferiors' main thread
675 uint32_t wp_hw_index = LLDB_INVALID_INDEX32;
Daniel Maleaa2cb9c42013-07-24 21:44:30 +0000676 Mutex::Locker lock(m_thread_list.GetMutex());
Matt Kopec6f961232013-06-03 17:40:20 +0000677 POSIXThread *thread = static_cast<POSIXThread*>(
678 m_thread_list.GetThreadAtIndex(0, false).get());
679
680 if (thread)
681 wp_hw_index = thread->FindVacantWatchpointIndex();
682
683 if (wp_hw_index == LLDB_INVALID_INDEX32)
Matt Kopece9ea0da2013-05-07 19:29:28 +0000684 {
Matt Kopec6f961232013-06-03 17:40:20 +0000685 error.SetErrorString("Setting hardware watchpoint failed.");
Matt Kopece9ea0da2013-05-07 19:29:28 +0000686 }
687 else
688 {
Matt Kopec6f961232013-06-03 17:40:20 +0000689 wp->SetHardwareIndex(wp_hw_index);
690 bool wp_enabled = true;
691 uint32_t thread_count = m_thread_list.GetSize(false);
692 for (uint32_t i = 0; i < thread_count; ++i)
693 {
694 thread = static_cast<POSIXThread*>(
695 m_thread_list.GetThreadAtIndex(i, false).get());
696 if (thread)
697 wp_enabled &= thread->EnableHardwareWatchpoint(wp);
698 else
699 wp_enabled = false;
700 }
701 if (wp_enabled)
702 {
703 wp->SetEnabled(true, notify);
704 return error;
705 }
706 else
707 {
708 // Watchpoint enabling failed on at least one
709 // of the threads so roll back all of them
710 DisableWatchpoint(wp, false);
711 error.SetErrorString("Setting hardware watchpoint failed");
712 }
Matt Kopece9ea0da2013-05-07 19:29:28 +0000713 }
714 }
715 else
716 error.SetErrorString("Watchpoint argument was NULL.");
717 return error;
718}
719
720Error
721ProcessPOSIX::DisableWatchpoint(Watchpoint *wp, bool notify)
722{
723 Error error;
724 if (wp)
725 {
726 user_id_t watchID = wp->GetID();
727 addr_t addr = wp->GetLoadAddress();
728 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
729 if (log)
730 log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64 ")",
731 watchID);
732 if (!wp->IsEnabled())
733 {
734 if (log)
735 log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64
736 ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
737 watchID, (uint64_t)addr);
738 // This is needed (for now) to keep watchpoints disabled correctly
739 wp->SetEnabled(false, notify);
740 return error;
741 }
742
743 if (wp->IsHardware())
744 {
745 bool wp_disabled = true;
Daniel Maleaa2cb9c42013-07-24 21:44:30 +0000746 Mutex::Locker lock(m_thread_list.GetMutex());
Matt Kopece9ea0da2013-05-07 19:29:28 +0000747 uint32_t thread_count = m_thread_list.GetSize(false);
748 for (uint32_t i = 0; i < thread_count; ++i)
749 {
750 POSIXThread *thread = static_cast<POSIXThread*>(
751 m_thread_list.GetThreadAtIndex(i, false).get());
752 if (thread)
753 wp_disabled &= thread->DisableHardwareWatchpoint(wp);
754 else
755 wp_disabled = false;
756 }
757 if (wp_disabled)
758 {
Matt Kopec6f961232013-06-03 17:40:20 +0000759 wp->SetHardwareIndex(LLDB_INVALID_INDEX32);
Matt Kopece9ea0da2013-05-07 19:29:28 +0000760 wp->SetEnabled(false, notify);
761 return error;
762 }
763 else
764 error.SetErrorString("Disabling hardware watchpoint failed");
765 }
766 }
767 else
768 error.SetErrorString("Watchpoint argument was NULL.");
769 return error;
770}
771
772Error
773ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num)
774{
775 Error error;
Daniel Maleaa2cb9c42013-07-24 21:44:30 +0000776 Mutex::Locker lock(m_thread_list.GetMutex());
Matt Kopece9ea0da2013-05-07 19:29:28 +0000777 POSIXThread *thread = static_cast<POSIXThread*>(
778 m_thread_list.GetThreadAtIndex(0, false).get());
779 if (thread)
780 num = thread->NumSupportedHardwareWatchpoints();
781 else
782 error.SetErrorString("Process does not exist.");
783 return error;
784}
785
786Error
787ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num, bool &after)
788{
789 Error error = GetWatchpointSupportInfo(num);
790 // Watchpoints trigger and halt the inferior after
791 // the corresponding instruction has been executed.
792 after = true;
793 return error;
794}
795
Johnny Chen9ed5b492012-01-05 21:48:15 +0000796uint32_t
797ProcessPOSIX::UpdateThreadListIfNeeded()
798{
Daniel Maleaa2cb9c42013-07-24 21:44:30 +0000799 Mutex::Locker lock(m_thread_list.GetMutex());
Johnny Chen9ed5b492012-01-05 21:48:15 +0000800 // Do not allow recursive updates.
801 return m_thread_list.GetSize(false);
802}
803
Greg Claytonc3c0b0e2012-04-12 19:04:34 +0000804bool
Johnny Chen9ed5b492012-01-05 21:48:15 +0000805ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
806{
Ashok Thirumurthi01186352013-03-28 16:02:31 +0000807 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
Johnny Chen9ed5b492012-01-05 21:48:15 +0000808 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malead01b2952012-11-29 21:49:15 +0000809 log->Printf ("ProcessPOSIX::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID());
Johnny Chen9ed5b492012-01-05 21:48:15 +0000810
Daniel Maleae0f8f572013-08-26 23:57:52 +0000811 bool has_updated = false;
Johnny Chen9ed5b492012-01-05 21:48:15 +0000812 // Update the process thread list with this new thread.
813 // FIXME: We should be using tid, not pid.
814 assert(m_monitor);
815 ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
Greg Clayton0c90ef42012-02-21 18:40:07 +0000816 if (!thread_sp) {
Michael Sartain9f822cd2013-07-31 23:27:46 +0000817 thread_sp.reset(CreateNewPOSIXThread(*this, GetID()));
Daniel Maleae0f8f572013-08-26 23:57:52 +0000818 has_updated = true;
Greg Clayton0c90ef42012-02-21 18:40:07 +0000819 }
Johnny Chen9ed5b492012-01-05 21:48:15 +0000820
821 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malead01b2952012-11-29 21:49:15 +0000822 log->Printf ("ProcessPOSIX::%s() updated pid = %" PRIi64, __FUNCTION__, GetID());
Johnny Chen9ed5b492012-01-05 21:48:15 +0000823 new_thread_list.AddThread(thread_sp);
824
Daniel Maleae0f8f572013-08-26 23:57:52 +0000825 return has_updated; // the list has been updated
Johnny Chen9ed5b492012-01-05 21:48:15 +0000826}
827
828ByteOrder
829ProcessPOSIX::GetByteOrder() const
830{
831 // FIXME: We should be able to extract this value directly. See comment in
832 // ProcessPOSIX().
833 return m_byte_order;
834}
835
836size_t
837ProcessPOSIX::PutSTDIN(const char *buf, size_t len, Error &error)
838{
839 ssize_t status;
840 if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
841 {
842 error.SetErrorToErrno();
843 return 0;
844 }
845 return status;
846}
847
Johnny Chen9ed5b492012-01-05 21:48:15 +0000848UnixSignals &
849ProcessPOSIX::GetUnixSignals()
850{
851 return m_signals;
852}
853
854//------------------------------------------------------------------------------
855// Utility functions.
856
857bool
858ProcessPOSIX::HasExited()
859{
860 switch (GetPrivateState())
861 {
862 default:
863 break;
864
865 case eStateDetached:
866 case eStateExited:
867 return true;
868 }
869
870 return false;
871}
872
873bool
874ProcessPOSIX::IsStopped()
875{
876 switch (GetPrivateState())
877 {
878 default:
879 break;
880
881 case eStateStopped:
882 case eStateCrashed:
883 case eStateSuspended:
884 return true;
885 }
886
887 return false;
888}
Matt Kopecb2910442013-07-09 15:09:45 +0000889
890bool
891ProcessPOSIX::IsAThreadRunning()
892{
893 bool is_running = false;
Daniel Maleaa2cb9c42013-07-24 21:44:30 +0000894 Mutex::Locker lock(m_thread_list.GetMutex());
Matt Kopecb2910442013-07-09 15:09:45 +0000895 uint32_t thread_count = m_thread_list.GetSize(false);
896 for (uint32_t i = 0; i < thread_count; ++i)
897 {
898 POSIXThread *thread = static_cast<POSIXThread*>(
899 m_thread_list.GetThreadAtIndex(i, false).get());
900 StateType thread_state = thread->GetState();
901 if (thread_state == eStateRunning || thread_state == eStateStepping)
902 {
903 is_running = true;
904 break;
905 }
906 }
907 return is_running;
908}