blob: d55609a7b8722e26eaeeb98c1e61a4cb33ed8bbc [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.
96
97bool
98ProcessPOSIX::CanDebug(Target &target, bool plugin_specified_by_name)
99{
100 // For now we are just making sure the file exists for a given module
101 ModuleSP exe_module_sp(target.GetExecutableModule());
102 if (exe_module_sp.get())
103 return exe_module_sp->GetFileSpec().Exists();
Andrew Kaylorbf9b4c12013-05-07 22:46:38 +0000104 // If there is no executable module, we return true since we might be preparing to attach.
105 return true;
Johnny Chen9ed5b492012-01-05 21:48:15 +0000106}
107
108Error
109ProcessPOSIX::DoAttachToProcessWithID(lldb::pid_t pid)
110{
111 Error error;
112 assert(m_monitor == NULL);
113
Ashok Thirumurthi01186352013-03-28 16:02:31 +0000114 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
Johnny Chen9ed5b492012-01-05 21:48:15 +0000115 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malead01b2952012-11-29 21:49:15 +0000116 log->Printf ("ProcessPOSIX::%s(pid = %" PRIi64 ")", __FUNCTION__, GetID());
Johnny Chen9ed5b492012-01-05 21:48:15 +0000117
Andrew Kaylor6578cb62013-07-09 22:36:48 +0000118 m_monitor = new ProcessMonitor(this, pid, error);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000119
120 if (!error.Success())
121 return error;
122
Andrew Kaylorbf9b4c12013-05-07 22:46:38 +0000123 PlatformSP platform_sp (m_target.GetPlatform ());
124 assert (platform_sp.get());
125 if (!platform_sp)
126 return error; // FIXME: Detatch?
127
128 // Find out what we can about this process
129 ProcessInstanceInfo process_info;
130 platform_sp->GetProcessInfo (pid, process_info);
131
132 // Resolve the executable module
133 ModuleSP exe_module_sp;
134 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
135 error = platform_sp->ResolveExecutable(process_info.GetExecutableFile(),
136 m_target.GetArchitecture(),
137 exe_module_sp,
138 executable_search_paths.GetSize() ? &executable_search_paths : NULL);
Ed Mastebe0b55d2013-07-04 18:25:34 +0000139 if (!error.Success())
140 return error;
Andrew Kaylorbf9b4c12013-05-07 22:46:38 +0000141
142 // Fix the target architecture if necessary
143 const ArchSpec &module_arch = exe_module_sp->GetArchitecture();
144 if (module_arch.IsValid() && !m_target.GetArchitecture().IsExactMatch(module_arch))
145 m_target.SetArchitecture(module_arch);
146
147 // Initialize the target module list
148 m_target.SetExecutableModule (exe_module_sp, true);
149
Andrew Kaylorbf9b4c12013-05-07 22:46:38 +0000150 SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
151
Johnny Chen9ed5b492012-01-05 21:48:15 +0000152 SetID(pid);
Andrew Kaylorbf9b4c12013-05-07 22:46:38 +0000153
Johnny Chen9ed5b492012-01-05 21:48:15 +0000154 return error;
155}
156
157Error
Greg Claytone2186ed2012-09-07 17:51:47 +0000158ProcessPOSIX::DoAttachToProcessWithID (lldb::pid_t pid, const ProcessAttachInfo &attach_info)
159{
160 return DoAttachToProcessWithID(pid);
161}
162
163Error
Johnny Chen9ed5b492012-01-05 21:48:15 +0000164ProcessPOSIX::WillLaunch(Module* module)
165{
166 Error error;
167 return error;
168}
169
170const char *
171ProcessPOSIX::GetFilePath(
172 const lldb_private::ProcessLaunchInfo::FileAction *file_action,
173 const char *default_path)
174{
175 const char *pts_name = "/dev/pts/";
176 const char *path = NULL;
177
178 if (file_action)
179 {
180 if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen)
181 path = file_action->GetPath();
182 // By default the stdio paths passed in will be pseudo-terminal
183 // (/dev/pts). If so, convert to using a different default path
184 // instead to redirect I/O to the debugger console. This should
185 // also handle user overrides to /dev/null or a different file.
186 if (::strncmp(path, pts_name, ::strlen(pts_name)) == 0)
187 path = default_path;
188 }
189
190 return path;
191}
192
193Error
194ProcessPOSIX::DoLaunch (Module *module,
195 const ProcessLaunchInfo &launch_info)
196{
197 Error error;
198 assert(m_monitor == NULL);
199
Daniel Malea6217d2a2013-01-08 14:49:22 +0000200 const char* working_dir = launch_info.GetWorkingDirectory();
201 if (working_dir) {
202 FileSpec WorkingDir(working_dir, true);
203 if (!WorkingDir || WorkingDir.GetFileType() != FileSpec::eFileTypeDirectory)
204 {
205 error.SetErrorStringWithFormat("No such file or directory: %s", working_dir);
206 return error;
207 }
208 }
209
Johnny Chen9ed5b492012-01-05 21:48:15 +0000210 SetPrivateState(eStateLaunching);
211
212 const lldb_private::ProcessLaunchInfo::FileAction *file_action;
213
214 // Default of NULL will mean to use existing open file descriptors
215 const char *stdin_path = NULL;
216 const char *stdout_path = NULL;
217 const char *stderr_path = NULL;
Daniel Malea6217d2a2013-01-08 14:49:22 +0000218
Johnny Chen9ed5b492012-01-05 21:48:15 +0000219 file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
220 stdin_path = GetFilePath(file_action, stdin_path);
221
222 file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
223 stdout_path = GetFilePath(file_action, stdout_path);
224
225 file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
226 stderr_path = GetFilePath(file_action, stderr_path);
227
Andrew Kaylor6578cb62013-07-09 22:36:48 +0000228 m_monitor = new ProcessMonitor (this,
Johnny Chen9ed5b492012-01-05 21:48:15 +0000229 module,
230 launch_info.GetArguments().GetConstArgumentVector(),
231 launch_info.GetEnvironmentEntries().GetConstArgumentVector(),
232 stdin_path,
233 stdout_path,
234 stderr_path,
Daniel Malea6217d2a2013-01-08 14:49:22 +0000235 working_dir,
Johnny Chen9ed5b492012-01-05 21:48:15 +0000236 error);
237
238 m_module = module;
239
240 if (!error.Success())
241 return error;
242
Matt Kopec9eb40a92013-03-14 21:35:26 +0000243 SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
244
Johnny Chen9ed5b492012-01-05 21:48:15 +0000245 SetID(m_monitor->GetPID());
246 return error;
247}
248
249void
250ProcessPOSIX::DidLaunch()
251{
252}
253
254Error
255ProcessPOSIX::DoResume()
256{
257 StateType state = GetPrivateState();
258
Matt Kopeceb7f2312013-06-26 18:46:08 +0000259 assert(state == eStateStopped);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000260
Matt Kopeceb7f2312013-06-26 18:46:08 +0000261 SetPrivateState(eStateRunning);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000262
263 bool did_resume = false;
264 uint32_t thread_count = m_thread_list.GetSize(false);
265 for (uint32_t i = 0; i < thread_count; ++i)
266 {
267 POSIXThread *thread = static_cast<POSIXThread*>(
268 m_thread_list.GetThreadAtIndex(i, false).get());
269 did_resume = thread->Resume() || did_resume;
270 }
271 assert(did_resume && "Process resume failed!");
272
273 return Error();
274}
275
276addr_t
277ProcessPOSIX::GetImageInfoAddress()
278{
279 Target *target = &GetTarget();
280 ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
281 Address addr = obj_file->GetImageInfoAddress();
282
283 if (addr.IsValid())
284 return addr.GetLoadAddress(target);
285 else
286 return LLDB_INVALID_ADDRESS;
287}
288
289Error
290ProcessPOSIX::DoHalt(bool &caused_stop)
291{
292 Error error;
293
294 if (IsStopped())
295 {
296 caused_stop = false;
297 }
298 else if (kill(GetID(), SIGSTOP))
299 {
300 caused_stop = false;
301 error.SetErrorToErrno();
302 }
303 else
304 {
305 caused_stop = true;
306 }
Johnny Chen9ed5b492012-01-05 21:48:15 +0000307 return error;
308}
309
310Error
Jim Inghamacff8952013-05-02 00:27:30 +0000311ProcessPOSIX::DoDetach(bool keep_stopped)
Johnny Chen9ed5b492012-01-05 21:48:15 +0000312{
313 Error error;
Jim Inghamacff8952013-05-02 00:27:30 +0000314 if (keep_stopped)
315 {
Ed Maste18757762013-07-03 16:26:34 +0000316 // FIXME: If you want to implement keep_stopped,
Jim Inghamacff8952013-05-02 00:27:30 +0000317 // this would be the place to do it.
Ed Maste18757762013-07-03 16:26:34 +0000318 error.SetErrorString("Detaching with keep_stopped true is not currently supported on this platform.");
Jim Inghamacff8952013-05-02 00:27:30 +0000319 return error;
320 }
Johnny Chen9ed5b492012-01-05 21:48:15 +0000321
Matt Kopec085d6ce2013-05-31 22:00:07 +0000322 uint32_t thread_count = m_thread_list.GetSize(false);
323 for (uint32_t i = 0; i < thread_count; ++i)
324 {
325 POSIXThread *thread = static_cast<POSIXThread*>(
326 m_thread_list.GetThreadAtIndex(i, false).get());
327 error = m_monitor->Detach(thread->GetID());
328 }
329
Johnny Chen9ed5b492012-01-05 21:48:15 +0000330 if (error.Success())
331 SetPrivateState(eStateDetached);
332
333 return error;
334}
335
336Error
337ProcessPOSIX::DoSignal(int signal)
338{
339 Error error;
340
341 if (kill(GetID(), signal))
342 error.SetErrorToErrno();
343
344 return error;
345}
346
347Error
348ProcessPOSIX::DoDestroy()
349{
350 Error error;
351
352 if (!HasExited())
353 {
354 // Drive the exit event to completion (do not keep the inferior in
355 // limbo).
356 m_exit_now = true;
357
Greg Claytonab950c32012-03-30 19:56:32 +0000358 if ((m_monitor == NULL || kill(m_monitor->GetPID(), SIGKILL)) && error.Success())
Johnny Chen9ed5b492012-01-05 21:48:15 +0000359 {
360 error.SetErrorToErrno();
361 return error;
362 }
363
364 SetPrivateState(eStateExited);
365 }
366
367 return error;
368}
369
370void
371ProcessPOSIX::SendMessage(const ProcessMessage &message)
372{
373 Mutex::Locker lock(m_message_mutex);
374
Andrew Kaylor93132f52013-05-28 23:04:25 +0000375 POSIXThread *thread = static_cast<POSIXThread*>(
376 m_thread_list.FindThreadByID(message.GetTID(), false).get());
377
Johnny Chen9ed5b492012-01-05 21:48:15 +0000378 switch (message.GetKind())
379 {
Johnny Chen9ed5b492012-01-05 21:48:15 +0000380 case ProcessMessage::eInvalidMessage:
381 return;
382
383 case ProcessMessage::eLimboMessage:
Andrew Kaylor93132f52013-05-28 23:04:25 +0000384 assert(thread);
385 thread->SetState(eStateStopped);
386 if (message.GetTID() == GetID())
Johnny Chen9ed5b492012-01-05 21:48:15 +0000387 {
Andrew Kaylor93132f52013-05-28 23:04:25 +0000388 m_exit_status = message.GetExitStatus();
389 if (m_exit_now)
390 {
391 SetPrivateState(eStateExited);
Matt Kopec085d6ce2013-05-31 22:00:07 +0000392 m_monitor->Detach(GetID());
Andrew Kaylor93132f52013-05-28 23:04:25 +0000393 }
394 else
395 {
396 StopAllThreads(message.GetTID());
397 SetPrivateState(eStateStopped);
398 }
Johnny Chen9ed5b492012-01-05 21:48:15 +0000399 }
400 else
Andrew Kaylor93132f52013-05-28 23:04:25 +0000401 {
402 StopAllThreads(message.GetTID());
Johnny Chen9ed5b492012-01-05 21:48:15 +0000403 SetPrivateState(eStateStopped);
Andrew Kaylor93132f52013-05-28 23:04:25 +0000404 }
Johnny Chen9ed5b492012-01-05 21:48:15 +0000405 break;
406
407 case ProcessMessage::eExitMessage:
Andrew Kaylor93132f52013-05-28 23:04:25 +0000408 assert(thread);
409 thread->SetState(eStateExited);
410 // FIXME: I'm not sure we need to do this.
411 if (message.GetTID() == GetID())
412 {
413 m_exit_status = message.GetExitStatus();
414 SetExitStatus(m_exit_status, NULL);
415 }
Matt Kopecb2910442013-07-09 15:09:45 +0000416 else if (!IsAThreadRunning())
417 SetPrivateState(eStateStopped);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000418 break;
419
Matt Kopecb2910442013-07-09 15:09:45 +0000420 assert(thread);
421 thread->SetState(eStateStopped);
422 StopAllThreads(message.GetTID());
423 SetPrivateState(eStateStopped);
424 break;
425
426 case ProcessMessage::eSignalMessage:
427 case ProcessMessage::eSignalDeliveredMessage:
428 if (message.GetSignal() == SIGSTOP &&
429 AddThreadForInitialStopIfNeeded(message.GetTID()))
430 return;
431 // Intentional fall-through
432
Johnny Chen9ed5b492012-01-05 21:48:15 +0000433 case ProcessMessage::eBreakpointMessage:
Andrew Kaylor93132f52013-05-28 23:04:25 +0000434 case ProcessMessage::eTraceMessage:
Matt Kopece9ea0da2013-05-07 19:29:28 +0000435 case ProcessMessage::eWatchpointMessage:
Andrew Kaylor93132f52013-05-28 23:04:25 +0000436 case ProcessMessage::eNewThreadMessage:
437 case ProcessMessage::eCrashMessage:
438 assert(thread);
439 thread->SetState(eStateStopped);
440 StopAllThreads(message.GetTID());
Johnny Chen9ed5b492012-01-05 21:48:15 +0000441 SetPrivateState(eStateStopped);
442 break;
Johnny Chen9ed5b492012-01-05 21:48:15 +0000443 }
444
445 m_message_queue.push(message);
446}
447
Andrew Kaylor93132f52013-05-28 23:04:25 +0000448void
449ProcessPOSIX::StopAllThreads(lldb::tid_t stop_tid)
450{
451 // FIXME: Will this work the same way on FreeBSD and Linux?
452}
453
Matt Kopecb2910442013-07-09 15:09:45 +0000454bool
455ProcessPOSIX::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid)
456{
457 bool added_to_set = false;
458 ThreadStopSet::iterator it = m_seen_initial_stop.find(stop_tid);
459 if (it == m_seen_initial_stop.end())
460 {
461 m_seen_initial_stop.insert(stop_tid);
462 added_to_set = true;
463 }
464 return added_to_set;
465}
466
Johnny Chen9ed5b492012-01-05 21:48:15 +0000467void
468ProcessPOSIX::RefreshStateAfterStop()
469{
Ashok Thirumurthi01186352013-03-28 16:02:31 +0000470 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
Johnny Chen9ed5b492012-01-05 21:48:15 +0000471 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Andrew Kaylor93132f52013-05-28 23:04:25 +0000472 log->Printf ("ProcessPOSIX::%s(), message_queue size = %d", __FUNCTION__, (int)m_message_queue.size());
Johnny Chen9ed5b492012-01-05 21:48:15 +0000473
474 Mutex::Locker lock(m_message_mutex);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000475
Andrew Kaylor93132f52013-05-28 23:04:25 +0000476 // This method used to only handle one message. Changing it to loop allows
477 // it to handle the case where we hit a breakpoint while handling a different
478 // breakpoint.
479 while (!m_message_queue.empty())
480 {
481 ProcessMessage &message = m_message_queue.front();
Johnny Chen9ed5b492012-01-05 21:48:15 +0000482
Andrew Kaylor93132f52013-05-28 23:04:25 +0000483 // Resolve the thread this message corresponds to and pass it along.
484 lldb::tid_t tid = message.GetTID();
485 if (log)
486 log->Printf ("ProcessPOSIX::%s(), message_queue size = %d, pid = %" PRIi64, __FUNCTION__, (int)m_message_queue.size(), tid);
487 POSIXThread *thread = static_cast<POSIXThread*>(
488 GetThreadList().FindThreadByID(tid, false).get());
Johnny Chen9ed5b492012-01-05 21:48:15 +0000489
Andrew Kaylor93132f52013-05-28 23:04:25 +0000490 if (message.GetKind() == ProcessMessage::eNewThreadMessage)
491 {
492 if (log)
493 log->Printf ("ProcessPOSIX::%s() adding thread, tid = %" PRIi64, __FUNCTION__, message.GetChildTID());
Matt Kopecfb6ab542013-07-10 20:53:11 +0000494 lldb::tid_t child_tid = message.GetChildTID();
Andrew Kaylor93132f52013-05-28 23:04:25 +0000495 ThreadSP thread_sp;
Matt Kopecfb6ab542013-07-10 20:53:11 +0000496 thread_sp.reset(new POSIXThread(*this, child_tid));
497
498 POSIXThread *thread = static_cast<POSIXThread*>(thread_sp.get());
499 thread->SetName(Host::GetThreadName(GetID(), child_tid).c_str());
500
Andrew Kaylor93132f52013-05-28 23:04:25 +0000501 m_thread_list.AddThread(thread_sp);
502 }
503
504 m_thread_list.RefreshStateAfterStop();
505
506 if (thread)
507 thread->Notify(message);
508
509 if (message.GetKind() == ProcessMessage::eExitMessage)
510 {
511 // FIXME: We should tell the user about this, but the limbo message is probably better for that.
512 if (log)
513 log->Printf ("ProcessPOSIX::%s() removing thread, tid = %" PRIi64, __FUNCTION__, tid);
514 ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false);
515 thread_sp.reset();
Matt Kopecb2910442013-07-09 15:09:45 +0000516 m_seen_initial_stop.erase(tid);
Andrew Kaylor93132f52013-05-28 23:04:25 +0000517 }
518
519 m_message_queue.pop();
Matt Kopec650648f2013-01-08 16:30:18 +0000520 }
Johnny Chen9ed5b492012-01-05 21:48:15 +0000521}
522
523bool
524ProcessPOSIX::IsAlive()
525{
526 StateType state = GetPrivateState();
Daniel Malea335bf6f2013-04-01 19:48:37 +0000527 return state != eStateDetached
528 && state != eStateExited
529 && state != eStateInvalid
530 && state != eStateUnloaded;
Johnny Chen9ed5b492012-01-05 21:48:15 +0000531}
532
533size_t
534ProcessPOSIX::DoReadMemory(addr_t vm_addr,
535 void *buf, size_t size, Error &error)
536{
537 assert(m_monitor);
538 return m_monitor->ReadMemory(vm_addr, buf, size, error);
539}
540
541size_t
542ProcessPOSIX::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
543 Error &error)
544{
545 assert(m_monitor);
546 return m_monitor->WriteMemory(vm_addr, buf, size, error);
547}
548
549addr_t
550ProcessPOSIX::DoAllocateMemory(size_t size, uint32_t permissions,
551 Error &error)
552{
553 addr_t allocated_addr = LLDB_INVALID_ADDRESS;
554
555 unsigned prot = 0;
556 if (permissions & lldb::ePermissionsReadable)
557 prot |= eMmapProtRead;
558 if (permissions & lldb::ePermissionsWritable)
559 prot |= eMmapProtWrite;
560 if (permissions & lldb::ePermissionsExecutable)
561 prot |= eMmapProtExec;
562
563 if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
564 eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
565 m_addr_to_mmap_size[allocated_addr] = size;
566 error.Clear();
567 } else {
568 allocated_addr = LLDB_INVALID_ADDRESS;
569 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
570 }
571
572 return allocated_addr;
573}
574
575Error
576ProcessPOSIX::DoDeallocateMemory(lldb::addr_t addr)
577{
578 Error error;
579 MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
580 if (pos != m_addr_to_mmap_size.end() &&
581 InferiorCallMunmap(this, addr, pos->second))
582 m_addr_to_mmap_size.erase (pos);
583 else
Daniel Malead01b2952012-11-29 21:49:15 +0000584 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000585
586 return error;
587}
588
Matt Kopec00049b82013-02-27 20:13:38 +0000589addr_t
590ProcessPOSIX::ResolveIndirectFunction(const Address *address, Error &error)
591{
592 addr_t function_addr = LLDB_INVALID_ADDRESS;
593 if (address == NULL) {
594 error.SetErrorStringWithFormat("unable to determine direct function call for NULL address");
595 } else if (!InferiorCall(this, address, function_addr)) {
596 function_addr = LLDB_INVALID_ADDRESS;
Matt Kopec66fd4b12013-03-01 17:44:31 +0000597 error.SetErrorStringWithFormat("unable to determine direct function call for indirect function %s",
598 address->CalculateSymbolContextSymbol()->GetName().AsCString());
Matt Kopec00049b82013-02-27 20:13:38 +0000599 }
600 return function_addr;
601}
602
Johnny Chen9ed5b492012-01-05 21:48:15 +0000603size_t
604ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
605{
606 static const uint8_t g_i386_opcode[] = { 0xCC };
607
608 ArchSpec arch = GetTarget().GetArchitecture();
609 const uint8_t *opcode = NULL;
610 size_t opcode_size = 0;
611
612 switch (arch.GetCore())
613 {
614 default:
615 assert(false && "CPU type not supported!");
616 break;
617
618 case ArchSpec::eCore_x86_32_i386:
619 case ArchSpec::eCore_x86_64_x86_64:
620 opcode = g_i386_opcode;
621 opcode_size = sizeof(g_i386_opcode);
622 break;
623 }
624
625 bp_site->SetTrapOpcode(opcode, opcode_size);
626 return opcode_size;
627}
628
629Error
Daniel Maleab7eec012013-02-15 20:23:25 +0000630ProcessPOSIX::EnableBreakpointSite(BreakpointSite *bp_site)
Johnny Chen9ed5b492012-01-05 21:48:15 +0000631{
632 return EnableSoftwareBreakpoint(bp_site);
633}
634
635Error
Daniel Maleab7eec012013-02-15 20:23:25 +0000636ProcessPOSIX::DisableBreakpointSite(BreakpointSite *bp_site)
Johnny Chen9ed5b492012-01-05 21:48:15 +0000637{
638 return DisableSoftwareBreakpoint(bp_site);
639}
640
Matt Kopece9ea0da2013-05-07 19:29:28 +0000641Error
642ProcessPOSIX::EnableWatchpoint(Watchpoint *wp, bool notify)
643{
644 Error error;
645 if (wp)
646 {
647 user_id_t watchID = wp->GetID();
648 addr_t addr = wp->GetLoadAddress();
649 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
650 if (log)
651 log->Printf ("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64 ")",
652 watchID);
653 if (wp->IsEnabled())
654 {
655 if (log)
656 log->Printf("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64
657 ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
658 watchID, (uint64_t)addr);
659 return error;
660 }
661
Matt Kopec6f961232013-06-03 17:40:20 +0000662 // Try to find a vacant watchpoint slot in the inferiors' main thread
663 uint32_t wp_hw_index = LLDB_INVALID_INDEX32;
664 POSIXThread *thread = static_cast<POSIXThread*>(
665 m_thread_list.GetThreadAtIndex(0, false).get());
666
667 if (thread)
668 wp_hw_index = thread->FindVacantWatchpointIndex();
669
670 if (wp_hw_index == LLDB_INVALID_INDEX32)
Matt Kopece9ea0da2013-05-07 19:29:28 +0000671 {
Matt Kopec6f961232013-06-03 17:40:20 +0000672 error.SetErrorString("Setting hardware watchpoint failed.");
Matt Kopece9ea0da2013-05-07 19:29:28 +0000673 }
674 else
675 {
Matt Kopec6f961232013-06-03 17:40:20 +0000676 wp->SetHardwareIndex(wp_hw_index);
677 bool wp_enabled = true;
678 uint32_t thread_count = m_thread_list.GetSize(false);
679 for (uint32_t i = 0; i < thread_count; ++i)
680 {
681 thread = static_cast<POSIXThread*>(
682 m_thread_list.GetThreadAtIndex(i, false).get());
683 if (thread)
684 wp_enabled &= thread->EnableHardwareWatchpoint(wp);
685 else
686 wp_enabled = false;
687 }
688 if (wp_enabled)
689 {
690 wp->SetEnabled(true, notify);
691 return error;
692 }
693 else
694 {
695 // Watchpoint enabling failed on at least one
696 // of the threads so roll back all of them
697 DisableWatchpoint(wp, false);
698 error.SetErrorString("Setting hardware watchpoint failed");
699 }
Matt Kopece9ea0da2013-05-07 19:29:28 +0000700 }
701 }
702 else
703 error.SetErrorString("Watchpoint argument was NULL.");
704 return error;
705}
706
707Error
708ProcessPOSIX::DisableWatchpoint(Watchpoint *wp, bool notify)
709{
710 Error error;
711 if (wp)
712 {
713 user_id_t watchID = wp->GetID();
714 addr_t addr = wp->GetLoadAddress();
715 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
716 if (log)
717 log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64 ")",
718 watchID);
719 if (!wp->IsEnabled())
720 {
721 if (log)
722 log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64
723 ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
724 watchID, (uint64_t)addr);
725 // This is needed (for now) to keep watchpoints disabled correctly
726 wp->SetEnabled(false, notify);
727 return error;
728 }
729
730 if (wp->IsHardware())
731 {
732 bool wp_disabled = true;
733 uint32_t thread_count = m_thread_list.GetSize(false);
734 for (uint32_t i = 0; i < thread_count; ++i)
735 {
736 POSIXThread *thread = static_cast<POSIXThread*>(
737 m_thread_list.GetThreadAtIndex(i, false).get());
738 if (thread)
739 wp_disabled &= thread->DisableHardwareWatchpoint(wp);
740 else
741 wp_disabled = false;
742 }
743 if (wp_disabled)
744 {
Matt Kopec6f961232013-06-03 17:40:20 +0000745 wp->SetHardwareIndex(LLDB_INVALID_INDEX32);
Matt Kopece9ea0da2013-05-07 19:29:28 +0000746 wp->SetEnabled(false, notify);
747 return error;
748 }
749 else
750 error.SetErrorString("Disabling hardware watchpoint failed");
751 }
752 }
753 else
754 error.SetErrorString("Watchpoint argument was NULL.");
755 return error;
756}
757
758Error
759ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num)
760{
761 Error error;
762 POSIXThread *thread = static_cast<POSIXThread*>(
763 m_thread_list.GetThreadAtIndex(0, false).get());
764 if (thread)
765 num = thread->NumSupportedHardwareWatchpoints();
766 else
767 error.SetErrorString("Process does not exist.");
768 return error;
769}
770
771Error
772ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num, bool &after)
773{
774 Error error = GetWatchpointSupportInfo(num);
775 // Watchpoints trigger and halt the inferior after
776 // the corresponding instruction has been executed.
777 after = true;
778 return error;
779}
780
Johnny Chen9ed5b492012-01-05 21:48:15 +0000781uint32_t
782ProcessPOSIX::UpdateThreadListIfNeeded()
783{
784 // Do not allow recursive updates.
785 return m_thread_list.GetSize(false);
786}
787
Greg Claytonc3c0b0e2012-04-12 19:04:34 +0000788bool
Johnny Chen9ed5b492012-01-05 21:48:15 +0000789ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
790{
Ashok Thirumurthi01186352013-03-28 16:02:31 +0000791 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
Johnny Chen9ed5b492012-01-05 21:48:15 +0000792 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malead01b2952012-11-29 21:49:15 +0000793 log->Printf ("ProcessPOSIX::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID());
Johnny Chen9ed5b492012-01-05 21:48:15 +0000794
795 // Update the process thread list with this new thread.
796 // FIXME: We should be using tid, not pid.
797 assert(m_monitor);
798 ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
Greg Clayton0c90ef42012-02-21 18:40:07 +0000799 if (!thread_sp) {
Greg Claytondf3df252012-10-12 16:23:23 +0000800 thread_sp.reset(new POSIXThread(*this, GetID()));
Greg Clayton0c90ef42012-02-21 18:40:07 +0000801 }
Johnny Chen9ed5b492012-01-05 21:48:15 +0000802
803 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malead01b2952012-11-29 21:49:15 +0000804 log->Printf ("ProcessPOSIX::%s() updated pid = %" PRIi64, __FUNCTION__, GetID());
Johnny Chen9ed5b492012-01-05 21:48:15 +0000805 new_thread_list.AddThread(thread_sp);
806
Greg Claytonc3c0b0e2012-04-12 19:04:34 +0000807 return new_thread_list.GetSize(false) > 0;
Johnny Chen9ed5b492012-01-05 21:48:15 +0000808}
809
810ByteOrder
811ProcessPOSIX::GetByteOrder() const
812{
813 // FIXME: We should be able to extract this value directly. See comment in
814 // ProcessPOSIX().
815 return m_byte_order;
816}
817
818size_t
819ProcessPOSIX::PutSTDIN(const char *buf, size_t len, Error &error)
820{
821 ssize_t status;
822 if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
823 {
824 error.SetErrorToErrno();
825 return 0;
826 }
827 return status;
828}
829
Johnny Chen9ed5b492012-01-05 21:48:15 +0000830UnixSignals &
831ProcessPOSIX::GetUnixSignals()
832{
833 return m_signals;
834}
835
836//------------------------------------------------------------------------------
837// Utility functions.
838
839bool
840ProcessPOSIX::HasExited()
841{
842 switch (GetPrivateState())
843 {
844 default:
845 break;
846
847 case eStateDetached:
848 case eStateExited:
849 return true;
850 }
851
852 return false;
853}
854
855bool
856ProcessPOSIX::IsStopped()
857{
858 switch (GetPrivateState())
859 {
860 default:
861 break;
862
863 case eStateStopped:
864 case eStateCrashed:
865 case eStateSuspended:
866 return true;
867 }
868
869 return false;
870}
Matt Kopecb2910442013-07-09 15:09:45 +0000871
872bool
873ProcessPOSIX::IsAThreadRunning()
874{
875 bool is_running = false;
876 uint32_t thread_count = m_thread_list.GetSize(false);
877 for (uint32_t i = 0; i < thread_count; ++i)
878 {
879 POSIXThread *thread = static_cast<POSIXThread*>(
880 m_thread_list.GetThreadAtIndex(i, false).get());
881 StateType thread_state = thread->GetState();
882 if (thread_state == eStateRunning || thread_state == eStateStepping)
883 {
884 is_running = true;
885 break;
886 }
887 }
888 return is_running;
889}