blob: f0105685de57a7dec9287002114b9039236ed67a [file] [log] [blame]
Johnny Chen2341d352012-01-05 21:48:15 +00001//===-- ProcessPOSIX.cpp ----------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Daniel Malead891f9b2012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Johnny Chen2341d352012-01-05 21:48:15 +000012// C Includes
13#include <errno.h>
14
15// C++ Includes
16// Other libraries and framework includes
Matt Kopec3d4d51c2013-05-07 19:29:28 +000017#include "lldb/Breakpoint/Watchpoint.h"
Greg Clayton8ac035d2012-09-04 14:55:50 +000018#include "lldb/Core/Module.h"
Johnny Chen2341d352012-01-05 21:48:15 +000019#include "lldb/Core/PluginManager.h"
20#include "lldb/Core/State.h"
Daniel Malea1e44fdd2013-01-08 14:49:22 +000021#include "lldb/Host/FileSpec.h"
Johnny Chen2341d352012-01-05 21:48:15 +000022#include "lldb/Host/Host.h"
23#include "lldb/Symbol/ObjectFile.h"
24#include "lldb/Target/DynamicLoader.h"
25#include "lldb/Target/Target.h"
26
27#include "ProcessPOSIX.h"
28#include "ProcessPOSIXLog.h"
29#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
30#include "ProcessMonitor.h"
31#include "POSIXThread.h"
32
33using namespace lldb;
34using namespace lldb_private;
35
36//------------------------------------------------------------------------------
37// Static functions.
38#if 0
39Process*
40ProcessPOSIX::CreateInstance(Target& target, Listener &listener)
41{
42 return new ProcessPOSIX(target, listener);
43}
44
45
46void
47ProcessPOSIX::Initialize()
48{
49 static bool g_initialized = false;
50
51 if (!g_initialized)
52 {
53 g_initialized = true;
54 PluginManager::RegisterPlugin(GetPluginNameStatic(),
55 GetPluginDescriptionStatic(),
56 CreateInstance);
57
58 Log::Callbacks log_callbacks = {
59 ProcessPOSIXLog::DisableLog,
60 ProcessPOSIXLog::EnableLog,
61 ProcessPOSIXLog::ListLogCategories
62 };
63
64 Log::RegisterLogChannel (ProcessPOSIX::GetPluginNameStatic(), log_callbacks);
65 }
66}
67#endif
68
69//------------------------------------------------------------------------------
70// Constructors and destructors.
71
72ProcessPOSIX::ProcessPOSIX(Target& target, Listener &listener)
73 : Process(target, listener),
Johnny Chen78dae822012-04-14 00:54:42 +000074 m_byte_order(lldb::endian::InlHostByteOrder()),
Johnny Chen2341d352012-01-05 21:48:15 +000075 m_monitor(NULL),
76 m_module(NULL),
77 m_in_limbo(false),
78 m_exit_now(false)
79{
80 // FIXME: Putting this code in the ctor and saving the byte order in a
81 // member variable is a hack to avoid const qual issues in GetByteOrder.
Johnny Chen78dae822012-04-14 00:54:42 +000082 lldb::ModuleSP module = GetTarget().GetExecutableModule();
83 if (module != NULL && module->GetObjectFile() != NULL)
84 m_byte_order = module->GetObjectFile()->GetByteOrder();
Johnny Chen2341d352012-01-05 21:48:15 +000085}
86
87ProcessPOSIX::~ProcessPOSIX()
88{
89 delete m_monitor;
90}
91
92//------------------------------------------------------------------------------
93// Process protocol.
94
95bool
96ProcessPOSIX::CanDebug(Target &target, bool plugin_specified_by_name)
97{
98 // For now we are just making sure the file exists for a given module
99 ModuleSP exe_module_sp(target.GetExecutableModule());
100 if (exe_module_sp.get())
101 return exe_module_sp->GetFileSpec().Exists();
102 return false;
103}
104
105Error
106ProcessPOSIX::DoAttachToProcessWithID(lldb::pid_t pid)
107{
108 Error error;
109 assert(m_monitor == NULL);
110
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000111 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
Johnny Chen2341d352012-01-05 21:48:15 +0000112 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000113 log->Printf ("ProcessPOSIX::%s(pid = %" PRIi64 ")", __FUNCTION__, GetID());
Johnny Chen2341d352012-01-05 21:48:15 +0000114
115 m_monitor = new ProcessMonitor(this, pid, error);
116
117 if (!error.Success())
118 return error;
119
120 SetID(pid);
121 return error;
122}
123
124Error
Greg Claytonc6430772012-09-07 17:51:47 +0000125ProcessPOSIX::DoAttachToProcessWithID (lldb::pid_t pid, const ProcessAttachInfo &attach_info)
126{
127 return DoAttachToProcessWithID(pid);
128}
129
130Error
Johnny Chen2341d352012-01-05 21:48:15 +0000131ProcessPOSIX::WillLaunch(Module* module)
132{
133 Error error;
134 return error;
135}
136
137const char *
138ProcessPOSIX::GetFilePath(
139 const lldb_private::ProcessLaunchInfo::FileAction *file_action,
140 const char *default_path)
141{
142 const char *pts_name = "/dev/pts/";
143 const char *path = NULL;
144
145 if (file_action)
146 {
147 if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen)
148 path = file_action->GetPath();
149 // By default the stdio paths passed in will be pseudo-terminal
150 // (/dev/pts). If so, convert to using a different default path
151 // instead to redirect I/O to the debugger console. This should
152 // also handle user overrides to /dev/null or a different file.
153 if (::strncmp(path, pts_name, ::strlen(pts_name)) == 0)
154 path = default_path;
155 }
156
157 return path;
158}
159
160Error
161ProcessPOSIX::DoLaunch (Module *module,
162 const ProcessLaunchInfo &launch_info)
163{
164 Error error;
165 assert(m_monitor == NULL);
166
Daniel Malea1e44fdd2013-01-08 14:49:22 +0000167 const char* working_dir = launch_info.GetWorkingDirectory();
168 if (working_dir) {
169 FileSpec WorkingDir(working_dir, true);
170 if (!WorkingDir || WorkingDir.GetFileType() != FileSpec::eFileTypeDirectory)
171 {
172 error.SetErrorStringWithFormat("No such file or directory: %s", working_dir);
173 return error;
174 }
175 }
176
Johnny Chen2341d352012-01-05 21:48:15 +0000177 SetPrivateState(eStateLaunching);
178
179 const lldb_private::ProcessLaunchInfo::FileAction *file_action;
180
181 // Default of NULL will mean to use existing open file descriptors
182 const char *stdin_path = NULL;
183 const char *stdout_path = NULL;
184 const char *stderr_path = NULL;
Daniel Malea1e44fdd2013-01-08 14:49:22 +0000185
Johnny Chen2341d352012-01-05 21:48:15 +0000186 file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
187 stdin_path = GetFilePath(file_action, stdin_path);
188
189 file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
190 stdout_path = GetFilePath(file_action, stdout_path);
191
192 file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
193 stderr_path = GetFilePath(file_action, stderr_path);
194
195 m_monitor = new ProcessMonitor (this,
196 module,
197 launch_info.GetArguments().GetConstArgumentVector(),
198 launch_info.GetEnvironmentEntries().GetConstArgumentVector(),
199 stdin_path,
200 stdout_path,
201 stderr_path,
Daniel Malea1e44fdd2013-01-08 14:49:22 +0000202 working_dir,
Johnny Chen2341d352012-01-05 21:48:15 +0000203 error);
204
205 m_module = module;
206
207 if (!error.Success())
208 return error;
209
Matt Kopeca7cd95d2013-03-14 21:35:26 +0000210 SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
211
Johnny Chen2341d352012-01-05 21:48:15 +0000212 SetID(m_monitor->GetPID());
213 return error;
214}
215
216void
217ProcessPOSIX::DidLaunch()
218{
219}
220
221Error
222ProcessPOSIX::DoResume()
223{
224 StateType state = GetPrivateState();
225
226 assert(state == eStateStopped || state == eStateCrashed);
227
228 // We are about to resume a thread that will cause the process to exit so
229 // set our exit status now. Do not change our state if the inferior
230 // crashed.
231 if (state == eStateStopped)
232 {
233 if (m_in_limbo)
234 SetExitStatus(m_exit_status, NULL);
235 else
236 SetPrivateState(eStateRunning);
237 }
238
239 bool did_resume = false;
240 uint32_t thread_count = m_thread_list.GetSize(false);
241 for (uint32_t i = 0; i < thread_count; ++i)
242 {
243 POSIXThread *thread = static_cast<POSIXThread*>(
244 m_thread_list.GetThreadAtIndex(i, false).get());
245 did_resume = thread->Resume() || did_resume;
246 }
247 assert(did_resume && "Process resume failed!");
248
249 return Error();
250}
251
252addr_t
253ProcessPOSIX::GetImageInfoAddress()
254{
255 Target *target = &GetTarget();
256 ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
257 Address addr = obj_file->GetImageInfoAddress();
258
259 if (addr.IsValid())
260 return addr.GetLoadAddress(target);
261 else
262 return LLDB_INVALID_ADDRESS;
263}
264
265Error
266ProcessPOSIX::DoHalt(bool &caused_stop)
267{
268 Error error;
269
270 if (IsStopped())
271 {
272 caused_stop = false;
273 }
274 else if (kill(GetID(), SIGSTOP))
275 {
276 caused_stop = false;
277 error.SetErrorToErrno();
278 }
279 else
280 {
281 caused_stop = true;
282 }
Johnny Chen2341d352012-01-05 21:48:15 +0000283 return error;
284}
285
286Error
Jim Ingham761afb82013-05-02 00:27:30 +0000287ProcessPOSIX::DoDetach(bool keep_stopped)
Johnny Chen2341d352012-01-05 21:48:15 +0000288{
289 Error error;
Jim Ingham761afb82013-05-02 00:27:30 +0000290 if (keep_stopped)
291 {
292 // FIXME: If you want to implement keep_stopped on Linux,
293 // this would be the place to do it.
294 error.SetErrorString("Detaching with keep_stopped true is not currently supported on Linux.");
295 return error;
296 }
Johnny Chen2341d352012-01-05 21:48:15 +0000297
298 error = m_monitor->Detach();
299 if (error.Success())
300 SetPrivateState(eStateDetached);
301
302 return error;
303}
304
305Error
306ProcessPOSIX::DoSignal(int signal)
307{
308 Error error;
309
310 if (kill(GetID(), signal))
311 error.SetErrorToErrno();
312
313 return error;
314}
315
316Error
317ProcessPOSIX::DoDestroy()
318{
319 Error error;
320
321 if (!HasExited())
322 {
323 // Drive the exit event to completion (do not keep the inferior in
324 // limbo).
325 m_exit_now = true;
326
Greg Clayton972c4382012-03-30 19:56:32 +0000327 if ((m_monitor == NULL || kill(m_monitor->GetPID(), SIGKILL)) && error.Success())
Johnny Chen2341d352012-01-05 21:48:15 +0000328 {
329 error.SetErrorToErrno();
330 return error;
331 }
332
333 SetPrivateState(eStateExited);
334 }
335
336 return error;
337}
338
339void
340ProcessPOSIX::SendMessage(const ProcessMessage &message)
341{
342 Mutex::Locker lock(m_message_mutex);
343
344 switch (message.GetKind())
345 {
Johnny Chen2341d352012-01-05 21:48:15 +0000346 case ProcessMessage::eInvalidMessage:
347 return;
348
349 case ProcessMessage::eLimboMessage:
350 m_in_limbo = true;
351 m_exit_status = message.GetExitStatus();
352 if (m_exit_now)
353 {
354 SetPrivateState(eStateExited);
355 m_monitor->Detach();
356 }
357 else
358 SetPrivateState(eStateStopped);
359 break;
360
361 case ProcessMessage::eExitMessage:
362 m_exit_status = message.GetExitStatus();
363 SetExitStatus(m_exit_status, NULL);
364 break;
365
366 case ProcessMessage::eTraceMessage:
367 case ProcessMessage::eBreakpointMessage:
Matt Kopec3d4d51c2013-05-07 19:29:28 +0000368 case ProcessMessage::eWatchpointMessage:
Johnny Chen2341d352012-01-05 21:48:15 +0000369 SetPrivateState(eStateStopped);
370 break;
371
372 case ProcessMessage::eSignalMessage:
373 case ProcessMessage::eSignalDeliveredMessage:
Matt Kopecf1fda372013-01-08 16:30:18 +0000374 {
375 lldb::tid_t tid = message.GetTID();
376 lldb::tid_t pid = GetID();
377 if (tid == pid) {
378 SetPrivateState(eStateStopped);
379 break;
380 } else {
381 // FIXME: Ignore any signals generated by children.
382 return;
383 }
384 }
Johnny Chen2341d352012-01-05 21:48:15 +0000385
386 case ProcessMessage::eCrashMessage:
Andrew Kaylor05a47892012-12-14 18:24:34 +0000387 // FIXME: Update stop reason as per bugzilla 14598
388 SetPrivateState(eStateStopped);
Johnny Chen2341d352012-01-05 21:48:15 +0000389 break;
Matt Kopecf1fda372013-01-08 16:30:18 +0000390
391 case ProcessMessage::eNewThreadMessage:
392 SetPrivateState(eStateStopped);
393 break;
Johnny Chen2341d352012-01-05 21:48:15 +0000394 }
395
396 m_message_queue.push(message);
397}
398
399void
400ProcessPOSIX::RefreshStateAfterStop()
401{
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000402 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
Johnny Chen2341d352012-01-05 21:48:15 +0000403 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
404 log->Printf ("ProcessPOSIX::%s()", __FUNCTION__);
405
406 Mutex::Locker lock(m_message_mutex);
407 if (m_message_queue.empty())
408 return;
409
410 ProcessMessage &message = m_message_queue.front();
411
412 // Resolve the thread this message corresponds to and pass it along.
413 // FIXME: we're really dealing with the pid here. This should get
414 // fixed when this code is fixed to handle multiple threads.
415 lldb::tid_t tid = message.GetTID();
416 if (log)
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000417 log->Printf ("ProcessPOSIX::%s() pid = %" PRIi64, __FUNCTION__, tid);
Johnny Chen2341d352012-01-05 21:48:15 +0000418 POSIXThread *thread = static_cast<POSIXThread*>(
419 GetThreadList().FindThreadByID(tid, false).get());
420
Matt Kopecf1fda372013-01-08 16:30:18 +0000421 if (message.GetKind() == ProcessMessage::eNewThreadMessage) {
422 ThreadSP thread_sp;
423 thread_sp.reset(new POSIXThread(*this, message.GetChildTID()));
424 m_thread_list.AddThread(thread_sp);
425 }
426
Johnny Chen2341d352012-01-05 21:48:15 +0000427 assert(thread);
428 thread->Notify(message);
429
430 m_message_queue.pop();
431}
432
433bool
434ProcessPOSIX::IsAlive()
435{
436 StateType state = GetPrivateState();
Daniel Malea0247cf52013-04-01 19:48:37 +0000437 return state != eStateDetached
438 && state != eStateExited
439 && state != eStateInvalid
440 && state != eStateUnloaded;
Johnny Chen2341d352012-01-05 21:48:15 +0000441}
442
443size_t
444ProcessPOSIX::DoReadMemory(addr_t vm_addr,
445 void *buf, size_t size, Error &error)
446{
447 assert(m_monitor);
448 return m_monitor->ReadMemory(vm_addr, buf, size, error);
449}
450
451size_t
452ProcessPOSIX::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
453 Error &error)
454{
455 assert(m_monitor);
456 return m_monitor->WriteMemory(vm_addr, buf, size, error);
457}
458
459addr_t
460ProcessPOSIX::DoAllocateMemory(size_t size, uint32_t permissions,
461 Error &error)
462{
463 addr_t allocated_addr = LLDB_INVALID_ADDRESS;
464
465 unsigned prot = 0;
466 if (permissions & lldb::ePermissionsReadable)
467 prot |= eMmapProtRead;
468 if (permissions & lldb::ePermissionsWritable)
469 prot |= eMmapProtWrite;
470 if (permissions & lldb::ePermissionsExecutable)
471 prot |= eMmapProtExec;
472
473 if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
474 eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
475 m_addr_to_mmap_size[allocated_addr] = size;
476 error.Clear();
477 } else {
478 allocated_addr = LLDB_INVALID_ADDRESS;
479 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
480 }
481
482 return allocated_addr;
483}
484
485Error
486ProcessPOSIX::DoDeallocateMemory(lldb::addr_t addr)
487{
488 Error error;
489 MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
490 if (pos != m_addr_to_mmap_size.end() &&
491 InferiorCallMunmap(this, addr, pos->second))
492 m_addr_to_mmap_size.erase (pos);
493 else
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000494 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
Johnny Chen2341d352012-01-05 21:48:15 +0000495
496 return error;
497}
498
Matt Kopec4f9103f2013-02-27 20:13:38 +0000499addr_t
500ProcessPOSIX::ResolveIndirectFunction(const Address *address, Error &error)
501{
502 addr_t function_addr = LLDB_INVALID_ADDRESS;
503 if (address == NULL) {
504 error.SetErrorStringWithFormat("unable to determine direct function call for NULL address");
505 } else if (!InferiorCall(this, address, function_addr)) {
506 function_addr = LLDB_INVALID_ADDRESS;
Matt Kopec70125482013-03-01 17:44:31 +0000507 error.SetErrorStringWithFormat("unable to determine direct function call for indirect function %s",
508 address->CalculateSymbolContextSymbol()->GetName().AsCString());
Matt Kopec4f9103f2013-02-27 20:13:38 +0000509 }
510 return function_addr;
511}
512
Johnny Chen2341d352012-01-05 21:48:15 +0000513size_t
514ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
515{
516 static const uint8_t g_i386_opcode[] = { 0xCC };
517
518 ArchSpec arch = GetTarget().GetArchitecture();
519 const uint8_t *opcode = NULL;
520 size_t opcode_size = 0;
521
522 switch (arch.GetCore())
523 {
524 default:
525 assert(false && "CPU type not supported!");
526 break;
527
528 case ArchSpec::eCore_x86_32_i386:
529 case ArchSpec::eCore_x86_64_x86_64:
530 opcode = g_i386_opcode;
531 opcode_size = sizeof(g_i386_opcode);
532 break;
533 }
534
535 bp_site->SetTrapOpcode(opcode, opcode_size);
536 return opcode_size;
537}
538
539Error
Daniel Malea52d8dd92013-02-15 20:23:25 +0000540ProcessPOSIX::EnableBreakpointSite(BreakpointSite *bp_site)
Johnny Chen2341d352012-01-05 21:48:15 +0000541{
542 return EnableSoftwareBreakpoint(bp_site);
543}
544
545Error
Daniel Malea52d8dd92013-02-15 20:23:25 +0000546ProcessPOSIX::DisableBreakpointSite(BreakpointSite *bp_site)
Johnny Chen2341d352012-01-05 21:48:15 +0000547{
548 return DisableSoftwareBreakpoint(bp_site);
549}
550
Matt Kopec3d4d51c2013-05-07 19:29:28 +0000551Error
552ProcessPOSIX::EnableWatchpoint(Watchpoint *wp, bool notify)
553{
554 Error error;
555 if (wp)
556 {
557 user_id_t watchID = wp->GetID();
558 addr_t addr = wp->GetLoadAddress();
559 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
560 if (log)
561 log->Printf ("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64 ")",
562 watchID);
563 if (wp->IsEnabled())
564 {
565 if (log)
566 log->Printf("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64
567 ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
568 watchID, (uint64_t)addr);
569 return error;
570 }
571
572 bool wp_enabled = true;
573 uint32_t thread_count = m_thread_list.GetSize(false);
574 for (uint32_t i = 0; i < thread_count; ++i)
575 {
576 POSIXThread *thread = static_cast<POSIXThread*>(
577 m_thread_list.GetThreadAtIndex(i, false).get());
578 if (thread)
579 wp_enabled &= thread->EnableHardwareWatchpoint(wp);
580 else
581 {
582 wp_enabled = false;
583 break;
584 }
585 }
586 if (wp_enabled)
587 {
588 wp->SetEnabled(true, notify);
589 return error;
590 }
591 else
592 {
593 // Watchpoint enabling failed on at least one
594 // of the threads so roll back all of them
595 DisableWatchpoint(wp, false);
596 error.SetErrorString("Setting hardware watchpoint failed");
597 }
598 }
599 else
600 error.SetErrorString("Watchpoint argument was NULL.");
601 return error;
602}
603
604Error
605ProcessPOSIX::DisableWatchpoint(Watchpoint *wp, bool notify)
606{
607 Error error;
608 if (wp)
609 {
610 user_id_t watchID = wp->GetID();
611 addr_t addr = wp->GetLoadAddress();
612 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
613 if (log)
614 log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64 ")",
615 watchID);
616 if (!wp->IsEnabled())
617 {
618 if (log)
619 log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64
620 ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
621 watchID, (uint64_t)addr);
622 // This is needed (for now) to keep watchpoints disabled correctly
623 wp->SetEnabled(false, notify);
624 return error;
625 }
626
627 if (wp->IsHardware())
628 {
629 bool wp_disabled = true;
630 uint32_t thread_count = m_thread_list.GetSize(false);
631 for (uint32_t i = 0; i < thread_count; ++i)
632 {
633 POSIXThread *thread = static_cast<POSIXThread*>(
634 m_thread_list.GetThreadAtIndex(i, false).get());
635 if (thread)
636 wp_disabled &= thread->DisableHardwareWatchpoint(wp);
637 else
638 wp_disabled = false;
639 }
640 if (wp_disabled)
641 {
642 wp->SetEnabled(false, notify);
643 return error;
644 }
645 else
646 error.SetErrorString("Disabling hardware watchpoint failed");
647 }
648 }
649 else
650 error.SetErrorString("Watchpoint argument was NULL.");
651 return error;
652}
653
654Error
655ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num)
656{
657 Error error;
658 POSIXThread *thread = static_cast<POSIXThread*>(
659 m_thread_list.GetThreadAtIndex(0, false).get());
660 if (thread)
661 num = thread->NumSupportedHardwareWatchpoints();
662 else
663 error.SetErrorString("Process does not exist.");
664 return error;
665}
666
667Error
668ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num, bool &after)
669{
670 Error error = GetWatchpointSupportInfo(num);
671 // Watchpoints trigger and halt the inferior after
672 // the corresponding instruction has been executed.
673 after = true;
674 return error;
675}
676
Johnny Chen2341d352012-01-05 21:48:15 +0000677uint32_t
678ProcessPOSIX::UpdateThreadListIfNeeded()
679{
680 // Do not allow recursive updates.
681 return m_thread_list.GetSize(false);
682}
683
Greg Claytonc8dd5702012-04-12 19:04:34 +0000684bool
Johnny Chen2341d352012-01-05 21:48:15 +0000685ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
686{
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000687 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
Johnny Chen2341d352012-01-05 21:48:15 +0000688 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000689 log->Printf ("ProcessPOSIX::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID());
Johnny Chen2341d352012-01-05 21:48:15 +0000690
691 // Update the process thread list with this new thread.
692 // FIXME: We should be using tid, not pid.
693 assert(m_monitor);
694 ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
Greg Claytone5eaa302012-02-21 18:40:07 +0000695 if (!thread_sp) {
Greg Clayton5e91e372012-10-12 16:23:23 +0000696 thread_sp.reset(new POSIXThread(*this, GetID()));
Greg Claytone5eaa302012-02-21 18:40:07 +0000697 }
Johnny Chen2341d352012-01-05 21:48:15 +0000698
699 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000700 log->Printf ("ProcessPOSIX::%s() updated pid = %" PRIi64, __FUNCTION__, GetID());
Johnny Chen2341d352012-01-05 21:48:15 +0000701 new_thread_list.AddThread(thread_sp);
702
Greg Claytonc8dd5702012-04-12 19:04:34 +0000703 return new_thread_list.GetSize(false) > 0;
Johnny Chen2341d352012-01-05 21:48:15 +0000704}
705
706ByteOrder
707ProcessPOSIX::GetByteOrder() const
708{
709 // FIXME: We should be able to extract this value directly. See comment in
710 // ProcessPOSIX().
711 return m_byte_order;
712}
713
714size_t
715ProcessPOSIX::PutSTDIN(const char *buf, size_t len, Error &error)
716{
717 ssize_t status;
718 if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
719 {
720 error.SetErrorToErrno();
721 return 0;
722 }
723 return status;
724}
725
Johnny Chen2341d352012-01-05 21:48:15 +0000726UnixSignals &
727ProcessPOSIX::GetUnixSignals()
728{
729 return m_signals;
730}
731
732//------------------------------------------------------------------------------
733// Utility functions.
734
735bool
736ProcessPOSIX::HasExited()
737{
738 switch (GetPrivateState())
739 {
740 default:
741 break;
742
743 case eStateDetached:
744 case eStateExited:
745 return true;
746 }
747
748 return false;
749}
750
751bool
752ProcessPOSIX::IsStopped()
753{
754 switch (GetPrivateState())
755 {
756 default:
757 break;
758
759 case eStateStopped:
760 case eStateCrashed:
761 case eStateSuspended:
762 return true;
763 }
764
765 return false;
766}