blob: e09bfcaf418161f32869c1ba21e8f6655e6d7ac9 [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
118 m_monitor = new ProcessMonitor(this, pid, error);
119
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
228 m_monitor = new ProcessMonitor (this,
229 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());
494 ThreadSP thread_sp;
495 thread_sp.reset(new POSIXThread(*this, message.GetChildTID()));
496 m_thread_list.AddThread(thread_sp);
497 }
498
499 m_thread_list.RefreshStateAfterStop();
500
501 if (thread)
502 thread->Notify(message);
503
504 if (message.GetKind() == ProcessMessage::eExitMessage)
505 {
506 // FIXME: We should tell the user about this, but the limbo message is probably better for that.
507 if (log)
508 log->Printf ("ProcessPOSIX::%s() removing thread, tid = %" PRIi64, __FUNCTION__, tid);
509 ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false);
510 thread_sp.reset();
Matt Kopecb2910442013-07-09 15:09:45 +0000511 m_seen_initial_stop.erase(tid);
Andrew Kaylor93132f52013-05-28 23:04:25 +0000512 }
513
514 m_message_queue.pop();
Matt Kopec650648f2013-01-08 16:30:18 +0000515 }
Johnny Chen9ed5b492012-01-05 21:48:15 +0000516}
517
518bool
519ProcessPOSIX::IsAlive()
520{
521 StateType state = GetPrivateState();
Daniel Malea335bf6f2013-04-01 19:48:37 +0000522 return state != eStateDetached
523 && state != eStateExited
524 && state != eStateInvalid
525 && state != eStateUnloaded;
Johnny Chen9ed5b492012-01-05 21:48:15 +0000526}
527
528size_t
529ProcessPOSIX::DoReadMemory(addr_t vm_addr,
530 void *buf, size_t size, Error &error)
531{
532 assert(m_monitor);
533 return m_monitor->ReadMemory(vm_addr, buf, size, error);
534}
535
536size_t
537ProcessPOSIX::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
538 Error &error)
539{
540 assert(m_monitor);
541 return m_monitor->WriteMemory(vm_addr, buf, size, error);
542}
543
544addr_t
545ProcessPOSIX::DoAllocateMemory(size_t size, uint32_t permissions,
546 Error &error)
547{
548 addr_t allocated_addr = LLDB_INVALID_ADDRESS;
549
550 unsigned prot = 0;
551 if (permissions & lldb::ePermissionsReadable)
552 prot |= eMmapProtRead;
553 if (permissions & lldb::ePermissionsWritable)
554 prot |= eMmapProtWrite;
555 if (permissions & lldb::ePermissionsExecutable)
556 prot |= eMmapProtExec;
557
558 if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
559 eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
560 m_addr_to_mmap_size[allocated_addr] = size;
561 error.Clear();
562 } else {
563 allocated_addr = LLDB_INVALID_ADDRESS;
564 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
565 }
566
567 return allocated_addr;
568}
569
570Error
571ProcessPOSIX::DoDeallocateMemory(lldb::addr_t addr)
572{
573 Error error;
574 MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
575 if (pos != m_addr_to_mmap_size.end() &&
576 InferiorCallMunmap(this, addr, pos->second))
577 m_addr_to_mmap_size.erase (pos);
578 else
Daniel Malead01b2952012-11-29 21:49:15 +0000579 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000580
581 return error;
582}
583
Matt Kopec00049b82013-02-27 20:13:38 +0000584addr_t
585ProcessPOSIX::ResolveIndirectFunction(const Address *address, Error &error)
586{
587 addr_t function_addr = LLDB_INVALID_ADDRESS;
588 if (address == NULL) {
589 error.SetErrorStringWithFormat("unable to determine direct function call for NULL address");
590 } else if (!InferiorCall(this, address, function_addr)) {
591 function_addr = LLDB_INVALID_ADDRESS;
Matt Kopec66fd4b12013-03-01 17:44:31 +0000592 error.SetErrorStringWithFormat("unable to determine direct function call for indirect function %s",
593 address->CalculateSymbolContextSymbol()->GetName().AsCString());
Matt Kopec00049b82013-02-27 20:13:38 +0000594 }
595 return function_addr;
596}
597
Johnny Chen9ed5b492012-01-05 21:48:15 +0000598size_t
599ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
600{
601 static const uint8_t g_i386_opcode[] = { 0xCC };
602
603 ArchSpec arch = GetTarget().GetArchitecture();
604 const uint8_t *opcode = NULL;
605 size_t opcode_size = 0;
606
607 switch (arch.GetCore())
608 {
609 default:
610 assert(false && "CPU type not supported!");
611 break;
612
613 case ArchSpec::eCore_x86_32_i386:
614 case ArchSpec::eCore_x86_64_x86_64:
615 opcode = g_i386_opcode;
616 opcode_size = sizeof(g_i386_opcode);
617 break;
618 }
619
620 bp_site->SetTrapOpcode(opcode, opcode_size);
621 return opcode_size;
622}
623
624Error
Daniel Maleab7eec012013-02-15 20:23:25 +0000625ProcessPOSIX::EnableBreakpointSite(BreakpointSite *bp_site)
Johnny Chen9ed5b492012-01-05 21:48:15 +0000626{
627 return EnableSoftwareBreakpoint(bp_site);
628}
629
630Error
Daniel Maleab7eec012013-02-15 20:23:25 +0000631ProcessPOSIX::DisableBreakpointSite(BreakpointSite *bp_site)
Johnny Chen9ed5b492012-01-05 21:48:15 +0000632{
633 return DisableSoftwareBreakpoint(bp_site);
634}
635
Matt Kopece9ea0da2013-05-07 19:29:28 +0000636Error
637ProcessPOSIX::EnableWatchpoint(Watchpoint *wp, bool notify)
638{
639 Error error;
640 if (wp)
641 {
642 user_id_t watchID = wp->GetID();
643 addr_t addr = wp->GetLoadAddress();
644 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
645 if (log)
646 log->Printf ("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64 ")",
647 watchID);
648 if (wp->IsEnabled())
649 {
650 if (log)
651 log->Printf("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64
652 ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
653 watchID, (uint64_t)addr);
654 return error;
655 }
656
Matt Kopec6f961232013-06-03 17:40:20 +0000657 // Try to find a vacant watchpoint slot in the inferiors' main thread
658 uint32_t wp_hw_index = LLDB_INVALID_INDEX32;
659 POSIXThread *thread = static_cast<POSIXThread*>(
660 m_thread_list.GetThreadAtIndex(0, false).get());
661
662 if (thread)
663 wp_hw_index = thread->FindVacantWatchpointIndex();
664
665 if (wp_hw_index == LLDB_INVALID_INDEX32)
Matt Kopece9ea0da2013-05-07 19:29:28 +0000666 {
Matt Kopec6f961232013-06-03 17:40:20 +0000667 error.SetErrorString("Setting hardware watchpoint failed.");
Matt Kopece9ea0da2013-05-07 19:29:28 +0000668 }
669 else
670 {
Matt Kopec6f961232013-06-03 17:40:20 +0000671 wp->SetHardwareIndex(wp_hw_index);
672 bool wp_enabled = true;
673 uint32_t thread_count = m_thread_list.GetSize(false);
674 for (uint32_t i = 0; i < thread_count; ++i)
675 {
676 thread = static_cast<POSIXThread*>(
677 m_thread_list.GetThreadAtIndex(i, false).get());
678 if (thread)
679 wp_enabled &= thread->EnableHardwareWatchpoint(wp);
680 else
681 wp_enabled = false;
682 }
683 if (wp_enabled)
684 {
685 wp->SetEnabled(true, notify);
686 return error;
687 }
688 else
689 {
690 // Watchpoint enabling failed on at least one
691 // of the threads so roll back all of them
692 DisableWatchpoint(wp, false);
693 error.SetErrorString("Setting hardware watchpoint failed");
694 }
Matt Kopece9ea0da2013-05-07 19:29:28 +0000695 }
696 }
697 else
698 error.SetErrorString("Watchpoint argument was NULL.");
699 return error;
700}
701
702Error
703ProcessPOSIX::DisableWatchpoint(Watchpoint *wp, bool notify)
704{
705 Error error;
706 if (wp)
707 {
708 user_id_t watchID = wp->GetID();
709 addr_t addr = wp->GetLoadAddress();
710 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
711 if (log)
712 log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64 ")",
713 watchID);
714 if (!wp->IsEnabled())
715 {
716 if (log)
717 log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64
718 ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
719 watchID, (uint64_t)addr);
720 // This is needed (for now) to keep watchpoints disabled correctly
721 wp->SetEnabled(false, notify);
722 return error;
723 }
724
725 if (wp->IsHardware())
726 {
727 bool wp_disabled = true;
728 uint32_t thread_count = m_thread_list.GetSize(false);
729 for (uint32_t i = 0; i < thread_count; ++i)
730 {
731 POSIXThread *thread = static_cast<POSIXThread*>(
732 m_thread_list.GetThreadAtIndex(i, false).get());
733 if (thread)
734 wp_disabled &= thread->DisableHardwareWatchpoint(wp);
735 else
736 wp_disabled = false;
737 }
738 if (wp_disabled)
739 {
Matt Kopec6f961232013-06-03 17:40:20 +0000740 wp->SetHardwareIndex(LLDB_INVALID_INDEX32);
Matt Kopece9ea0da2013-05-07 19:29:28 +0000741 wp->SetEnabled(false, notify);
742 return error;
743 }
744 else
745 error.SetErrorString("Disabling hardware watchpoint failed");
746 }
747 }
748 else
749 error.SetErrorString("Watchpoint argument was NULL.");
750 return error;
751}
752
753Error
754ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num)
755{
756 Error error;
757 POSIXThread *thread = static_cast<POSIXThread*>(
758 m_thread_list.GetThreadAtIndex(0, false).get());
759 if (thread)
760 num = thread->NumSupportedHardwareWatchpoints();
761 else
762 error.SetErrorString("Process does not exist.");
763 return error;
764}
765
766Error
767ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num, bool &after)
768{
769 Error error = GetWatchpointSupportInfo(num);
770 // Watchpoints trigger and halt the inferior after
771 // the corresponding instruction has been executed.
772 after = true;
773 return error;
774}
775
Johnny Chen9ed5b492012-01-05 21:48:15 +0000776uint32_t
777ProcessPOSIX::UpdateThreadListIfNeeded()
778{
779 // Do not allow recursive updates.
780 return m_thread_list.GetSize(false);
781}
782
Greg Claytonc3c0b0e2012-04-12 19:04:34 +0000783bool
Johnny Chen9ed5b492012-01-05 21:48:15 +0000784ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
785{
Ashok Thirumurthi01186352013-03-28 16:02:31 +0000786 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
Johnny Chen9ed5b492012-01-05 21:48:15 +0000787 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malead01b2952012-11-29 21:49:15 +0000788 log->Printf ("ProcessPOSIX::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID());
Johnny Chen9ed5b492012-01-05 21:48:15 +0000789
790 // Update the process thread list with this new thread.
791 // FIXME: We should be using tid, not pid.
792 assert(m_monitor);
793 ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
Greg Clayton0c90ef42012-02-21 18:40:07 +0000794 if (!thread_sp) {
Greg Claytondf3df252012-10-12 16:23:23 +0000795 thread_sp.reset(new POSIXThread(*this, GetID()));
Greg Clayton0c90ef42012-02-21 18:40:07 +0000796 }
Johnny Chen9ed5b492012-01-05 21:48:15 +0000797
798 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malead01b2952012-11-29 21:49:15 +0000799 log->Printf ("ProcessPOSIX::%s() updated pid = %" PRIi64, __FUNCTION__, GetID());
Johnny Chen9ed5b492012-01-05 21:48:15 +0000800 new_thread_list.AddThread(thread_sp);
801
Greg Claytonc3c0b0e2012-04-12 19:04:34 +0000802 return new_thread_list.GetSize(false) > 0;
Johnny Chen9ed5b492012-01-05 21:48:15 +0000803}
804
805ByteOrder
806ProcessPOSIX::GetByteOrder() const
807{
808 // FIXME: We should be able to extract this value directly. See comment in
809 // ProcessPOSIX().
810 return m_byte_order;
811}
812
813size_t
814ProcessPOSIX::PutSTDIN(const char *buf, size_t len, Error &error)
815{
816 ssize_t status;
817 if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
818 {
819 error.SetErrorToErrno();
820 return 0;
821 }
822 return status;
823}
824
Johnny Chen9ed5b492012-01-05 21:48:15 +0000825UnixSignals &
826ProcessPOSIX::GetUnixSignals()
827{
828 return m_signals;
829}
830
831//------------------------------------------------------------------------------
832// Utility functions.
833
834bool
835ProcessPOSIX::HasExited()
836{
837 switch (GetPrivateState())
838 {
839 default:
840 break;
841
842 case eStateDetached:
843 case eStateExited:
844 return true;
845 }
846
847 return false;
848}
849
850bool
851ProcessPOSIX::IsStopped()
852{
853 switch (GetPrivateState())
854 {
855 default:
856 break;
857
858 case eStateStopped:
859 case eStateCrashed:
860 case eStateSuspended:
861 return true;
862 }
863
864 return false;
865}
Matt Kopecb2910442013-07-09 15:09:45 +0000866
867bool
868ProcessPOSIX::IsAThreadRunning()
869{
870 bool is_running = false;
871 uint32_t thread_count = m_thread_list.GetSize(false);
872 for (uint32_t i = 0; i < thread_count; ++i)
873 {
874 POSIXThread *thread = static_cast<POSIXThread*>(
875 m_thread_list.GetThreadAtIndex(i, false).get());
876 StateType thread_state = thread->GetState();
877 if (thread_state == eStateRunning || thread_state == eStateStepping)
878 {
879 is_running = true;
880 break;
881 }
882 }
883 return is_running;
884}