blob: 0be86851c2f841b7f27ab8e2996420bdd6a221b0 [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,
Jean-Daniel Dupas7782de92013-12-09 22:52:50 +0000203 ProcessLaunchInfo &launch_info)
Johnny Chen9ed5b492012-01-05 21:48:15 +0000204{
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
Johnny Chen9ed5b492012-01-05 21:48:15 +0000262addr_t
263ProcessPOSIX::GetImageInfoAddress()
264{
265 Target *target = &GetTarget();
266 ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
Ed Maste54803652013-10-11 17:39:07 +0000267 Address addr = obj_file->GetImageInfoAddress(target);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000268
Ed Maste04a8bab2013-10-11 01:16:08 +0000269 if (addr.IsValid())
Ed Maste54803652013-10-11 17:39:07 +0000270 return addr.GetLoadAddress(target);
Ed Maste04a8bab2013-10-11 01:16:08 +0000271 return LLDB_INVALID_ADDRESS;
Johnny Chen9ed5b492012-01-05 21:48:15 +0000272}
273
274Error
275ProcessPOSIX::DoHalt(bool &caused_stop)
276{
277 Error error;
278
279 if (IsStopped())
280 {
281 caused_stop = false;
282 }
283 else if (kill(GetID(), SIGSTOP))
284 {
285 caused_stop = false;
286 error.SetErrorToErrno();
287 }
288 else
289 {
290 caused_stop = true;
291 }
Johnny Chen9ed5b492012-01-05 21:48:15 +0000292 return error;
293}
294
295Error
Johnny Chen9ed5b492012-01-05 21:48:15 +0000296ProcessPOSIX::DoSignal(int signal)
297{
298 Error error;
299
300 if (kill(GetID(), signal))
301 error.SetErrorToErrno();
302
303 return error;
304}
305
306Error
307ProcessPOSIX::DoDestroy()
308{
309 Error error;
310
311 if (!HasExited())
312 {
313 // Drive the exit event to completion (do not keep the inferior in
314 // limbo).
315 m_exit_now = true;
316
Greg Claytonab950c32012-03-30 19:56:32 +0000317 if ((m_monitor == NULL || kill(m_monitor->GetPID(), SIGKILL)) && error.Success())
Johnny Chen9ed5b492012-01-05 21:48:15 +0000318 {
319 error.SetErrorToErrno();
320 return error;
321 }
322
323 SetPrivateState(eStateExited);
324 }
325
326 return error;
327}
328
329void
Matt Kopec718be872013-10-09 19:39:55 +0000330ProcessPOSIX::DoDidExec()
331{
332 Target *target = &GetTarget();
333 if (target)
334 {
335 PlatformSP platform_sp (target->GetPlatform());
336 assert (platform_sp.get());
337 if (platform_sp)
338 {
339 ProcessInstanceInfo process_info;
340 platform_sp->GetProcessInfo(GetID(), process_info);
341 ModuleSP exe_module_sp;
342 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
343 Error error = platform_sp->ResolveExecutable(process_info.GetExecutableFile(),
344 target->GetArchitecture(),
345 exe_module_sp,
346 executable_search_paths.GetSize() ? &executable_search_paths : NULL);
347 if (!error.Success())
348 return;
349 target->SetExecutableModule(exe_module_sp, true);
350 }
351 }
352}
353
Andrew Kaylor93132f52013-05-28 23:04:25 +0000354void
355ProcessPOSIX::StopAllThreads(lldb::tid_t stop_tid)
356{
357 // FIXME: Will this work the same way on FreeBSD and Linux?
358}
359
Matt Kopecb2910442013-07-09 15:09:45 +0000360bool
361ProcessPOSIX::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid)
362{
363 bool added_to_set = false;
364 ThreadStopSet::iterator it = m_seen_initial_stop.find(stop_tid);
365 if (it == m_seen_initial_stop.end())
366 {
367 m_seen_initial_stop.insert(stop_tid);
368 added_to_set = true;
369 }
370 return added_to_set;
371}
372
Andrew Kaylord4d54992013-09-17 00:30:24 +0000373bool
374ProcessPOSIX::WaitingForInitialStop(lldb::tid_t stop_tid)
375{
376 return (m_seen_initial_stop.find(stop_tid) == m_seen_initial_stop.end());
377}
378
Michael Sartain9f822cd2013-07-31 23:27:46 +0000379POSIXThread *
380ProcessPOSIX::CreateNewPOSIXThread(lldb_private::Process &process, lldb::tid_t tid)
381{
382 return new POSIXThread(process, tid);
383}
384
Johnny Chen9ed5b492012-01-05 21:48:15 +0000385void
386ProcessPOSIX::RefreshStateAfterStop()
387{
Ashok Thirumurthi01186352013-03-28 16:02:31 +0000388 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
Johnny Chen9ed5b492012-01-05 21:48:15 +0000389 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Andrew Kaylor93132f52013-05-28 23:04:25 +0000390 log->Printf ("ProcessPOSIX::%s(), message_queue size = %d", __FUNCTION__, (int)m_message_queue.size());
Johnny Chen9ed5b492012-01-05 21:48:15 +0000391
392 Mutex::Locker lock(m_message_mutex);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000393
Andrew Kaylor93132f52013-05-28 23:04:25 +0000394 // This method used to only handle one message. Changing it to loop allows
395 // it to handle the case where we hit a breakpoint while handling a different
396 // breakpoint.
397 while (!m_message_queue.empty())
398 {
399 ProcessMessage &message = m_message_queue.front();
Johnny Chen9ed5b492012-01-05 21:48:15 +0000400
Andrew Kaylor93132f52013-05-28 23:04:25 +0000401 // Resolve the thread this message corresponds to and pass it along.
402 lldb::tid_t tid = message.GetTID();
403 if (log)
404 log->Printf ("ProcessPOSIX::%s(), message_queue size = %d, pid = %" PRIi64, __FUNCTION__, (int)m_message_queue.size(), tid);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000405
Andrew Kaylor93132f52013-05-28 23:04:25 +0000406 if (message.GetKind() == ProcessMessage::eNewThreadMessage)
407 {
408 if (log)
409 log->Printf ("ProcessPOSIX::%s() adding thread, tid = %" PRIi64, __FUNCTION__, message.GetChildTID());
Matt Kopecfb6ab542013-07-10 20:53:11 +0000410 lldb::tid_t child_tid = message.GetChildTID();
Andrew Kaylor93132f52013-05-28 23:04:25 +0000411 ThreadSP thread_sp;
Michael Sartain9f822cd2013-07-31 23:27:46 +0000412 thread_sp.reset(CreateNewPOSIXThread(*this, child_tid));
Matt Kopecfb6ab542013-07-10 20:53:11 +0000413
Daniel Maleaa2cb9c42013-07-24 21:44:30 +0000414 Mutex::Locker lock(m_thread_list.GetMutex());
415
Andrew Kaylor93132f52013-05-28 23:04:25 +0000416 m_thread_list.AddThread(thread_sp);
417 }
418
419 m_thread_list.RefreshStateAfterStop();
420
Ed Maste685fea92013-08-29 20:40:11 +0000421 POSIXThread *thread = static_cast<POSIXThread*>(
422 GetThreadList().FindThreadByID(tid, false).get());
Andrew Kaylor93132f52013-05-28 23:04:25 +0000423 if (thread)
424 thread->Notify(message);
425
426 if (message.GetKind() == ProcessMessage::eExitMessage)
427 {
428 // FIXME: We should tell the user about this, but the limbo message is probably better for that.
429 if (log)
430 log->Printf ("ProcessPOSIX::%s() removing thread, tid = %" PRIi64, __FUNCTION__, tid);
Daniel Maleaa2cb9c42013-07-24 21:44:30 +0000431
432 Mutex::Locker lock(m_thread_list.GetMutex());
433
Andrew Kaylor93132f52013-05-28 23:04:25 +0000434 ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false);
435 thread_sp.reset();
Matt Kopecb2910442013-07-09 15:09:45 +0000436 m_seen_initial_stop.erase(tid);
Andrew Kaylor93132f52013-05-28 23:04:25 +0000437 }
438
439 m_message_queue.pop();
Matt Kopec650648f2013-01-08 16:30:18 +0000440 }
Johnny Chen9ed5b492012-01-05 21:48:15 +0000441}
442
443bool
444ProcessPOSIX::IsAlive()
445{
446 StateType state = GetPrivateState();
Daniel Malea335bf6f2013-04-01 19:48:37 +0000447 return state != eStateDetached
448 && state != eStateExited
449 && state != eStateInvalid
450 && state != eStateUnloaded;
Johnny Chen9ed5b492012-01-05 21:48:15 +0000451}
452
453size_t
454ProcessPOSIX::DoReadMemory(addr_t vm_addr,
455 void *buf, size_t size, Error &error)
456{
457 assert(m_monitor);
458 return m_monitor->ReadMemory(vm_addr, buf, size, error);
459}
460
461size_t
462ProcessPOSIX::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
463 Error &error)
464{
465 assert(m_monitor);
466 return m_monitor->WriteMemory(vm_addr, buf, size, error);
467}
468
469addr_t
470ProcessPOSIX::DoAllocateMemory(size_t size, uint32_t permissions,
471 Error &error)
472{
473 addr_t allocated_addr = LLDB_INVALID_ADDRESS;
474
475 unsigned prot = 0;
476 if (permissions & lldb::ePermissionsReadable)
477 prot |= eMmapProtRead;
478 if (permissions & lldb::ePermissionsWritable)
479 prot |= eMmapProtWrite;
480 if (permissions & lldb::ePermissionsExecutable)
481 prot |= eMmapProtExec;
482
483 if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
484 eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
485 m_addr_to_mmap_size[allocated_addr] = size;
486 error.Clear();
487 } else {
488 allocated_addr = LLDB_INVALID_ADDRESS;
489 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
490 }
491
492 return allocated_addr;
493}
494
495Error
496ProcessPOSIX::DoDeallocateMemory(lldb::addr_t addr)
497{
498 Error error;
499 MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
500 if (pos != m_addr_to_mmap_size.end() &&
501 InferiorCallMunmap(this, addr, pos->second))
502 m_addr_to_mmap_size.erase (pos);
503 else
Daniel Malead01b2952012-11-29 21:49:15 +0000504 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000505
506 return error;
507}
508
Matt Kopec00049b82013-02-27 20:13:38 +0000509addr_t
510ProcessPOSIX::ResolveIndirectFunction(const Address *address, Error &error)
511{
512 addr_t function_addr = LLDB_INVALID_ADDRESS;
513 if (address == NULL) {
514 error.SetErrorStringWithFormat("unable to determine direct function call for NULL address");
515 } else if (!InferiorCall(this, address, function_addr)) {
516 function_addr = LLDB_INVALID_ADDRESS;
Matt Kopec66fd4b12013-03-01 17:44:31 +0000517 error.SetErrorStringWithFormat("unable to determine direct function call for indirect function %s",
518 address->CalculateSymbolContextSymbol()->GetName().AsCString());
Matt Kopec00049b82013-02-27 20:13:38 +0000519 }
520 return function_addr;
521}
522
Johnny Chen9ed5b492012-01-05 21:48:15 +0000523size_t
524ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
525{
526 static const uint8_t g_i386_opcode[] = { 0xCC };
527
528 ArchSpec arch = GetTarget().GetArchitecture();
529 const uint8_t *opcode = NULL;
530 size_t opcode_size = 0;
531
532 switch (arch.GetCore())
533 {
534 default:
535 assert(false && "CPU type not supported!");
536 break;
537
538 case ArchSpec::eCore_x86_32_i386:
539 case ArchSpec::eCore_x86_64_x86_64:
540 opcode = g_i386_opcode;
541 opcode_size = sizeof(g_i386_opcode);
542 break;
543 }
544
545 bp_site->SetTrapOpcode(opcode, opcode_size);
546 return opcode_size;
547}
548
549Error
Daniel Maleab7eec012013-02-15 20:23:25 +0000550ProcessPOSIX::EnableBreakpointSite(BreakpointSite *bp_site)
Johnny Chen9ed5b492012-01-05 21:48:15 +0000551{
552 return EnableSoftwareBreakpoint(bp_site);
553}
554
555Error
Daniel Maleab7eec012013-02-15 20:23:25 +0000556ProcessPOSIX::DisableBreakpointSite(BreakpointSite *bp_site)
Johnny Chen9ed5b492012-01-05 21:48:15 +0000557{
558 return DisableSoftwareBreakpoint(bp_site);
559}
560
Matt Kopece9ea0da2013-05-07 19:29:28 +0000561Error
562ProcessPOSIX::EnableWatchpoint(Watchpoint *wp, bool notify)
563{
564 Error error;
565 if (wp)
566 {
567 user_id_t watchID = wp->GetID();
568 addr_t addr = wp->GetLoadAddress();
569 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
570 if (log)
571 log->Printf ("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64 ")",
572 watchID);
573 if (wp->IsEnabled())
574 {
575 if (log)
576 log->Printf("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64
577 ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
578 watchID, (uint64_t)addr);
579 return error;
580 }
581
Matt Kopec6f961232013-06-03 17:40:20 +0000582 // Try to find a vacant watchpoint slot in the inferiors' main thread
583 uint32_t wp_hw_index = LLDB_INVALID_INDEX32;
Daniel Maleaa2cb9c42013-07-24 21:44:30 +0000584 Mutex::Locker lock(m_thread_list.GetMutex());
Matt Kopec6f961232013-06-03 17:40:20 +0000585 POSIXThread *thread = static_cast<POSIXThread*>(
586 m_thread_list.GetThreadAtIndex(0, false).get());
587
588 if (thread)
589 wp_hw_index = thread->FindVacantWatchpointIndex();
590
591 if (wp_hw_index == LLDB_INVALID_INDEX32)
Matt Kopece9ea0da2013-05-07 19:29:28 +0000592 {
Matt Kopec6f961232013-06-03 17:40:20 +0000593 error.SetErrorString("Setting hardware watchpoint failed.");
Matt Kopece9ea0da2013-05-07 19:29:28 +0000594 }
595 else
596 {
Matt Kopec6f961232013-06-03 17:40:20 +0000597 wp->SetHardwareIndex(wp_hw_index);
598 bool wp_enabled = true;
599 uint32_t thread_count = m_thread_list.GetSize(false);
600 for (uint32_t i = 0; i < thread_count; ++i)
601 {
602 thread = static_cast<POSIXThread*>(
603 m_thread_list.GetThreadAtIndex(i, false).get());
604 if (thread)
605 wp_enabled &= thread->EnableHardwareWatchpoint(wp);
606 else
607 wp_enabled = false;
608 }
609 if (wp_enabled)
610 {
611 wp->SetEnabled(true, notify);
612 return error;
613 }
614 else
615 {
616 // Watchpoint enabling failed on at least one
617 // of the threads so roll back all of them
618 DisableWatchpoint(wp, false);
619 error.SetErrorString("Setting hardware watchpoint failed");
620 }
Matt Kopece9ea0da2013-05-07 19:29:28 +0000621 }
622 }
623 else
624 error.SetErrorString("Watchpoint argument was NULL.");
625 return error;
626}
627
628Error
629ProcessPOSIX::DisableWatchpoint(Watchpoint *wp, bool notify)
630{
631 Error error;
632 if (wp)
633 {
634 user_id_t watchID = wp->GetID();
635 addr_t addr = wp->GetLoadAddress();
636 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
637 if (log)
638 log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64 ")",
639 watchID);
640 if (!wp->IsEnabled())
641 {
642 if (log)
643 log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64
644 ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
645 watchID, (uint64_t)addr);
646 // This is needed (for now) to keep watchpoints disabled correctly
647 wp->SetEnabled(false, notify);
648 return error;
649 }
650
651 if (wp->IsHardware())
652 {
653 bool wp_disabled = true;
Daniel Maleaa2cb9c42013-07-24 21:44:30 +0000654 Mutex::Locker lock(m_thread_list.GetMutex());
Matt Kopece9ea0da2013-05-07 19:29:28 +0000655 uint32_t thread_count = m_thread_list.GetSize(false);
656 for (uint32_t i = 0; i < thread_count; ++i)
657 {
658 POSIXThread *thread = static_cast<POSIXThread*>(
659 m_thread_list.GetThreadAtIndex(i, false).get());
660 if (thread)
661 wp_disabled &= thread->DisableHardwareWatchpoint(wp);
662 else
663 wp_disabled = false;
664 }
665 if (wp_disabled)
666 {
Matt Kopec6f961232013-06-03 17:40:20 +0000667 wp->SetHardwareIndex(LLDB_INVALID_INDEX32);
Matt Kopece9ea0da2013-05-07 19:29:28 +0000668 wp->SetEnabled(false, notify);
669 return error;
670 }
671 else
672 error.SetErrorString("Disabling hardware watchpoint failed");
673 }
674 }
675 else
676 error.SetErrorString("Watchpoint argument was NULL.");
677 return error;
678}
679
680Error
681ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num)
682{
683 Error error;
Daniel Maleaa2cb9c42013-07-24 21:44:30 +0000684 Mutex::Locker lock(m_thread_list.GetMutex());
Matt Kopece9ea0da2013-05-07 19:29:28 +0000685 POSIXThread *thread = static_cast<POSIXThread*>(
686 m_thread_list.GetThreadAtIndex(0, false).get());
687 if (thread)
688 num = thread->NumSupportedHardwareWatchpoints();
689 else
690 error.SetErrorString("Process does not exist.");
691 return error;
692}
693
694Error
695ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num, bool &after)
696{
697 Error error = GetWatchpointSupportInfo(num);
698 // Watchpoints trigger and halt the inferior after
699 // the corresponding instruction has been executed.
700 after = true;
701 return error;
702}
703
Johnny Chen9ed5b492012-01-05 21:48:15 +0000704uint32_t
705ProcessPOSIX::UpdateThreadListIfNeeded()
706{
Daniel Maleaa2cb9c42013-07-24 21:44:30 +0000707 Mutex::Locker lock(m_thread_list.GetMutex());
Johnny Chen9ed5b492012-01-05 21:48:15 +0000708 // Do not allow recursive updates.
709 return m_thread_list.GetSize(false);
710}
711
Greg Claytonc3c0b0e2012-04-12 19:04:34 +0000712bool
Johnny Chen9ed5b492012-01-05 21:48:15 +0000713ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
714{
Ashok Thirumurthi01186352013-03-28 16:02:31 +0000715 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
Johnny Chen9ed5b492012-01-05 21:48:15 +0000716 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malead01b2952012-11-29 21:49:15 +0000717 log->Printf ("ProcessPOSIX::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID());
Johnny Chen9ed5b492012-01-05 21:48:15 +0000718
Daniel Maleae0f8f572013-08-26 23:57:52 +0000719 bool has_updated = false;
Johnny Chen9ed5b492012-01-05 21:48:15 +0000720 // Update the process thread list with this new thread.
721 // FIXME: We should be using tid, not pid.
722 assert(m_monitor);
723 ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
Greg Clayton0c90ef42012-02-21 18:40:07 +0000724 if (!thread_sp) {
Michael Sartain9f822cd2013-07-31 23:27:46 +0000725 thread_sp.reset(CreateNewPOSIXThread(*this, GetID()));
Daniel Maleae0f8f572013-08-26 23:57:52 +0000726 has_updated = true;
Greg Clayton0c90ef42012-02-21 18:40:07 +0000727 }
Johnny Chen9ed5b492012-01-05 21:48:15 +0000728
729 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malead01b2952012-11-29 21:49:15 +0000730 log->Printf ("ProcessPOSIX::%s() updated pid = %" PRIi64, __FUNCTION__, GetID());
Johnny Chen9ed5b492012-01-05 21:48:15 +0000731 new_thread_list.AddThread(thread_sp);
732
Daniel Maleae0f8f572013-08-26 23:57:52 +0000733 return has_updated; // the list has been updated
Johnny Chen9ed5b492012-01-05 21:48:15 +0000734}
735
736ByteOrder
737ProcessPOSIX::GetByteOrder() const
738{
739 // FIXME: We should be able to extract this value directly. See comment in
740 // ProcessPOSIX().
741 return m_byte_order;
742}
743
744size_t
745ProcessPOSIX::PutSTDIN(const char *buf, size_t len, Error &error)
746{
747 ssize_t status;
748 if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
749 {
750 error.SetErrorToErrno();
751 return 0;
752 }
753 return status;
754}
755
Johnny Chen9ed5b492012-01-05 21:48:15 +0000756UnixSignals &
757ProcessPOSIX::GetUnixSignals()
758{
759 return m_signals;
760}
761
762//------------------------------------------------------------------------------
763// Utility functions.
764
765bool
766ProcessPOSIX::HasExited()
767{
768 switch (GetPrivateState())
769 {
770 default:
771 break;
772
773 case eStateDetached:
774 case eStateExited:
775 return true;
776 }
777
778 return false;
779}
780
781bool
782ProcessPOSIX::IsStopped()
783{
784 switch (GetPrivateState())
785 {
786 default:
787 break;
788
789 case eStateStopped:
790 case eStateCrashed:
791 case eStateSuspended:
792 return true;
793 }
794
795 return false;
796}
Matt Kopecb2910442013-07-09 15:09:45 +0000797
798bool
799ProcessPOSIX::IsAThreadRunning()
800{
801 bool is_running = false;
Daniel Maleaa2cb9c42013-07-24 21:44:30 +0000802 Mutex::Locker lock(m_thread_list.GetMutex());
Matt Kopecb2910442013-07-09 15:09:45 +0000803 uint32_t thread_count = m_thread_list.GetSize(false);
804 for (uint32_t i = 0; i < thread_count; ++i)
805 {
806 POSIXThread *thread = static_cast<POSIXThread*>(
807 m_thread_list.GetThreadAtIndex(i, false).get());
808 StateType thread_state = thread->GetState();
809 if (thread_state == eStateRunning || thread_state == eStateStepping)
810 {
811 is_running = true;
812 break;
813 }
814 }
815 return is_running;
816}