blob: a12377792d0b66166e265529a42004dc5c7165dc [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- Process.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
10#include "lldb/Target/Process.h"
11
12#include "lldb/lldb-private-log.h"
13
14#include "lldb/Breakpoint/StoppointCallbackContext.h"
15#include "lldb/Breakpoint/BreakpointLocation.h"
16#include "lldb/Core/Event.h"
17#include "lldb/Core/Debugger.h"
18#include "lldb/Core/Log.h"
19#include "lldb/Core/PluginManager.h"
20#include "lldb/Core/State.h"
Caroline Tice6e4c5ce2010-09-04 00:03:46 +000021#include "lldb/Interpreter/CommandInterpreter.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022#include "lldb/Host/Host.h"
23#include "lldb/Target/ABI.h"
Jim Ingham642036f2010-09-23 02:01:19 +000024#include "lldb/Target/LanguageRuntime.h"
25#include "lldb/Target/CPPLanguageRuntime.h"
26#include "lldb/Target/ObjCLanguageRuntime.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027#include "lldb/Target/RegisterContext.h"
Greg Clayton643ee732010-08-04 01:40:35 +000028#include "lldb/Target/StopInfo.h"
Chris Lattner24943d22010-06-08 16:52:24 +000029#include "lldb/Target/Target.h"
30#include "lldb/Target/TargetList.h"
31#include "lldb/Target/Thread.h"
32#include "lldb/Target/ThreadPlan.h"
33
34using namespace lldb;
35using namespace lldb_private;
36
37Process*
38Process::FindPlugin (Target &target, const char *plugin_name, Listener &listener)
39{
40 ProcessCreateInstance create_callback = NULL;
41 if (plugin_name)
42 {
43 create_callback = PluginManager::GetProcessCreateCallbackForPluginName (plugin_name);
44 if (create_callback)
45 {
46 std::auto_ptr<Process> debugger_ap(create_callback(target, listener));
47 if (debugger_ap->CanDebug(target))
48 return debugger_ap.release();
49 }
50 }
51 else
52 {
Greg Clayton54e7afa2010-07-09 20:39:50 +000053 for (uint32_t idx = 0; (create_callback = PluginManager::GetProcessCreateCallbackAtIndex(idx)) != NULL; ++idx)
Chris Lattner24943d22010-06-08 16:52:24 +000054 {
Greg Clayton54e7afa2010-07-09 20:39:50 +000055 std::auto_ptr<Process> debugger_ap(create_callback(target, listener));
56 if (debugger_ap->CanDebug(target))
57 return debugger_ap.release();
Chris Lattner24943d22010-06-08 16:52:24 +000058 }
59 }
60 return NULL;
61}
62
63
64//----------------------------------------------------------------------
65// Process constructor
66//----------------------------------------------------------------------
67Process::Process(Target &target, Listener &listener) :
68 UserID (LLDB_INVALID_PROCESS_ID),
69 Broadcaster ("Process"),
Caroline Tice6e4c5ce2010-09-04 00:03:46 +000070 ProcessInstanceSettings (*(Process::GetSettingsController().get())),
Chris Lattner24943d22010-06-08 16:52:24 +000071 m_target (target),
Chris Lattner24943d22010-06-08 16:52:24 +000072 m_public_state (eStateUnloaded),
73 m_private_state (eStateUnloaded),
74 m_private_state_broadcaster ("lldb.process.internal_state_broadcaster"),
75 m_private_state_control_broadcaster ("lldb.process.internal_state_control_broadcaster"),
76 m_private_state_listener ("lldb.process.internal_state_listener"),
77 m_private_state_control_wait(),
78 m_private_state_thread (LLDB_INVALID_HOST_THREAD),
79 m_stop_id (0),
80 m_thread_index_id (0),
81 m_exit_status (-1),
82 m_exit_string (),
83 m_thread_list (this),
84 m_notifications (),
85 m_listener(listener),
86 m_unix_signals (),
Sean Callanana48fe162010-08-11 03:57:18 +000087 m_objc_object_printer(*this),
88 m_persistent_vars()
Chris Lattner24943d22010-06-08 16:52:24 +000089{
90 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
91 if (log)
92 log->Printf ("%p Process::Process()", this);
93
94 listener.StartListeningForEvents (this,
95 eBroadcastBitStateChanged |
96 eBroadcastBitInterrupt |
97 eBroadcastBitSTDOUT |
98 eBroadcastBitSTDERR);
99
100 m_private_state_listener.StartListeningForEvents(&m_private_state_broadcaster,
101 eBroadcastBitStateChanged);
102
103 m_private_state_listener.StartListeningForEvents(&m_private_state_control_broadcaster,
104 eBroadcastInternalStateControlStop |
105 eBroadcastInternalStateControlPause |
106 eBroadcastInternalStateControlResume);
107}
108
109//----------------------------------------------------------------------
110// Destructor
111//----------------------------------------------------------------------
112Process::~Process()
113{
114 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
115 if (log)
116 log->Printf ("%p Process::~Process()", this);
117 StopPrivateStateThread();
118}
119
120void
121Process::Finalize()
122{
123 // Do any cleanup needed prior to being destructed... Subclasses
124 // that override this method should call this superclass method as well.
125}
126
127void
128Process::RegisterNotificationCallbacks (const Notifications& callbacks)
129{
130 m_notifications.push_back(callbacks);
131 if (callbacks.initialize != NULL)
132 callbacks.initialize (callbacks.baton, this);
133}
134
135bool
136Process::UnregisterNotificationCallbacks(const Notifications& callbacks)
137{
138 std::vector<Notifications>::iterator pos, end = m_notifications.end();
139 for (pos = m_notifications.begin(); pos != end; ++pos)
140 {
141 if (pos->baton == callbacks.baton &&
142 pos->initialize == callbacks.initialize &&
143 pos->process_state_changed == callbacks.process_state_changed)
144 {
145 m_notifications.erase(pos);
146 return true;
147 }
148 }
149 return false;
150}
151
152void
153Process::SynchronouslyNotifyStateChanged (StateType state)
154{
155 std::vector<Notifications>::iterator notification_pos, notification_end = m_notifications.end();
156 for (notification_pos = m_notifications.begin(); notification_pos != notification_end; ++notification_pos)
157 {
158 if (notification_pos->process_state_changed)
159 notification_pos->process_state_changed (notification_pos->baton, this, state);
160 }
161}
162
163// FIXME: We need to do some work on events before the general Listener sees them.
164// For instance if we are continuing from a breakpoint, we need to ensure that we do
165// the little "insert real insn, step & stop" trick. But we can't do that when the
166// event is delivered by the broadcaster - since that is done on the thread that is
167// waiting for new events, so if we needed more than one event for our handling, we would
168// stall. So instead we do it when we fetch the event off of the queue.
169//
170
171StateType
172Process::GetNextEvent (EventSP &event_sp)
173{
174 StateType state = eStateInvalid;
175
176 if (m_listener.GetNextEventForBroadcaster (this, event_sp) && event_sp)
177 state = Process::ProcessEventData::GetStateFromEvent (event_sp.get());
178
179 return state;
180}
181
182
183StateType
184Process::WaitForProcessToStop (const TimeValue *timeout)
185{
186 StateType match_states[] = { eStateStopped, eStateCrashed, eStateDetached, eStateExited, eStateUnloaded };
187 return WaitForState (timeout, match_states, sizeof(match_states) / sizeof(StateType));
188}
189
190
191StateType
192Process::WaitForState
193(
194 const TimeValue *timeout,
195 const StateType *match_states, const uint32_t num_match_states
196)
197{
198 EventSP event_sp;
199 uint32_t i;
200 StateType state = eStateUnloaded;
201 while (state != eStateInvalid)
202 {
203 state = WaitForStateChangedEvents (timeout, event_sp);
204
205 for (i=0; i<num_match_states; ++i)
206 {
207 if (match_states[i] == state)
208 return state;
209 }
210 }
211 return state;
212}
213
214StateType
215Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp)
216{
217 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
218
219 if (log)
220 log->Printf ("Process::%s (timeout = %p, event_sp)...", __FUNCTION__, timeout);
221
222 StateType state = eStateInvalid;
223 if (m_listener.WaitForEventForBroadcasterWithType(timeout,
224 this,
225 eBroadcastBitStateChanged,
226 event_sp))
227 state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
228
229 if (log)
230 log->Printf ("Process::%s (timeout = %p, event_sp) => %s",
231 __FUNCTION__,
232 timeout,
233 StateAsCString(state));
234 return state;
235}
236
237Event *
238Process::PeekAtStateChangedEvents ()
239{
240 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
241
242 if (log)
243 log->Printf ("Process::%s...", __FUNCTION__);
244
245 Event *event_ptr;
246 event_ptr = m_listener.PeekAtNextEventForBroadcasterWithType(this,
247 eBroadcastBitStateChanged);
248 if (log)
249 {
250 if (event_ptr)
251 {
252 log->Printf ("Process::%s (event_ptr) => %s",
253 __FUNCTION__,
254 StateAsCString(ProcessEventData::GetStateFromEvent (event_ptr)));
255 }
256 else
257 {
258 log->Printf ("Process::%s no events found",
259 __FUNCTION__);
260 }
261 }
262 return event_ptr;
263}
264
265StateType
266Process::WaitForStateChangedEventsPrivate (const TimeValue *timeout, EventSP &event_sp)
267{
268 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
269
270 if (log)
271 log->Printf ("Process::%s (timeout = %p, event_sp)...", __FUNCTION__, timeout);
272
273 StateType state = eStateInvalid;
274 if (m_private_state_listener.WaitForEventForBroadcasterWithType(timeout,
275 &m_private_state_broadcaster,
276 eBroadcastBitStateChanged,
277 event_sp))
278 state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
279
280 // This is a bit of a hack, but when we wait here we could very well return
281 // to the command-line, and that could disable the log, which would render the
282 // log we got above invalid.
283 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
284 if (log)
285 log->Printf ("Process::%s (timeout = %p, event_sp) => %s", __FUNCTION__, timeout, StateAsCString(state));
286 return state;
287}
288
289bool
290Process::WaitForEventsPrivate (const TimeValue *timeout, EventSP &event_sp, bool control_only)
291{
292 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
293
294 if (log)
295 log->Printf ("Process::%s (timeout = %p, event_sp)...", __FUNCTION__, timeout);
296
297 if (control_only)
298 return m_private_state_listener.WaitForEventForBroadcaster(timeout, &m_private_state_control_broadcaster, event_sp);
299 else
300 return m_private_state_listener.WaitForEvent(timeout, event_sp);
301}
302
303bool
304Process::IsRunning () const
305{
306 return StateIsRunningState (m_public_state.GetValue());
307}
308
309int
310Process::GetExitStatus ()
311{
312 if (m_public_state.GetValue() == eStateExited)
313 return m_exit_status;
314 return -1;
315}
316
317const char *
318Process::GetExitDescription ()
319{
320 if (m_public_state.GetValue() == eStateExited && !m_exit_string.empty())
321 return m_exit_string.c_str();
322 return NULL;
323}
324
325void
326Process::SetExitStatus (int status, const char *cstr)
327{
328 m_exit_status = status;
329 if (cstr)
330 m_exit_string = cstr;
331 else
332 m_exit_string.clear();
333
334 SetPrivateState (eStateExited);
335}
336
337// This static callback can be used to watch for local child processes on
338// the current host. The the child process exits, the process will be
339// found in the global target list (we want to be completely sure that the
340// lldb_private::Process doesn't go away before we can deliver the signal.
341bool
342Process::SetProcessExitStatus
343(
344 void *callback_baton,
345 lldb::pid_t pid,
346 int signo, // Zero for no signal
347 int exit_status // Exit value of process if signal is zero
348)
349{
350 if (signo == 0 || exit_status)
351 {
Greg Clayton63094e02010-06-23 01:19:29 +0000352 TargetSP target_sp(Debugger::FindTargetWithProcessID (pid));
Chris Lattner24943d22010-06-08 16:52:24 +0000353 if (target_sp)
354 {
355 ProcessSP process_sp (target_sp->GetProcessSP());
356 if (process_sp)
357 {
358 const char *signal_cstr = NULL;
359 if (signo)
360 signal_cstr = process_sp->GetUnixSignals().GetSignalAsCString (signo);
361
362 process_sp->SetExitStatus (exit_status, signal_cstr);
363 }
364 }
365 return true;
366 }
367 return false;
368}
369
370
371uint32_t
372Process::GetNextThreadIndexID ()
373{
374 return ++m_thread_index_id;
375}
376
377StateType
378Process::GetState()
379{
380 // If any other threads access this we will need a mutex for it
381 return m_public_state.GetValue ();
382}
383
384void
385Process::SetPublicState (StateType new_state)
386{
387 Log *log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STATE);
388 if (log)
389 log->Printf("Process::SetPublicState (%s)", StateAsCString(new_state));
390 m_public_state.SetValue (new_state);
391}
392
393StateType
394Process::GetPrivateState ()
395{
396 return m_private_state.GetValue();
397}
398
399void
400Process::SetPrivateState (StateType new_state)
401{
402 Log *log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STATE);
403 bool state_changed = false;
404
405 if (log)
406 log->Printf("Process::SetPrivateState (%s)", StateAsCString(new_state));
407
408 Mutex::Locker locker(m_private_state.GetMutex());
409
410 const StateType old_state = m_private_state.GetValueNoLock ();
411 state_changed = old_state != new_state;
412 if (state_changed)
413 {
414 m_private_state.SetValueNoLock (new_state);
415 if (StateIsStoppedState(new_state))
416 {
417 m_stop_id++;
418 if (log)
419 log->Printf("Process::SetPrivateState (%s) stop_id = %u", StateAsCString(new_state), m_stop_id);
420 }
421 // Use our target to get a shared pointer to ourselves...
422 m_private_state_broadcaster.BroadcastEvent (eBroadcastBitStateChanged, new ProcessEventData (GetTarget().GetProcessSP(), new_state));
423 }
424 else
425 {
426 if (log)
427 log->Printf("Process::SetPrivateState (%s) state didn't change. Ignoring...", StateAsCString(new_state), StateAsCString(old_state));
428 }
429}
430
431
432uint32_t
433Process::GetStopID() const
434{
435 return m_stop_id;
436}
437
438addr_t
439Process::GetImageInfoAddress()
440{
441 return LLDB_INVALID_ADDRESS;
442}
443
444DynamicLoader *
445Process::GetDynamicLoader()
446{
447 return NULL;
448}
449
450const ABI *
451Process::GetABI()
452{
453 ConstString& triple = m_target_triple;
454
455 if (triple.IsEmpty())
456 return NULL;
457
458 if (m_abi_sp.get() == NULL)
459 {
460 m_abi_sp.reset(ABI::FindPlugin(triple));
461 }
462
463 return m_abi_sp.get();
464}
465
Jim Ingham642036f2010-09-23 02:01:19 +0000466LanguageRuntime *
467Process::GetLanguageRuntime(lldb::LanguageType language)
468{
469 LanguageRuntimeCollection::iterator pos;
470 pos = m_language_runtimes.find (language);
471 if (pos == m_language_runtimes.end())
472 {
473 lldb::LanguageRuntimeSP runtime(LanguageRuntime::FindPlugin(this, language));
474
475 m_language_runtimes[language]
476 = runtime;
477 return runtime.get();
478 }
479 else
480 return (*pos).second.get();
481}
482
483CPPLanguageRuntime *
484Process::GetCPPLanguageRuntime ()
485{
486 LanguageRuntime *runtime = GetLanguageRuntime(eLanguageTypeC_plus_plus);
487 if (runtime != NULL && runtime->GetLanguageType() == eLanguageTypeC_plus_plus)
488 return static_cast<CPPLanguageRuntime *> (runtime);
489 return NULL;
490}
491
492ObjCLanguageRuntime *
493Process::GetObjCLanguageRuntime ()
494{
495 LanguageRuntime *runtime = GetLanguageRuntime(eLanguageTypeObjC);
496 if (runtime != NULL && runtime->GetLanguageType() == eLanguageTypeObjC)
497 return static_cast<ObjCLanguageRuntime *> (runtime);
498 return NULL;
499}
500
Chris Lattner24943d22010-06-08 16:52:24 +0000501BreakpointSiteList &
502Process::GetBreakpointSiteList()
503{
504 return m_breakpoint_site_list;
505}
506
507const BreakpointSiteList &
508Process::GetBreakpointSiteList() const
509{
510 return m_breakpoint_site_list;
511}
512
513
514void
515Process::DisableAllBreakpointSites ()
516{
517 m_breakpoint_site_list.SetEnabledForAll (false);
518}
519
520Error
521Process::ClearBreakpointSiteByID (lldb::user_id_t break_id)
522{
523 Error error (DisableBreakpointSiteByID (break_id));
524
525 if (error.Success())
526 m_breakpoint_site_list.Remove(break_id);
527
528 return error;
529}
530
531Error
532Process::DisableBreakpointSiteByID (lldb::user_id_t break_id)
533{
534 Error error;
535 BreakpointSiteSP bp_site_sp = m_breakpoint_site_list.FindByID (break_id);
536 if (bp_site_sp)
537 {
538 if (bp_site_sp->IsEnabled())
539 error = DisableBreakpoint (bp_site_sp.get());
540 }
541 else
542 {
543 error.SetErrorStringWithFormat("invalid breakpoint site ID: %i", break_id);
544 }
545
546 return error;
547}
548
549Error
550Process::EnableBreakpointSiteByID (lldb::user_id_t break_id)
551{
552 Error error;
553 BreakpointSiteSP bp_site_sp = m_breakpoint_site_list.FindByID (break_id);
554 if (bp_site_sp)
555 {
556 if (!bp_site_sp->IsEnabled())
557 error = EnableBreakpoint (bp_site_sp.get());
558 }
559 else
560 {
561 error.SetErrorStringWithFormat("invalid breakpoint site ID: %i", break_id);
562 }
563 return error;
564}
565
Stephen Wilson3fd1f362010-07-17 00:56:13 +0000566lldb::break_id_t
Chris Lattner24943d22010-06-08 16:52:24 +0000567Process::CreateBreakpointSite (BreakpointLocationSP &owner, bool use_hardware)
568{
Greg Claytoneea26402010-09-14 23:36:40 +0000569 const addr_t load_addr = owner->GetAddress().GetLoadAddress (&m_target);
Chris Lattner24943d22010-06-08 16:52:24 +0000570 if (load_addr != LLDB_INVALID_ADDRESS)
571 {
572 BreakpointSiteSP bp_site_sp;
573
574 // Look up this breakpoint site. If it exists, then add this new owner, otherwise
575 // create a new breakpoint site and add it.
576
577 bp_site_sp = m_breakpoint_site_list.FindByAddress (load_addr);
578
579 if (bp_site_sp)
580 {
581 bp_site_sp->AddOwner (owner);
582 owner->SetBreakpointSite (bp_site_sp);
583 return bp_site_sp->GetID();
584 }
585 else
586 {
587 bp_site_sp.reset (new BreakpointSite (&m_breakpoint_site_list, owner, load_addr, LLDB_INVALID_THREAD_ID, use_hardware));
588 if (bp_site_sp)
589 {
590 if (EnableBreakpoint (bp_site_sp.get()).Success())
591 {
592 owner->SetBreakpointSite (bp_site_sp);
593 return m_breakpoint_site_list.Add (bp_site_sp);
594 }
595 }
596 }
597 }
598 // We failed to enable the breakpoint
599 return LLDB_INVALID_BREAK_ID;
600
601}
602
603void
604Process::RemoveOwnerFromBreakpointSite (lldb::user_id_t owner_id, lldb::user_id_t owner_loc_id, BreakpointSiteSP &bp_site_sp)
605{
606 uint32_t num_owners = bp_site_sp->RemoveOwner (owner_id, owner_loc_id);
607 if (num_owners == 0)
608 {
609 DisableBreakpoint(bp_site_sp.get());
610 m_breakpoint_site_list.RemoveByAddress(bp_site_sp->GetLoadAddress());
611 }
612}
613
614
615size_t
616Process::RemoveBreakpointOpcodesFromBuffer (addr_t bp_addr, size_t size, uint8_t *buf) const
617{
618 size_t bytes_removed = 0;
619 addr_t intersect_addr;
620 size_t intersect_size;
621 size_t opcode_offset;
622 size_t idx;
623 BreakpointSiteSP bp;
624
625 for (idx = 0; (bp = m_breakpoint_site_list.GetByIndex(idx)) != NULL; ++idx)
626 {
627 if (bp->GetType() == BreakpointSite::eSoftware)
628 {
629 if (bp->IntersectsRange(bp_addr, size, &intersect_addr, &intersect_size, &opcode_offset))
630 {
631 assert(bp_addr <= intersect_addr && intersect_addr < bp_addr + size);
632 assert(bp_addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= bp_addr + size);
633 assert(opcode_offset + intersect_size <= bp->GetByteSize());
634 size_t buf_offset = intersect_addr - bp_addr;
635 ::memcpy(buf + buf_offset, bp->GetSavedOpcodeBytes() + opcode_offset, intersect_size);
636 }
637 }
638 }
639 return bytes_removed;
640}
641
642
643Error
644Process::EnableSoftwareBreakpoint (BreakpointSite *bp_site)
645{
646 Error error;
647 assert (bp_site != NULL);
648 Log *log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
649 const addr_t bp_addr = bp_site->GetLoadAddress();
650 if (log)
651 log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%llx", bp_site->GetID(), (uint64_t)bp_addr);
652 if (bp_site->IsEnabled())
653 {
654 if (log)
655 log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- already enabled", bp_site->GetID(), (uint64_t)bp_addr);
656 return error;
657 }
658
659 if (bp_addr == LLDB_INVALID_ADDRESS)
660 {
661 error.SetErrorString("BreakpointSite contains an invalid load address.");
662 return error;
663 }
664 // Ask the lldb::Process subclass to fill in the correct software breakpoint
665 // trap for the breakpoint site
666 const size_t bp_opcode_size = GetSoftwareBreakpointTrapOpcode(bp_site);
667
668 if (bp_opcode_size == 0)
669 {
670 error.SetErrorStringWithFormat ("Process::GetSoftwareBreakpointTrapOpcode() returned zero, unable to get breakpoint trap for address 0x%llx.\n", bp_addr);
671 }
672 else
673 {
674 const uint8_t * const bp_opcode_bytes = bp_site->GetTrapOpcodeBytes();
675
676 if (bp_opcode_bytes == NULL)
677 {
678 error.SetErrorString ("BreakpointSite doesn't contain a valid breakpoint trap opcode.");
679 return error;
680 }
681
682 // Save the original opcode by reading it
683 if (DoReadMemory(bp_addr, bp_site->GetSavedOpcodeBytes(), bp_opcode_size, error) == bp_opcode_size)
684 {
685 // Write a software breakpoint in place of the original opcode
686 if (DoWriteMemory(bp_addr, bp_opcode_bytes, bp_opcode_size, error) == bp_opcode_size)
687 {
688 uint8_t verify_bp_opcode_bytes[64];
689 if (DoReadMemory(bp_addr, verify_bp_opcode_bytes, bp_opcode_size, error) == bp_opcode_size)
690 {
691 if (::memcmp(bp_opcode_bytes, verify_bp_opcode_bytes, bp_opcode_size) == 0)
692 {
693 bp_site->SetEnabled(true);
694 bp_site->SetType (BreakpointSite::eSoftware);
695 if (log)
696 log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- SUCCESS",
697 bp_site->GetID(),
698 (uint64_t)bp_addr);
699 }
700 else
701 error.SetErrorString("Failed to verify the breakpoint trap in memory.");
702 }
703 else
704 error.SetErrorString("Unable to read memory to verify breakpoint trap.");
705 }
706 else
707 error.SetErrorString("Unable to write breakpoint trap to memory.");
708 }
709 else
710 error.SetErrorString("Unable to read memory at breakpoint address.");
711 }
712 if (log)
713 log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- FAILED: %s",
714 bp_site->GetID(),
715 (uint64_t)bp_addr,
716 error.AsCString());
717 return error;
718}
719
720Error
721Process::DisableSoftwareBreakpoint (BreakpointSite *bp_site)
722{
723 Error error;
724 assert (bp_site != NULL);
725 Log *log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
726 addr_t bp_addr = bp_site->GetLoadAddress();
727 lldb::user_id_t breakID = bp_site->GetID();
728 if (log)
729 log->Printf ("ProcessMacOSX::DisableBreakpoint (breakID = %d) addr = 0x%llx", breakID, (uint64_t)bp_addr);
730
731 if (bp_site->IsHardware())
732 {
733 error.SetErrorString("Breakpoint site is a hardware breakpoint.");
734 }
735 else if (bp_site->IsEnabled())
736 {
737 const size_t break_op_size = bp_site->GetByteSize();
738 const uint8_t * const break_op = bp_site->GetTrapOpcodeBytes();
739 if (break_op_size > 0)
740 {
741 // Clear a software breakoint instruction
Greg Clayton54e7afa2010-07-09 20:39:50 +0000742 uint8_t curr_break_op[8];
Stephen Wilson141eeac2010-07-20 18:41:11 +0000743 assert (break_op_size <= sizeof(curr_break_op));
Chris Lattner24943d22010-06-08 16:52:24 +0000744 bool break_op_found = false;
745
746 // Read the breakpoint opcode
747 if (DoReadMemory (bp_addr, curr_break_op, break_op_size, error) == break_op_size)
748 {
749 bool verify = false;
750 // Make sure we have the a breakpoint opcode exists at this address
751 if (::memcmp (curr_break_op, break_op, break_op_size) == 0)
752 {
753 break_op_found = true;
754 // We found a valid breakpoint opcode at this address, now restore
755 // the saved opcode.
756 if (DoWriteMemory (bp_addr, bp_site->GetSavedOpcodeBytes(), break_op_size, error) == break_op_size)
757 {
758 verify = true;
759 }
760 else
761 error.SetErrorString("Memory write failed when restoring original opcode.");
762 }
763 else
764 {
765 error.SetErrorString("Original breakpoint trap is no longer in memory.");
766 // Set verify to true and so we can check if the original opcode has already been restored
767 verify = true;
768 }
769
770 if (verify)
771 {
Greg Clayton54e7afa2010-07-09 20:39:50 +0000772 uint8_t verify_opcode[8];
Stephen Wilson141eeac2010-07-20 18:41:11 +0000773 assert (break_op_size < sizeof(verify_opcode));
Chris Lattner24943d22010-06-08 16:52:24 +0000774 // Verify that our original opcode made it back to the inferior
775 if (DoReadMemory (bp_addr, verify_opcode, break_op_size, error) == break_op_size)
776 {
777 // compare the memory we just read with the original opcode
778 if (::memcmp (bp_site->GetSavedOpcodeBytes(), verify_opcode, break_op_size) == 0)
779 {
780 // SUCCESS
781 bp_site->SetEnabled(false);
782 if (log)
783 log->Printf ("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- SUCCESS", bp_site->GetID(), (uint64_t)bp_addr);
784 return error;
785 }
786 else
787 {
788 if (break_op_found)
789 error.SetErrorString("Failed to restore original opcode.");
790 }
791 }
792 else
793 error.SetErrorString("Failed to read memory to verify that breakpoint trap was restored.");
794 }
795 }
796 else
797 error.SetErrorString("Unable to read memory that should contain the breakpoint trap.");
798 }
799 }
800 else
801 {
802 if (log)
803 log->Printf ("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- already disabled", bp_site->GetID(), (uint64_t)bp_addr);
804 return error;
805 }
806
807 if (log)
808 log->Printf ("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- FAILED: %s",
809 bp_site->GetID(),
810 (uint64_t)bp_addr,
811 error.AsCString());
812 return error;
813
814}
815
816
817size_t
818Process::ReadMemory (addr_t addr, void *buf, size_t size, Error &error)
819{
820 if (buf == NULL || size == 0)
821 return 0;
822
823 size_t bytes_read = 0;
824 uint8_t *bytes = (uint8_t *)buf;
825
826 while (bytes_read < size)
827 {
828 const size_t curr_size = size - bytes_read;
829 const size_t curr_bytes_read = DoReadMemory (addr + bytes_read,
830 bytes + bytes_read,
831 curr_size,
832 error);
833 bytes_read += curr_bytes_read;
834 if (curr_bytes_read == curr_size || curr_bytes_read == 0)
835 break;
836 }
837
838 // Replace any software breakpoint opcodes that fall into this range back
839 // into "buf" before we return
840 if (bytes_read > 0)
841 RemoveBreakpointOpcodesFromBuffer (addr, bytes_read, (uint8_t *)buf);
842 return bytes_read;
843}
844
845size_t
846Process::WriteMemoryPrivate (addr_t addr, const void *buf, size_t size, Error &error)
847{
848 size_t bytes_written = 0;
849 const uint8_t *bytes = (const uint8_t *)buf;
850
851 while (bytes_written < size)
852 {
853 const size_t curr_size = size - bytes_written;
854 const size_t curr_bytes_written = DoWriteMemory (addr + bytes_written,
855 bytes + bytes_written,
856 curr_size,
857 error);
858 bytes_written += curr_bytes_written;
859 if (curr_bytes_written == curr_size || curr_bytes_written == 0)
860 break;
861 }
862 return bytes_written;
863}
864
865size_t
866Process::WriteMemory (addr_t addr, const void *buf, size_t size, Error &error)
867{
868 if (buf == NULL || size == 0)
869 return 0;
870 // We need to write any data that would go where any current software traps
871 // (enabled software breakpoints) any software traps (breakpoints) that we
872 // may have placed in our tasks memory.
873
874 BreakpointSiteList::collection::const_iterator iter = m_breakpoint_site_list.GetMap()->lower_bound (addr);
875 BreakpointSiteList::collection::const_iterator end = m_breakpoint_site_list.GetMap()->end();
876
877 if (iter == end || iter->second->GetLoadAddress() > addr + size)
878 return DoWriteMemory(addr, buf, size, error);
879
880 BreakpointSiteList::collection::const_iterator pos;
881 size_t bytes_written = 0;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000882 addr_t intersect_addr = 0;
883 size_t intersect_size = 0;
884 size_t opcode_offset = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000885 const uint8_t *ubuf = (const uint8_t *)buf;
886
887 for (pos = iter; pos != end; ++pos)
888 {
889 BreakpointSiteSP bp;
890 bp = pos->second;
891
892 assert(bp->IntersectsRange(addr, size, &intersect_addr, &intersect_size, &opcode_offset));
893 assert(addr <= intersect_addr && intersect_addr < addr + size);
894 assert(addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= addr + size);
895 assert(opcode_offset + intersect_size <= bp->GetByteSize());
896
897 // Check for bytes before this breakpoint
898 const addr_t curr_addr = addr + bytes_written;
899 if (intersect_addr > curr_addr)
900 {
901 // There are some bytes before this breakpoint that we need to
902 // just write to memory
903 size_t curr_size = intersect_addr - curr_addr;
904 size_t curr_bytes_written = WriteMemoryPrivate (curr_addr,
905 ubuf + bytes_written,
906 curr_size,
907 error);
908 bytes_written += curr_bytes_written;
909 if (curr_bytes_written != curr_size)
910 {
911 // We weren't able to write all of the requested bytes, we
912 // are done looping and will return the number of bytes that
913 // we have written so far.
914 break;
915 }
916 }
917
918 // Now write any bytes that would cover up any software breakpoints
919 // directly into the breakpoint opcode buffer
920 ::memcpy(bp->GetSavedOpcodeBytes() + opcode_offset, ubuf + bytes_written, intersect_size);
921 bytes_written += intersect_size;
922 }
923
924 // Write any remaining bytes after the last breakpoint if we have any left
925 if (bytes_written < size)
926 bytes_written += WriteMemoryPrivate (addr + bytes_written,
927 ubuf + bytes_written,
928 size - bytes_written,
929 error);
930
931 return bytes_written;
932}
933
934addr_t
935Process::AllocateMemory(size_t size, uint32_t permissions, Error &error)
936{
937 // Fixme: we should track the blocks we've allocated, and clean them up...
938 // We could even do our own allocator here if that ends up being more efficient.
939 return DoAllocateMemory (size, permissions, error);
940}
941
942Error
943Process::DeallocateMemory (addr_t ptr)
944{
945 return DoDeallocateMemory (ptr);
946}
947
948
949Error
950Process::EnableWatchpoint (WatchpointLocation *watchpoint)
951{
952 Error error;
953 error.SetErrorString("watchpoints are not supported");
954 return error;
955}
956
957Error
958Process::DisableWatchpoint (WatchpointLocation *watchpoint)
959{
960 Error error;
961 error.SetErrorString("watchpoints are not supported");
962 return error;
963}
964
965StateType
966Process::WaitForProcessStopPrivate (const TimeValue *timeout, EventSP &event_sp)
967{
968 StateType state;
969 // Now wait for the process to launch and return control to us, and then
970 // call DidLaunch:
971 while (1)
972 {
973 // FIXME: Might want to put a timeout in here:
974 state = WaitForStateChangedEventsPrivate (NULL, event_sp);
975 if (state == eStateStopped || state == eStateCrashed || state == eStateExited)
976 break;
977 else
978 HandlePrivateEvent (event_sp);
979 }
980 return state;
981}
982
983Error
984Process::Launch
985(
986 char const *argv[],
987 char const *envp[],
Greg Clayton452bf612010-08-31 18:35:14 +0000988 uint32_t launch_flags,
Chris Lattner24943d22010-06-08 16:52:24 +0000989 const char *stdin_path,
990 const char *stdout_path,
991 const char *stderr_path
992)
993{
994 Error error;
995 m_target_triple.Clear();
996 m_abi_sp.reset();
997
998 Module *exe_module = m_target.GetExecutableModule().get();
999 if (exe_module)
1000 {
1001 char exec_file_path[PATH_MAX];
1002 exe_module->GetFileSpec().GetPath(exec_file_path, sizeof(exec_file_path));
1003 if (exe_module->GetFileSpec().Exists())
1004 {
1005 error = WillLaunch (exe_module);
1006 if (error.Success())
1007 {
1008 // The args coming in should not contain the application name, the
1009 // lldb_private::Process class will add this in case the executable
1010 // gets resolved to a different file than was given on the command
1011 // line (like when an applicaiton bundle is specified and will
1012 // resolve to the contained exectuable file, or the file given was
1013 // a symlink or other file system link that resolves to a different
1014 // file).
1015
1016 // Get the resolved exectuable path
1017
1018 // Make a new argument vector
1019 std::vector<const char *> exec_path_plus_argv;
1020 // Append the resolved executable path
1021 exec_path_plus_argv.push_back (exec_file_path);
1022
1023 // Push all args if there are any
1024 if (argv)
1025 {
1026 for (int i = 0; argv[i]; ++i)
1027 exec_path_plus_argv.push_back(argv[i]);
1028 }
1029
1030 // Push a NULL to terminate the args.
1031 exec_path_plus_argv.push_back(NULL);
1032
1033 // Now launch using these arguments.
Greg Clayton53d68e72010-07-20 22:52:08 +00001034 error = DoLaunch (exe_module,
1035 exec_path_plus_argv.empty() ? NULL : &exec_path_plus_argv.front(),
1036 envp,
Greg Clayton452bf612010-08-31 18:35:14 +00001037 launch_flags,
Greg Clayton53d68e72010-07-20 22:52:08 +00001038 stdin_path,
1039 stdout_path,
1040 stderr_path);
Chris Lattner24943d22010-06-08 16:52:24 +00001041
1042 if (error.Fail())
1043 {
1044 if (GetID() != LLDB_INVALID_PROCESS_ID)
1045 {
1046 SetID (LLDB_INVALID_PROCESS_ID);
1047 const char *error_string = error.AsCString();
1048 if (error_string == NULL)
1049 error_string = "launch failed";
1050 SetExitStatus (-1, error_string);
1051 }
1052 }
1053 else
1054 {
1055 EventSP event_sp;
1056 StateType state = WaitForProcessStopPrivate(NULL, event_sp);
1057
1058 if (state == eStateStopped || state == eStateCrashed)
1059 {
1060 DidLaunch ();
1061
1062 // This delays passing the stopped event to listeners till DidLaunch gets
1063 // a chance to complete...
1064 HandlePrivateEvent (event_sp);
1065 StartPrivateStateThread ();
1066 }
1067 else if (state == eStateExited)
1068 {
1069 // We exited while trying to launch somehow. Don't call DidLaunch as that's
1070 // not likely to work, and return an invalid pid.
1071 HandlePrivateEvent (event_sp);
1072 }
1073 }
1074 }
1075 }
1076 else
1077 {
1078 error.SetErrorStringWithFormat("File doesn't exist: '%s'.\n", exec_file_path);
1079 }
1080 }
1081 return error;
1082}
1083
1084Error
1085Process::CompleteAttach ()
1086{
1087 Error error;
1088 EventSP event_sp;
1089 StateType state = WaitForProcessStopPrivate(NULL, event_sp);
1090 if (state == eStateStopped || state == eStateCrashed)
1091 {
1092 DidAttach ();
Jim Ingham7508e732010-08-09 23:31:02 +00001093 // Figure out which one is the executable, and set that in our target:
1094 ModuleList &modules = GetTarget().GetImages();
1095
1096 size_t num_modules = modules.GetSize();
1097 for (int i = 0; i < num_modules; i++)
1098 {
1099 ModuleSP module_sp = modules.GetModuleAtIndex(i);
1100 if (module_sp->IsExecutable())
1101 {
1102 ModuleSP exec_module = GetTarget().GetExecutableModule();
1103 if (!exec_module || exec_module != module_sp)
1104 {
1105
1106 GetTarget().SetExecutableModule (module_sp, false);
1107 }
1108 break;
1109 }
1110 }
Chris Lattner24943d22010-06-08 16:52:24 +00001111
1112 // This delays passing the stopped event to listeners till DidLaunch gets
1113 // a chance to complete...
1114 HandlePrivateEvent(event_sp);
1115 StartPrivateStateThread();
1116 }
1117 else
1118 {
1119 // We exited while trying to launch somehow. Don't call DidLaunch as that's
1120 // not likely to work, and return an invalid pid.
1121 if (state == eStateExited)
1122 HandlePrivateEvent (event_sp);
1123 error.SetErrorStringWithFormat("invalid state after attach: %s",
1124 lldb_private::StateAsCString(state));
1125 }
1126 return error;
1127}
1128
1129Error
1130Process::Attach (lldb::pid_t attach_pid)
1131{
1132
1133 m_target_triple.Clear();
1134 m_abi_sp.reset();
1135
Jim Ingham7508e732010-08-09 23:31:02 +00001136 // Find the process and its architecture. Make sure it matches the architecture
1137 // of the current Target, and if not adjust it.
1138
1139 ArchSpec attach_spec = GetArchSpecForExistingProcess (attach_pid);
1140 if (attach_spec != GetTarget().GetArchitecture())
1141 {
1142 // Set the architecture on the target.
1143 GetTarget().SetArchitecture(attach_spec);
1144 }
1145
Greg Clayton54e7afa2010-07-09 20:39:50 +00001146 Error error (WillAttachToProcessWithID(attach_pid));
Chris Lattner24943d22010-06-08 16:52:24 +00001147 if (error.Success())
1148 {
Greg Clayton54e7afa2010-07-09 20:39:50 +00001149 error = DoAttachToProcessWithID (attach_pid);
Chris Lattner24943d22010-06-08 16:52:24 +00001150 if (error.Success())
1151 {
1152 error = CompleteAttach();
1153 }
1154 else
1155 {
1156 if (GetID() != LLDB_INVALID_PROCESS_ID)
1157 {
1158 SetID (LLDB_INVALID_PROCESS_ID);
1159 const char *error_string = error.AsCString();
1160 if (error_string == NULL)
1161 error_string = "attach failed";
1162
1163 SetExitStatus(-1, error_string);
1164 }
1165 }
1166 }
1167 return error;
1168}
1169
1170Error
1171Process::Attach (const char *process_name, bool wait_for_launch)
1172{
1173 m_target_triple.Clear();
1174 m_abi_sp.reset();
Jim Ingham7508e732010-08-09 23:31:02 +00001175
1176 // Find the process and its architecture. Make sure it matches the architecture
1177 // of the current Target, and if not adjust it.
1178
Jim Inghamea294182010-08-17 21:54:19 +00001179 if (!wait_for_launch)
Jim Ingham7508e732010-08-09 23:31:02 +00001180 {
Jim Inghamea294182010-08-17 21:54:19 +00001181 ArchSpec attach_spec = GetArchSpecForExistingProcess (process_name);
1182 if (attach_spec != GetTarget().GetArchitecture())
1183 {
1184 // Set the architecture on the target.
1185 GetTarget().SetArchitecture(attach_spec);
1186 }
Jim Ingham7508e732010-08-09 23:31:02 +00001187 }
Jim Inghamea294182010-08-17 21:54:19 +00001188
Greg Clayton54e7afa2010-07-09 20:39:50 +00001189 Error error (WillAttachToProcessWithName(process_name, wait_for_launch));
Chris Lattner24943d22010-06-08 16:52:24 +00001190 if (error.Success())
1191 {
1192 StartPrivateStateThread();
Greg Clayton54e7afa2010-07-09 20:39:50 +00001193 error = DoAttachToProcessWithName (process_name, wait_for_launch);
Chris Lattner24943d22010-06-08 16:52:24 +00001194 if (error.Fail())
1195 {
1196 if (GetID() != LLDB_INVALID_PROCESS_ID)
1197 {
1198 SetID (LLDB_INVALID_PROCESS_ID);
1199 const char *error_string = error.AsCString();
1200 if (error_string == NULL)
1201 error_string = "attach failed";
1202
1203 SetExitStatus(-1, error_string);
1204 }
1205 }
1206 else
1207 {
1208 error = CompleteAttach();
1209 }
1210 }
1211 return error;
1212}
1213
1214Error
1215Process::Resume ()
1216{
1217 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
1218 if (log)
1219 log->Printf("Process::Resume() m_stop_id = %u", m_stop_id);
1220
1221 Error error (WillResume());
1222 // Tell the process it is about to resume before the thread list
1223 if (error.Success())
1224 {
1225 // Now let the thread list know we are about to resume to it
1226 // can let all of our threads know that they are about to be
1227 // resumed. Threads will each be called with
1228 // Thread::WillResume(StateType) where StateType contains the state
1229 // that they are supposed to have when the process is resumed
1230 // (suspended/running/stepping). Threads should also check
1231 // their resume signal in lldb::Thread::GetResumeSignal()
1232 // to see if they are suppoed to start back up with a signal.
1233 if (m_thread_list.WillResume())
1234 {
1235 error = DoResume();
1236 if (error.Success())
1237 {
1238 DidResume();
1239 m_thread_list.DidResume();
1240 }
1241 }
1242 else
1243 {
1244 error.SetErrorStringWithFormat("thread list returned flase after WillResume");
1245 }
1246 }
1247 return error;
1248}
1249
1250Error
1251Process::Halt ()
1252{
1253 Error error (WillHalt());
1254
1255 if (error.Success())
1256 {
1257 error = DoHalt();
1258 if (error.Success())
1259 DidHalt();
1260 }
1261 return error;
1262}
1263
1264Error
1265Process::Detach ()
1266{
1267 Error error (WillDetach());
1268
1269 if (error.Success())
1270 {
1271 DisableAllBreakpointSites();
1272 error = DoDetach();
1273 if (error.Success())
1274 {
1275 DidDetach();
1276 StopPrivateStateThread();
1277 }
1278 }
1279 return error;
1280}
1281
1282Error
1283Process::Destroy ()
1284{
1285 Error error (WillDestroy());
1286 if (error.Success())
1287 {
1288 DisableAllBreakpointSites();
1289 error = DoDestroy();
1290 if (error.Success())
1291 {
1292 DidDestroy();
1293 StopPrivateStateThread();
1294 }
1295 }
1296 return error;
1297}
1298
1299Error
1300Process::Signal (int signal)
1301{
1302 Error error (WillSignal());
1303 if (error.Success())
1304 {
1305 error = DoSignal(signal);
1306 if (error.Success())
1307 DidSignal();
1308 }
1309 return error;
1310}
1311
1312UnixSignals &
1313Process::GetUnixSignals ()
1314{
1315 return m_unix_signals;
1316}
1317
1318Target &
1319Process::GetTarget ()
1320{
1321 return m_target;
1322}
1323
1324const Target &
1325Process::GetTarget () const
1326{
1327 return m_target;
1328}
1329
1330uint32_t
1331Process::GetAddressByteSize()
1332{
1333 return m_target.GetArchitecture().GetAddressByteSize();
1334}
1335
1336bool
1337Process::ShouldBroadcastEvent (Event *event_ptr)
1338{
1339 const StateType state = Process::ProcessEventData::GetStateFromEvent (event_ptr);
1340 bool return_value = true;
1341 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS);
1342
1343 switch (state)
1344 {
1345 case eStateAttaching:
1346 case eStateLaunching:
1347 case eStateDetached:
1348 case eStateExited:
1349 case eStateUnloaded:
1350 // These events indicate changes in the state of the debugging session, always report them.
1351 return_value = true;
1352 break;
1353 case eStateInvalid:
1354 // We stopped for no apparent reason, don't report it.
1355 return_value = false;
1356 break;
1357 case eStateRunning:
1358 case eStateStepping:
1359 // If we've started the target running, we handle the cases where we
1360 // are already running and where there is a transition from stopped to
1361 // running differently.
1362 // running -> running: Automatically suppress extra running events
1363 // stopped -> running: Report except when there is one or more no votes
1364 // and no yes votes.
1365 SynchronouslyNotifyStateChanged (state);
1366 switch (m_public_state.GetValue())
1367 {
1368 case eStateRunning:
1369 case eStateStepping:
1370 // We always suppress multiple runnings with no PUBLIC stop in between.
1371 return_value = false;
1372 break;
1373 default:
1374 // TODO: make this work correctly. For now always report
1375 // run if we aren't running so we don't miss any runnning
1376 // events. If I run the lldb/test/thread/a.out file and
1377 // break at main.cpp:58, run and hit the breakpoints on
1378 // multiple threads, then somehow during the stepping over
1379 // of all breakpoints no run gets reported.
1380 return_value = true;
1381
1382 // This is a transition from stop to run.
1383 switch (m_thread_list.ShouldReportRun (event_ptr))
1384 {
1385 case eVoteYes:
1386 case eVoteNoOpinion:
1387 return_value = true;
1388 break;
1389 case eVoteNo:
1390 return_value = false;
1391 break;
1392 }
1393 break;
1394 }
1395 break;
1396 case eStateStopped:
1397 case eStateCrashed:
1398 case eStateSuspended:
1399 {
1400 // We've stopped. First see if we're going to restart the target.
1401 // If we are going to stop, then we always broadcast the event.
1402 // If we aren't going to stop, let the thread plans decide if we're going to report this event.
Jim Ingham5a47e8b2010-06-19 04:45:32 +00001403 // If no thread has an opinion, we don't report it.
Chris Lattner24943d22010-06-08 16:52:24 +00001404 if (state != eStateInvalid)
1405 {
1406
1407 RefreshStateAfterStop ();
1408
1409 if (m_thread_list.ShouldStop (event_ptr) == false)
1410 {
1411 switch (m_thread_list.ShouldReportStop (event_ptr))
1412 {
1413 case eVoteYes:
1414 Process::ProcessEventData::SetRestartedInEvent (event_ptr, true);
1415 case eVoteNoOpinion:
Chris Lattner24943d22010-06-08 16:52:24 +00001416 case eVoteNo:
1417 return_value = false;
1418 break;
1419 }
1420
1421 if (log)
1422 log->Printf ("Process::ShouldBroadcastEvent (%p) Restarting process", event_ptr, StateAsCString(state));
1423 Resume ();
1424 }
1425 else
1426 {
1427 return_value = true;
1428 SynchronouslyNotifyStateChanged (state);
1429 }
1430 }
1431 }
1432 }
1433
1434 if (log)
1435 log->Printf ("Process::ShouldBroadcastEvent (%p) => %s", event_ptr, StateAsCString(state), return_value ? "YES" : "NO");
1436 return return_value;
1437}
1438
1439//------------------------------------------------------------------
1440// Thread Queries
1441//------------------------------------------------------------------
1442
1443ThreadList &
1444Process::GetThreadList ()
1445{
1446 return m_thread_list;
1447}
1448
1449const ThreadList &
1450Process::GetThreadList () const
1451{
1452 return m_thread_list;
1453}
1454
1455
1456bool
1457Process::StartPrivateStateThread ()
1458{
1459 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS);
1460
1461 if (log)
1462 log->Printf ("Process::%s ( )", __FUNCTION__);
1463
1464 // Create a thread that watches our internal state and controls which
1465 // events make it to clients (into the DCProcess event queue).
1466 m_private_state_thread = Host::ThreadCreate ("<lldb.process.internal-state>", Process::PrivateStateThread, this, NULL);
1467 return m_private_state_thread != LLDB_INVALID_HOST_THREAD;
1468}
1469
1470void
1471Process::PausePrivateStateThread ()
1472{
1473 ControlPrivateStateThread (eBroadcastInternalStateControlPause);
1474}
1475
1476void
1477Process::ResumePrivateStateThread ()
1478{
1479 ControlPrivateStateThread (eBroadcastInternalStateControlResume);
1480}
1481
1482void
1483Process::StopPrivateStateThread ()
1484{
1485 ControlPrivateStateThread (eBroadcastInternalStateControlStop);
1486}
1487
1488void
1489Process::ControlPrivateStateThread (uint32_t signal)
1490{
1491 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS);
1492
1493 assert (signal == eBroadcastInternalStateControlStop ||
1494 signal == eBroadcastInternalStateControlPause ||
1495 signal == eBroadcastInternalStateControlResume);
1496
1497 if (log)
1498 log->Printf ("Process::%s ( ) - signal: %d", __FUNCTION__, signal);
1499
1500 // Signal the private state thread
1501 if (m_private_state_thread != LLDB_INVALID_HOST_THREAD)
1502 {
1503 TimeValue timeout_time;
1504 bool timed_out;
1505
1506 m_private_state_control_broadcaster.BroadcastEvent (signal, NULL);
1507
1508 timeout_time = TimeValue::Now();
1509 timeout_time.OffsetWithSeconds(2);
1510 m_private_state_control_wait.WaitForValueEqualTo (true, &timeout_time, &timed_out);
1511 m_private_state_control_wait.SetValue (false, eBroadcastNever);
1512
1513 if (signal == eBroadcastInternalStateControlStop)
1514 {
1515 if (timed_out)
1516 Host::ThreadCancel (m_private_state_thread, NULL);
1517
1518 thread_result_t result = NULL;
1519 Host::ThreadJoin (m_private_state_thread, &result, NULL);
Greg Claytonc607d862010-07-22 18:34:21 +00001520 m_private_state_thread = LLDB_INVALID_HOST_THREAD;
Chris Lattner24943d22010-06-08 16:52:24 +00001521 }
1522 }
1523}
1524
1525void
1526Process::HandlePrivateEvent (EventSP &event_sp)
1527{
1528 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
1529 const StateType internal_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
1530 // See if we should broadcast this state to external clients?
1531 const bool should_broadcast = ShouldBroadcastEvent (event_sp.get());
1532 if (log)
1533 log->Printf ("Process::%s (arg = %p, pid = %i) got event '%s' broadcast = %s", __FUNCTION__, this, GetID(), StateAsCString(internal_state), should_broadcast ? "yes" : "no");
1534
1535 if (should_broadcast)
1536 {
1537 if (log)
1538 {
1539 log->Printf ("\tChanging public state from: %s to %s", StateAsCString(GetState ()), StateAsCString (internal_state));
1540 }
1541 Process::ProcessEventData::SetUpdateStateOnRemoval(event_sp.get());
1542 BroadcastEvent (event_sp);
1543 }
1544 else
1545 {
1546 if (log)
1547 {
1548 log->Printf ("\tNot changing public state with event: %s", StateAsCString (internal_state));
1549 }
1550 }
1551}
1552
1553void *
1554Process::PrivateStateThread (void *arg)
1555{
1556 Process *proc = static_cast<Process*> (arg);
1557 void *result = proc->RunPrivateStateThread ();
Chris Lattner24943d22010-06-08 16:52:24 +00001558 return result;
1559}
1560
1561void *
1562Process::RunPrivateStateThread ()
1563{
1564 bool control_only = false;
1565 m_private_state_control_wait.SetValue (false, eBroadcastNever);
1566
1567 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
1568 if (log)
1569 log->Printf ("Process::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, this, GetID());
1570
1571 bool exit_now = false;
1572 while (!exit_now)
1573 {
1574 EventSP event_sp;
1575 WaitForEventsPrivate (NULL, event_sp, control_only);
1576 if (event_sp->BroadcasterIs(&m_private_state_control_broadcaster))
1577 {
1578 switch (event_sp->GetType())
1579 {
1580 case eBroadcastInternalStateControlStop:
1581 exit_now = true;
1582 continue; // Go to next loop iteration so we exit without
1583 break; // doing any internal state managment below
1584
1585 case eBroadcastInternalStateControlPause:
1586 control_only = true;
1587 break;
1588
1589 case eBroadcastInternalStateControlResume:
1590 control_only = false;
1591 break;
1592 }
1593 m_private_state_control_wait.SetValue (true, eBroadcastAlways);
1594 }
1595
1596
1597 const StateType internal_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
1598
1599 if (internal_state != eStateInvalid)
1600 {
1601 HandlePrivateEvent (event_sp);
1602 }
1603
1604 if (internal_state == eStateInvalid || internal_state == eStateExited)
1605 break;
1606 }
1607
1608 if (log)
1609 log->Printf ("Process::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, this, GetID());
1610
Greg Clayton8b4c16e2010-08-19 21:50:06 +00001611 m_private_state_thread = LLDB_INVALID_HOST_THREAD;
Chris Lattner24943d22010-06-08 16:52:24 +00001612 return NULL;
1613}
1614
Chris Lattner24943d22010-06-08 16:52:24 +00001615//------------------------------------------------------------------
1616// Process Event Data
1617//------------------------------------------------------------------
1618
1619Process::ProcessEventData::ProcessEventData () :
1620 EventData (),
1621 m_process_sp (),
1622 m_state (eStateInvalid),
Greg Clayton54e7afa2010-07-09 20:39:50 +00001623 m_restarted (false),
1624 m_update_state (false)
Chris Lattner24943d22010-06-08 16:52:24 +00001625{
1626}
1627
1628Process::ProcessEventData::ProcessEventData (const ProcessSP &process_sp, StateType state) :
1629 EventData (),
1630 m_process_sp (process_sp),
1631 m_state (state),
Greg Clayton54e7afa2010-07-09 20:39:50 +00001632 m_restarted (false),
1633 m_update_state (false)
Chris Lattner24943d22010-06-08 16:52:24 +00001634{
1635}
1636
1637Process::ProcessEventData::~ProcessEventData()
1638{
1639}
1640
1641const ConstString &
1642Process::ProcessEventData::GetFlavorString ()
1643{
1644 static ConstString g_flavor ("Process::ProcessEventData");
1645 return g_flavor;
1646}
1647
1648const ConstString &
1649Process::ProcessEventData::GetFlavor () const
1650{
1651 return ProcessEventData::GetFlavorString ();
1652}
1653
1654const ProcessSP &
1655Process::ProcessEventData::GetProcessSP () const
1656{
1657 return m_process_sp;
1658}
1659
1660StateType
1661Process::ProcessEventData::GetState () const
1662{
1663 return m_state;
1664}
1665
1666bool
1667Process::ProcessEventData::GetRestarted () const
1668{
1669 return m_restarted;
1670}
1671
1672void
1673Process::ProcessEventData::SetRestarted (bool new_value)
1674{
1675 m_restarted = new_value;
1676}
1677
1678void
1679Process::ProcessEventData::DoOnRemoval (Event *event_ptr)
1680{
1681 // This function gets called twice for each event, once when the event gets pulled
1682 // off of the private process event queue, and once when it gets pulled off of
1683 // the public event queue. m_update_state is used to distinguish these
1684 // two cases; it is false when we're just pulling it off for private handling,
1685 // and we don't want to do the breakpoint command handling then.
1686
1687 if (!m_update_state)
1688 return;
1689
1690 m_process_sp->SetPublicState (m_state);
1691
1692 // If we're stopped and haven't restarted, then do the breakpoint commands here:
1693 if (m_state == eStateStopped && ! m_restarted)
1694 {
1695 int num_threads = m_process_sp->GetThreadList().GetSize();
1696 int idx;
Greg Clayton643ee732010-08-04 01:40:35 +00001697
Chris Lattner24943d22010-06-08 16:52:24 +00001698 for (idx = 0; idx < num_threads; ++idx)
1699 {
1700 lldb::ThreadSP thread_sp = m_process_sp->GetThreadList().GetThreadAtIndex(idx);
1701
Greg Clayton643ee732010-08-04 01:40:35 +00001702 StopInfo *stop_info = thread_sp->GetStopInfo ();
1703 if (stop_info)
Chris Lattner24943d22010-06-08 16:52:24 +00001704 {
Jim Ingham6fb8baa2010-08-10 00:59:59 +00001705 stop_info->PerformAction(event_ptr);
Chris Lattner24943d22010-06-08 16:52:24 +00001706 }
1707 }
Greg Clayton643ee732010-08-04 01:40:35 +00001708
Jim Ingham6fb8baa2010-08-10 00:59:59 +00001709 // The stop action might restart the target. If it does, then we want to mark that in the
1710 // event so that whoever is receiving it will know to wait for the running event and reflect
1711 // that state appropriately.
1712
Chris Lattner24943d22010-06-08 16:52:24 +00001713 if (m_process_sp->GetPrivateState() == eStateRunning)
1714 SetRestarted(true);
1715 }
1716}
1717
1718void
1719Process::ProcessEventData::Dump (Stream *s) const
1720{
1721 if (m_process_sp)
1722 s->Printf(" process = %p (pid = %u), ", m_process_sp.get(), m_process_sp->GetID());
1723
1724 s->Printf("state = %s", StateAsCString(GetState()));;
1725}
1726
1727const Process::ProcessEventData *
1728Process::ProcessEventData::GetEventDataFromEvent (const Event *event_ptr)
1729{
1730 if (event_ptr)
1731 {
1732 const EventData *event_data = event_ptr->GetData();
1733 if (event_data && event_data->GetFlavor() == ProcessEventData::GetFlavorString())
1734 return static_cast <const ProcessEventData *> (event_ptr->GetData());
1735 }
1736 return NULL;
1737}
1738
1739ProcessSP
1740Process::ProcessEventData::GetProcessFromEvent (const Event *event_ptr)
1741{
1742 ProcessSP process_sp;
1743 const ProcessEventData *data = GetEventDataFromEvent (event_ptr);
1744 if (data)
1745 process_sp = data->GetProcessSP();
1746 return process_sp;
1747}
1748
1749StateType
1750Process::ProcessEventData::GetStateFromEvent (const Event *event_ptr)
1751{
1752 const ProcessEventData *data = GetEventDataFromEvent (event_ptr);
1753 if (data == NULL)
1754 return eStateInvalid;
1755 else
1756 return data->GetState();
1757}
1758
1759bool
1760Process::ProcessEventData::GetRestartedFromEvent (const Event *event_ptr)
1761{
1762 const ProcessEventData *data = GetEventDataFromEvent (event_ptr);
1763 if (data == NULL)
1764 return false;
1765 else
1766 return data->GetRestarted();
1767}
1768
1769void
1770Process::ProcessEventData::SetRestartedInEvent (Event *event_ptr, bool new_value)
1771{
1772 ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
1773 if (data != NULL)
1774 data->SetRestarted(new_value);
1775}
1776
1777bool
1778Process::ProcessEventData::SetUpdateStateOnRemoval (Event *event_ptr)
1779{
1780 ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
1781 if (data)
1782 {
1783 data->SetUpdateStateOnRemoval();
1784 return true;
1785 }
1786 return false;
1787}
1788
1789void
1790Process::ProcessEventData::SetUpdateStateOnRemoval()
1791{
1792 m_update_state = true;
1793}
1794
1795Target *
1796Process::CalculateTarget ()
1797{
1798 return &m_target;
1799}
1800
1801Process *
1802Process::CalculateProcess ()
1803{
1804 return this;
1805}
1806
1807Thread *
1808Process::CalculateThread ()
1809{
1810 return NULL;
1811}
1812
1813StackFrame *
1814Process::CalculateStackFrame ()
1815{
1816 return NULL;
1817}
1818
1819void
1820Process::Calculate (ExecutionContext &exe_ctx)
1821{
1822 exe_ctx.target = &m_target;
1823 exe_ctx.process = this;
1824 exe_ctx.thread = NULL;
1825 exe_ctx.frame = NULL;
1826}
1827
1828lldb::ProcessSP
1829Process::GetSP ()
1830{
1831 return GetTarget().GetProcessSP();
1832}
1833
Sean Callanana48fe162010-08-11 03:57:18 +00001834ClangPersistentVariables &
1835Process::GetPersistentVariables()
1836{
1837 return m_persistent_vars;
1838}
1839
Chris Lattner24943d22010-06-08 16:52:24 +00001840ObjCObjectPrinter &
1841Process::GetObjCObjectPrinter()
1842{
1843 return m_objc_object_printer;
1844}
1845
Jim Ingham7508e732010-08-09 23:31:02 +00001846uint32_t
1847Process::ListProcessesMatchingName (const char *name, StringList &matches, std::vector<lldb::pid_t> &pids)
1848{
1849 return 0;
1850}
1851
1852ArchSpec
1853Process::GetArchSpecForExistingProcess (lldb::pid_t pid)
1854{
1855 return Host::GetArchSpecForExistingProcess (pid);
1856}
1857
1858ArchSpec
1859Process::GetArchSpecForExistingProcess (const char *process_name)
1860{
1861 return Host::GetArchSpecForExistingProcess (process_name);
1862}
1863
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00001864lldb::UserSettingsControllerSP
1865Process::GetSettingsController (bool finish)
1866{
Greg Claytond0a5a232010-09-19 02:33:57 +00001867 static UserSettingsControllerSP g_settings_controller (new SettingsController);
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00001868 static bool initialized = false;
1869
1870 if (!initialized)
1871 {
Jim Ingham7ac83bd2010-09-07 20:27:09 +00001872 initialized = UserSettingsController::InitializeSettingsController (g_settings_controller,
Greg Claytond0a5a232010-09-19 02:33:57 +00001873 Process::SettingsController::global_settings_table,
1874 Process::SettingsController::instance_settings_table);
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00001875 }
1876
1877 if (finish)
1878 {
Jim Ingham7ac83bd2010-09-07 20:27:09 +00001879 UserSettingsController::FinalizeSettingsController (g_settings_controller);
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00001880 g_settings_controller.reset();
Jim Ingham7ac83bd2010-09-07 20:27:09 +00001881 initialized = false;
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00001882 }
1883
1884 return g_settings_controller;
1885}
1886
1887//--------------------------------------------------------------
Greg Claytond0a5a232010-09-19 02:33:57 +00001888// class Process::SettingsController
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00001889//--------------------------------------------------------------
1890
Greg Claytond0a5a232010-09-19 02:33:57 +00001891Process::SettingsController::SettingsController () :
Caroline Tice5bc8c972010-09-20 20:44:43 +00001892 UserSettingsController ("process", Target::GetSettingsController())
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00001893{
Caroline Tice004afcb2010-09-08 17:48:55 +00001894 m_default_settings.reset (new ProcessInstanceSettings (*this, false,
1895 InstanceSettings::GetDefaultName().AsCString()));
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00001896}
1897
Greg Claytond0a5a232010-09-19 02:33:57 +00001898Process::SettingsController::~SettingsController ()
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00001899{
1900}
1901
1902lldb::InstanceSettingsSP
Greg Claytond0a5a232010-09-19 02:33:57 +00001903Process::SettingsController::CreateInstanceSettings (const char *instance_name)
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00001904{
Caroline Tice004afcb2010-09-08 17:48:55 +00001905 ProcessInstanceSettings *new_settings = new ProcessInstanceSettings (*(Process::GetSettingsController().get()),
1906 false, instance_name);
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00001907 lldb::InstanceSettingsSP new_settings_sp (new_settings);
1908 return new_settings_sp;
1909}
1910
1911//--------------------------------------------------------------
1912// class ProcessInstanceSettings
1913//--------------------------------------------------------------
1914
Caroline Tice004afcb2010-09-08 17:48:55 +00001915ProcessInstanceSettings::ProcessInstanceSettings (UserSettingsController &owner, bool live_instance,
1916 const char *name) :
Caroline Tice75b11a32010-09-16 19:05:55 +00001917 InstanceSettings (owner, (name == NULL ? InstanceSettings::InvalidName().AsCString() : name), live_instance),
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00001918 m_run_args (),
1919 m_env_vars (),
1920 m_input_path (),
1921 m_output_path (),
1922 m_error_path (),
1923 m_plugin (),
1924 m_disable_aslr (true)
1925{
Caroline Tice396704b2010-09-09 18:26:37 +00001926 // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called
1927 // until the vtables for ProcessInstanceSettings are properly set up, i.e. AFTER all the initializers.
1928 // For this reason it has to be called here, rather than in the initializer or in the parent constructor.
Caroline Tice75b11a32010-09-16 19:05:55 +00001929 // This is true for CreateInstanceName() too.
1930
1931 if (GetInstanceName () == InstanceSettings::InvalidName())
1932 {
1933 ChangeInstanceName (std::string (CreateInstanceName().AsCString()));
1934 m_owner.RegisterInstanceSettings (this);
1935 }
Caroline Tice396704b2010-09-09 18:26:37 +00001936
1937 if (live_instance)
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00001938 {
1939 const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name);
1940 CopyInstanceSettings (pending_settings,false);
Caroline Tice396704b2010-09-09 18:26:37 +00001941 //m_owner.RemovePendingSettings (m_instance_name);
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00001942 }
1943}
1944
1945ProcessInstanceSettings::ProcessInstanceSettings (const ProcessInstanceSettings &rhs) :
1946 InstanceSettings (*(Process::GetSettingsController().get()), CreateInstanceName().AsCString()),
1947 m_run_args (rhs.m_run_args),
1948 m_env_vars (rhs.m_env_vars),
1949 m_input_path (rhs.m_input_path),
1950 m_output_path (rhs.m_output_path),
1951 m_error_path (rhs.m_error_path),
1952 m_plugin (rhs.m_plugin),
1953 m_disable_aslr (rhs.m_disable_aslr)
1954{
1955 if (m_instance_name != InstanceSettings::GetDefaultName())
1956 {
1957 const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name);
1958 CopyInstanceSettings (pending_settings,false);
1959 m_owner.RemovePendingSettings (m_instance_name);
1960 }
1961}
1962
1963ProcessInstanceSettings::~ProcessInstanceSettings ()
1964{
1965}
1966
1967ProcessInstanceSettings&
1968ProcessInstanceSettings::operator= (const ProcessInstanceSettings &rhs)
1969{
1970 if (this != &rhs)
1971 {
1972 m_run_args = rhs.m_run_args;
1973 m_env_vars = rhs.m_env_vars;
1974 m_input_path = rhs.m_input_path;
1975 m_output_path = rhs.m_output_path;
1976 m_error_path = rhs.m_error_path;
1977 m_plugin = rhs.m_plugin;
1978 m_disable_aslr = rhs.m_disable_aslr;
1979 }
1980
1981 return *this;
1982}
1983
1984
1985void
1986ProcessInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name,
1987 const char *index_value,
1988 const char *value,
1989 const ConstString &instance_name,
1990 const SettingEntry &entry,
1991 lldb::VarSetOperationType op,
1992 Error &err,
1993 bool pending)
1994{
1995 if (var_name == RunArgsVarName())
1996 UserSettingsController::UpdateStringArrayVariable (op, index_value, m_run_args, value, err);
1997 else if (var_name == EnvVarsVarName())
1998 UserSettingsController::UpdateDictionaryVariable (op, index_value, m_env_vars, value, err);
1999 else if (var_name == InputPathVarName())
2000 UserSettingsController::UpdateStringVariable (op, m_input_path, value, err);
2001 else if (var_name == OutputPathVarName())
2002 UserSettingsController::UpdateStringVariable (op, m_output_path, value, err);
2003 else if (var_name == ErrorPathVarName())
2004 UserSettingsController::UpdateStringVariable (op, m_error_path, value, err);
2005 else if (var_name == PluginVarName())
2006 UserSettingsController::UpdateEnumVariable (entry.enum_values, (int *) &m_plugin, value, err);
2007 else if (var_name == DisableASLRVarName())
2008 UserSettingsController::UpdateBooleanVariable (op, m_disable_aslr, value, err);
2009}
2010
2011void
2012ProcessInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings,
2013 bool pending)
2014{
2015 if (new_settings.get() == NULL)
2016 return;
2017
2018 ProcessInstanceSettings *new_process_settings = (ProcessInstanceSettings *) new_settings.get();
2019
2020 m_run_args = new_process_settings->m_run_args;
2021 m_env_vars = new_process_settings->m_env_vars;
2022 m_input_path = new_process_settings->m_input_path;
2023 m_output_path = new_process_settings->m_output_path;
2024 m_error_path = new_process_settings->m_error_path;
2025 m_plugin = new_process_settings->m_plugin;
2026 m_disable_aslr = new_process_settings->m_disable_aslr;
2027}
2028
Caroline Ticebcb5b452010-09-20 21:37:42 +00002029bool
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00002030ProcessInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry,
2031 const ConstString &var_name,
Caroline Tice5bc8c972010-09-20 20:44:43 +00002032 StringList &value,
Caroline Ticebcb5b452010-09-20 21:37:42 +00002033 Error *err)
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00002034{
2035 if (var_name == RunArgsVarName())
2036 {
2037 if (m_run_args.GetArgumentCount() > 0)
Greg Claytonc14069e2010-09-14 03:47:41 +00002038 {
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00002039 for (int i = 0; i < m_run_args.GetArgumentCount(); ++i)
2040 value.AppendString (m_run_args.GetArgumentAtIndex (i));
Greg Claytonc14069e2010-09-14 03:47:41 +00002041 }
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00002042 }
2043 else if (var_name == EnvVarsVarName())
2044 {
2045 if (m_env_vars.size() > 0)
2046 {
2047 std::map<std::string, std::string>::iterator pos;
2048 for (pos = m_env_vars.begin(); pos != m_env_vars.end(); ++pos)
2049 {
2050 StreamString value_str;
2051 value_str.Printf ("%s=%s", pos->first.c_str(), pos->second.c_str());
2052 value.AppendString (value_str.GetData());
2053 }
2054 }
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00002055 }
2056 else if (var_name == InputPathVarName())
2057 {
2058 value.AppendString (m_input_path.c_str());
2059 }
2060 else if (var_name == OutputPathVarName())
2061 {
2062 value.AppendString (m_output_path.c_str());
2063 }
2064 else if (var_name == ErrorPathVarName())
2065 {
2066 value.AppendString (m_error_path.c_str());
2067 }
2068 else if (var_name == PluginVarName())
2069 {
2070 value.AppendString (UserSettingsController::EnumToString (entry.enum_values, (int) m_plugin));
2071 }
2072 else if (var_name == DisableASLRVarName())
2073 {
2074 if (m_disable_aslr)
2075 value.AppendString ("true");
2076 else
2077 value.AppendString ("false");
2078 }
2079 else
Caroline Ticebcb5b452010-09-20 21:37:42 +00002080 {
2081 if (err)
2082 err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString());
2083 return false;
2084 }
2085 return true;
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00002086}
2087
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00002088const ConstString
2089ProcessInstanceSettings::CreateInstanceName ()
2090{
2091 static int instance_count = 1;
2092 StreamString sstr;
2093
2094 sstr.Printf ("process_%d", instance_count);
2095 ++instance_count;
2096
2097 const ConstString ret_val (sstr.GetData());
2098 return ret_val;
2099}
2100
2101const ConstString &
2102ProcessInstanceSettings::RunArgsVarName ()
2103{
2104 static ConstString run_args_var_name ("run-args");
2105
2106 return run_args_var_name;
2107}
2108
2109const ConstString &
2110ProcessInstanceSettings::EnvVarsVarName ()
2111{
2112 static ConstString env_vars_var_name ("env-vars");
2113
2114 return env_vars_var_name;
2115}
2116
2117const ConstString &
2118ProcessInstanceSettings::InputPathVarName ()
2119{
2120 static ConstString input_path_var_name ("input-path");
2121
2122 return input_path_var_name;
2123}
2124
2125const ConstString &
2126ProcessInstanceSettings::OutputPathVarName ()
2127{
Caroline Tice87097232010-09-07 18:35:40 +00002128 static ConstString output_path_var_name ("output-path");
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00002129
2130 return output_path_var_name;
2131}
2132
2133const ConstString &
2134ProcessInstanceSettings::ErrorPathVarName ()
2135{
Caroline Tice87097232010-09-07 18:35:40 +00002136 static ConstString error_path_var_name ("error-path");
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00002137
2138 return error_path_var_name;
2139}
2140
2141const ConstString &
2142ProcessInstanceSettings::PluginVarName ()
2143{
2144 static ConstString plugin_var_name ("plugin");
2145
2146 return plugin_var_name;
2147}
2148
2149
2150const ConstString &
2151ProcessInstanceSettings::DisableASLRVarName ()
2152{
2153 static ConstString disable_aslr_var_name ("disable-aslr");
2154
2155 return disable_aslr_var_name;
2156}
2157
2158
2159//--------------------------------------------------
Greg Claytond0a5a232010-09-19 02:33:57 +00002160// SettingsController Variable Tables
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00002161//--------------------------------------------------
2162
2163SettingEntry
Greg Claytond0a5a232010-09-19 02:33:57 +00002164Process::SettingsController::global_settings_table[] =
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00002165{
2166 //{ "var-name", var-type , "default", enum-table, init'd, hidden, "help-text"},
2167 { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL }
2168};
2169
2170
2171lldb::OptionEnumValueElement
Greg Claytond0a5a232010-09-19 02:33:57 +00002172Process::SettingsController::g_plugins[] =
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00002173{
Caroline Ticef2c330d2010-09-09 18:01:59 +00002174 { eMacosx, "process.macosx", "Use the native MacOSX debugger plugin" },
2175 { eRemoteDebugger, "process.gdb-remote" , "Use the GDB Remote protocol based debugger plugin" },
2176 { 0, NULL, NULL }
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00002177};
2178
2179SettingEntry
Greg Claytond0a5a232010-09-19 02:33:57 +00002180Process::SettingsController::instance_settings_table[] =
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00002181{
2182 //{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"},
2183 { "run-args", eSetVarTypeArray, NULL, NULL, false, false, "A list containing all the arguments to be passed to the executable when it is run." },
2184 { "env-vars", eSetVarTypeDictionary, NULL, NULL, false, false, "A list of all the environment variables to be passed to the executable's environment, and their values." },
2185 { "input-path", eSetVarTypeString, "/dev/stdin", NULL, false, false, "The file/path to be used by the executable program for reading its input." },
2186 { "output-path", eSetVarTypeString, "/dev/stdout", NULL, false, false, "The file/path to be used by the executable program for writing its output." },
2187 { "error-path", eSetVarTypeString, "/dev/stderr", NULL, false, false, "The file/path to be used by the executable program for writings its error messages." },
2188 { "plugin", eSetVarTypeEnum, NULL , g_plugins, false, false, "The plugin to be used to run the process." },
2189 { "disable-aslr", eSetVarTypeBool, "true", NULL, false, false, "Disable Address Space Layout Randomization (ASLR)" },
2190 { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL }
2191};
2192
2193
Jim Ingham7508e732010-08-09 23:31:02 +00002194