blob: 7af39038c9b8cbf5257a35848a738b77e1ea8d92 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- SBDebugger.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
Eli Friedmand6ec8aa2010-06-09 07:37:52 +000010#include "lldb/API/SBDebugger.h"
Chris Lattner24943d22010-06-08 16:52:24 +000011
12#include "lldb/lldb-include.h"
Jim Ingham84cdc152010-06-15 19:49:27 +000013#include "lldb/Interpreter/Args.h"
Chris Lattner24943d22010-06-08 16:52:24 +000014#include "lldb/Core/Debugger.h"
15#include "lldb/Core/State.h"
16#include "lldb/Target/Process.h"
17#include "lldb/Target/TargetList.h"
18
Eli Friedmand6ec8aa2010-06-09 07:37:52 +000019#include "lldb/API/SBListener.h"
20#include "lldb/API/SBBroadcaster.h"
21#include "lldb/API/SBCommandInterpreter.h"
22#include "lldb/API/SBCommandReturnObject.h"
23#include "lldb/API/SBEvent.h"
24#include "lldb/API/SBFrame.h"
Eli Friedmand6ec8aa2010-06-09 07:37:52 +000025#include "lldb/API/SBInputReader.h"
Caroline Tice6e4c5ce2010-09-04 00:03:46 +000026#include "lldb/API/SBProcess.h"
27#include "lldb/API/SBSourceManager.h"
28#include "lldb/API/SBStringList.h"
29#include "lldb/API/SBTarget.h"
30#include "lldb/API/SBThread.h"
Chris Lattner24943d22010-06-08 16:52:24 +000031
32using namespace lldb;
33using namespace lldb_private;
34
35void
36SBDebugger::Initialize ()
37{
38 Debugger::Initialize();
39}
40
41void
42SBDebugger::Terminate ()
43{
44 Debugger::Terminate();
45}
46
Greg Clayton43490d12010-07-30 20:12:55 +000047void
48SBDebugger::Clear ()
49{
50 m_opaque_sp.reset();
51}
52
Greg Clayton63094e02010-06-23 01:19:29 +000053SBDebugger
54SBDebugger::Create()
55{
56 SBDebugger debugger;
57 debugger.reset(Debugger::CreateInstance());
58 return debugger;
59}
60
Greg Clayton63094e02010-06-23 01:19:29 +000061SBDebugger::SBDebugger () :
62 m_opaque_sp ()
63{
64}
65
66SBDebugger::~SBDebugger ()
67{
68}
69
70bool
71SBDebugger::IsValid() const
72{
73 return m_opaque_sp.get() != NULL;
74}
75
76
Chris Lattner24943d22010-06-08 16:52:24 +000077void
78SBDebugger::SetAsync (bool b)
79{
Greg Clayton63094e02010-06-23 01:19:29 +000080 if (m_opaque_sp)
81 m_opaque_sp->SetAsyncExecution(b);
Chris Lattner24943d22010-06-08 16:52:24 +000082}
83
Chris Lattner24943d22010-06-08 16:52:24 +000084// Shouldn't really be settable after initialization as this could cause lots of problems; don't want users
85// trying to switch modes in the middle of a debugging session.
86void
87SBDebugger::SetInputFileHandle (FILE *fh, bool transfer_ownership)
88{
Greg Clayton63094e02010-06-23 01:19:29 +000089 if (m_opaque_sp)
90 m_opaque_sp->SetInputFileHandle (fh, transfer_ownership);
Chris Lattner24943d22010-06-08 16:52:24 +000091}
92
93void
94SBDebugger::SetOutputFileHandle (FILE *fh, bool transfer_ownership)
95{
Greg Clayton63094e02010-06-23 01:19:29 +000096 if (m_opaque_sp)
97 m_opaque_sp->SetOutputFileHandle (fh, transfer_ownership);
Chris Lattner24943d22010-06-08 16:52:24 +000098}
99
100void
101SBDebugger::SetErrorFileHandle (FILE *fh, bool transfer_ownership)
102{
Greg Clayton63094e02010-06-23 01:19:29 +0000103 if (m_opaque_sp)
104 m_opaque_sp->SetErrorFileHandle (fh, transfer_ownership);
Chris Lattner24943d22010-06-08 16:52:24 +0000105}
106
107FILE *
108SBDebugger::GetInputFileHandle ()
109{
Greg Clayton63094e02010-06-23 01:19:29 +0000110 if (m_opaque_sp)
111 return m_opaque_sp->GetInputFileHandle();
112 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000113}
114
115FILE *
116SBDebugger::GetOutputFileHandle ()
117{
Greg Clayton63094e02010-06-23 01:19:29 +0000118 if (m_opaque_sp)
119 return m_opaque_sp->GetOutputFileHandle();
120 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000121}
122
123FILE *
124SBDebugger::GetErrorFileHandle ()
125{
Greg Clayton63094e02010-06-23 01:19:29 +0000126 if (m_opaque_sp)
127 return m_opaque_sp->GetErrorFileHandle();
128 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000129}
130
131SBCommandInterpreter
132SBDebugger::GetCommandInterpreter ()
133{
Greg Clayton63094e02010-06-23 01:19:29 +0000134 SBCommandInterpreter sb_interpreter;
135 if (m_opaque_sp)
136 sb_interpreter.reset (&m_opaque_sp->GetCommandInterpreter());
Chris Lattner24943d22010-06-08 16:52:24 +0000137 return sb_interpreter;
138}
139
140void
141SBDebugger::HandleCommand (const char *command)
142{
Greg Clayton63094e02010-06-23 01:19:29 +0000143 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000144 {
Greg Clayton63094e02010-06-23 01:19:29 +0000145 SBCommandInterpreter sb_interpreter(GetCommandInterpreter ());
146 SBCommandReturnObject result;
147
148 sb_interpreter.HandleCommand (command, result, false);
149
150 if (GetErrorFileHandle() != NULL)
151 result.PutError (GetErrorFileHandle());
152 if (GetOutputFileHandle() != NULL)
153 result.PutOutput (GetOutputFileHandle());
154
155 if (m_opaque_sp->GetAsyncExecution() == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000156 {
Greg Clayton63094e02010-06-23 01:19:29 +0000157 SBProcess process(GetCommandInterpreter().GetProcess ());
158 if (process.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000159 {
Greg Clayton63094e02010-06-23 01:19:29 +0000160 EventSP event_sp;
161 Listener &lldb_listener = m_opaque_sp->GetListener();
162 while (lldb_listener.GetNextEventForBroadcaster (process.get(), event_sp))
163 {
164 SBEvent event(event_sp);
165 HandleProcessEvent (process, event, GetOutputFileHandle(), GetErrorFileHandle());
166 }
Chris Lattner24943d22010-06-08 16:52:24 +0000167 }
168 }
169 }
170}
171
172SBListener
173SBDebugger::GetListener ()
174{
Greg Clayton63094e02010-06-23 01:19:29 +0000175 SBListener sb_listener;
176 if (m_opaque_sp)
177 sb_listener.reset(&m_opaque_sp->GetListener(), false);
Chris Lattner24943d22010-06-08 16:52:24 +0000178 return sb_listener;
179}
180
181void
182SBDebugger::HandleProcessEvent (const SBProcess &process, const SBEvent &event, FILE *out, FILE *err)
183{
184 const uint32_t event_type = event.GetType();
185 char stdio_buffer[1024];
186 size_t len;
187
188 if (event_type & Process::eBroadcastBitSTDOUT)
189 {
190 while ((len = process.GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
191 if (out != NULL)
192 ::fwrite (stdio_buffer, 1, len, out);
193 }
194 else if (event_type & Process::eBroadcastBitSTDERR)
195 {
196 while ((len = process.GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
197 if (out != NULL)
198 ::fwrite (stdio_buffer, 1, len, out);
199 }
200 else if (event_type & Process::eBroadcastBitStateChanged)
201 {
202 // Drain any stdout messages.
203 while ((len = process.GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
204 if (out != NULL)
205 ::fwrite (stdio_buffer, 1, len, out);
206
207 // Drain any stderr messages.
208 while ((len = process.GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
209 if (out != NULL)
210 ::fwrite (stdio_buffer, 1, len, out);
211
212 StateType event_state = SBProcess::GetStateFromEvent (event);
213
214 if (event_state == eStateInvalid)
215 return;
216
217 bool is_stopped = StateIsStoppedState (event_state);
218 if (!is_stopped)
Jim Inghamc8332952010-08-26 21:32:51 +0000219 process.ReportEventState (event, out);
Chris Lattner24943d22010-06-08 16:52:24 +0000220 }
221}
222
223void
Jim Inghamc8332952010-08-26 21:32:51 +0000224SBDebugger::UpdateSelectedThread (SBProcess &process)
Chris Lattner24943d22010-06-08 16:52:24 +0000225{
226 if (process.IsValid())
227 {
Jim Inghamc8332952010-08-26 21:32:51 +0000228 SBThread curr_thread = process.GetSelectedThread ();
Chris Lattner24943d22010-06-08 16:52:24 +0000229 SBThread thread;
230 StopReason curr_thread_stop_reason = eStopReasonInvalid;
231 if (curr_thread.IsValid())
232 {
233 if (curr_thread.GetStopReason() != eStopReasonInvalid)
234 curr_thread_stop_reason = curr_thread.GetStopReason ();
235 }
236
237 if (! curr_thread.IsValid()
238 || curr_thread_stop_reason == eStopReasonInvalid
239 || curr_thread_stop_reason == eStopReasonNone)
240 {
241 // Prefer a thread that has just completed its plan over another thread as current thread.
242 SBThread plan_thread;
243 SBThread other_thread;
244 const size_t num_threads = process.GetNumThreads ();
245 size_t i;
246 for (i = 0; i < num_threads; ++i)
247 {
248 thread = process.GetThreadAtIndex(i);
249 if (thread.GetStopReason () != eStopReasonInvalid)
250 {
251 switch (thread.GetStopReason ())
252 {
253 default:
254 case eStopReasonInvalid:
255 case eStopReasonNone:
256 break;
257
258 case eStopReasonTrace:
259 case eStopReasonBreakpoint:
260 case eStopReasonWatchpoint:
261 case eStopReasonSignal:
262 case eStopReasonException:
263 if (! other_thread.IsValid())
264 other_thread = thread;
265 break;
266 case eStopReasonPlanComplete:
267 if (! plan_thread.IsValid())
268 plan_thread = thread;
269 break;
270 }
271 }
272 }
273 if (plan_thread.IsValid())
Jim Inghamc8332952010-08-26 21:32:51 +0000274 process.SetSelectedThreadByID (plan_thread.GetThreadID());
Chris Lattner24943d22010-06-08 16:52:24 +0000275 else if (other_thread.IsValid())
Jim Inghamc8332952010-08-26 21:32:51 +0000276 process.SetSelectedThreadByID (other_thread.GetThreadID());
Chris Lattner24943d22010-06-08 16:52:24 +0000277 else
278 {
279 if (curr_thread.IsValid())
280 thread = curr_thread;
281 else
282 thread = process.GetThreadAtIndex(0);
283
284 if (thread.IsValid())
Jim Inghamc8332952010-08-26 21:32:51 +0000285 process.SetSelectedThreadByID (thread.GetThreadID());
Chris Lattner24943d22010-06-08 16:52:24 +0000286 }
287 }
288 }
289}
290
Chris Lattner24943d22010-06-08 16:52:24 +0000291SBSourceManager &
292SBDebugger::GetSourceManager ()
293{
294 static SourceManager g_lldb_source_manager;
295 static SBSourceManager g_sb_source_manager (g_lldb_source_manager);
296 return g_sb_source_manager;
297}
298
299
300bool
301SBDebugger::GetDefaultArchitecture (char *arch_name, size_t arch_name_len)
302{
303 if (arch_name && arch_name_len)
304 {
305 ArchSpec &default_arch = lldb_private::GetDefaultArchitecture ();
306 if (default_arch.IsValid())
307 {
308 ::snprintf (arch_name, arch_name_len, "%s", default_arch.AsCString());
309 return true;
310 }
311 }
312 if (arch_name && arch_name_len)
313 arch_name[0] = '\0';
314 return false;
315}
316
317
318bool
319SBDebugger::SetDefaultArchitecture (const char *arch_name)
320{
321 if (arch_name)
322 {
323 ArchSpec arch (arch_name);
324 if (arch.IsValid())
325 {
326 lldb_private::GetDefaultArchitecture () = arch;
327 return true;
328 }
329 }
330 return false;
331}
332
333ScriptLanguage
334SBDebugger::GetScriptingLanguage (const char *script_language_name)
335{
336 return Args::StringToScriptLanguage (script_language_name,
337 eScriptLanguageDefault,
338 NULL);
339}
Chris Lattner24943d22010-06-08 16:52:24 +0000340
341const char *
342SBDebugger::GetVersionString ()
343{
344 return lldb_private::GetVersion();
345}
346
347const char *
348SBDebugger::StateAsCString (lldb::StateType state)
349{
350 return lldb_private::StateAsCString (state);
351}
352
353bool
354SBDebugger::StateIsRunningState (lldb::StateType state)
355{
356 return lldb_private::StateIsRunningState (state);
357}
358
359bool
360SBDebugger::StateIsStoppedState (lldb::StateType state)
361{
362 return lldb_private::StateIsStoppedState (state);
363}
364
365
366SBTarget
367SBDebugger::CreateTargetWithFileAndTargetTriple (const char *filename,
368 const char *target_triple)
369{
Greg Clayton63094e02010-06-23 01:19:29 +0000370 SBTarget target;
371 if (m_opaque_sp)
372 {
373 ArchSpec arch;
374 FileSpec file_spec (filename);
375 arch.SetArchFromTargetTriple(target_triple);
376 TargetSP target_sp;
377 Error error (m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file_spec, arch, NULL, true, target_sp));
378 target.reset (target_sp);
379 }
Chris Lattner24943d22010-06-08 16:52:24 +0000380 return target;
381}
382
383SBTarget
384SBDebugger::CreateTargetWithFileAndArch (const char *filename, const char *archname)
385{
Greg Clayton63094e02010-06-23 01:19:29 +0000386 SBTarget target;
387 if (m_opaque_sp)
388 {
389 FileSpec file (filename);
390 ArchSpec arch = lldb_private::GetDefaultArchitecture();
391 TargetSP target_sp;
392 Error error;
Chris Lattner24943d22010-06-08 16:52:24 +0000393
Greg Clayton63094e02010-06-23 01:19:29 +0000394 if (archname != NULL)
395 {
396 ArchSpec arch2 (archname);
397 error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch2, NULL, true, target_sp);
398 }
399 else
400 {
401 if (!arch.IsValid())
402 arch = LLDB_ARCH_DEFAULT;
403
404 error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, NULL, true, target_sp);
405
406 if (error.Fail())
407 {
408 if (arch == LLDB_ARCH_DEFAULT_32BIT)
409 arch = LLDB_ARCH_DEFAULT_64BIT;
410 else
411 arch = LLDB_ARCH_DEFAULT_32BIT;
412
413 error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, NULL, true, target_sp);
414 }
415 }
416
417 if (error.Success())
418 {
Jim Inghamc8332952010-08-26 21:32:51 +0000419 m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get());
Greg Clayton63094e02010-06-23 01:19:29 +0000420 target.reset(target_sp);
421 }
Chris Lattner24943d22010-06-08 16:52:24 +0000422 }
Greg Clayton63094e02010-06-23 01:19:29 +0000423 return target;
424}
425
426SBTarget
427SBDebugger::CreateTarget (const char *filename)
428{
429 SBTarget target;
430 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000431 {
Greg Clayton63094e02010-06-23 01:19:29 +0000432 FileSpec file (filename);
433 ArchSpec arch = lldb_private::GetDefaultArchitecture();
434 TargetSP target_sp;
435 Error error;
436
Chris Lattner24943d22010-06-08 16:52:24 +0000437 if (!arch.IsValid())
438 arch = LLDB_ARCH_DEFAULT;
439
Greg Clayton63094e02010-06-23 01:19:29 +0000440 error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, NULL, true, target_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000441
442 if (error.Fail())
443 {
444 if (arch == LLDB_ARCH_DEFAULT_32BIT)
445 arch = LLDB_ARCH_DEFAULT_64BIT;
446 else
447 arch = LLDB_ARCH_DEFAULT_32BIT;
448
Greg Clayton63094e02010-06-23 01:19:29 +0000449 error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, NULL, true, target_sp);
450 }
451
452 if (error.Success())
453 {
Jim Inghamc8332952010-08-26 21:32:51 +0000454 m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get());
Greg Clayton63094e02010-06-23 01:19:29 +0000455 target.reset (target_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000456 }
457 }
Greg Clayton63094e02010-06-23 01:19:29 +0000458 return target;
Chris Lattner24943d22010-06-08 16:52:24 +0000459}
460
461SBTarget
462SBDebugger::GetTargetAtIndex (uint32_t idx)
463{
Greg Clayton63094e02010-06-23 01:19:29 +0000464 SBTarget sb_target;
465 if (m_opaque_sp)
466 sb_target.reset(m_opaque_sp->GetTargetList().GetTargetAtIndex (idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000467 return sb_target;
468}
469
470SBTarget
471SBDebugger::FindTargetWithProcessID (pid_t pid)
472{
Greg Clayton63094e02010-06-23 01:19:29 +0000473 SBTarget sb_target;
474 if (m_opaque_sp)
475 sb_target.reset(m_opaque_sp->GetTargetList().FindTargetWithProcessID (pid));
Chris Lattner24943d22010-06-08 16:52:24 +0000476 return sb_target;
477}
478
479SBTarget
480SBDebugger::FindTargetWithFileAndArch (const char *filename, const char *arch_name)
481{
Greg Clayton63094e02010-06-23 01:19:29 +0000482 SBTarget sb_target;
483 if (m_opaque_sp && filename && filename[0])
484 {
485 ArchSpec arch;
486 if (arch_name)
487 arch.SetArch(arch_name);
488 TargetSP target_sp (m_opaque_sp->GetTargetList().FindTargetWithExecutableAndArchitecture (FileSpec(filename), arch_name ? &arch : NULL));
489 sb_target.reset(target_sp);
490 }
491 return sb_target;
Chris Lattner24943d22010-06-08 16:52:24 +0000492}
493
494SBTarget
495SBDebugger::FindTargetWithLLDBProcess (const lldb::ProcessSP &process_sp)
496{
Greg Clayton63094e02010-06-23 01:19:29 +0000497 SBTarget sb_target;
498 if (m_opaque_sp)
499 sb_target.reset(m_opaque_sp->GetTargetList().FindTargetWithProcess (process_sp.get()));
Chris Lattner24943d22010-06-08 16:52:24 +0000500 return sb_target;
501}
502
503
504uint32_t
505SBDebugger::GetNumTargets ()
506{
Greg Clayton63094e02010-06-23 01:19:29 +0000507 if (m_opaque_sp)
508 return m_opaque_sp->GetTargetList().GetNumTargets ();
509 return 0;
510}
Chris Lattner24943d22010-06-08 16:52:24 +0000511
512SBTarget
Jim Inghamc8332952010-08-26 21:32:51 +0000513SBDebugger::GetSelectedTarget ()
Chris Lattner24943d22010-06-08 16:52:24 +0000514{
Greg Clayton63094e02010-06-23 01:19:29 +0000515 SBTarget sb_target;
516 if (m_opaque_sp)
Jim Inghamc8332952010-08-26 21:32:51 +0000517 sb_target.reset(m_opaque_sp->GetTargetList().GetSelectedTarget ());
Chris Lattner24943d22010-06-08 16:52:24 +0000518 return sb_target;
519}
520
521void
522SBDebugger::DispatchInput (void *baton, const void *data, size_t data_len)
523{
Greg Clayton63094e02010-06-23 01:19:29 +0000524 if (m_opaque_sp)
525 m_opaque_sp->DispatchInput ((const char *) data, data_len);
Chris Lattner24943d22010-06-08 16:52:24 +0000526}
527
528void
529SBDebugger::PushInputReader (SBInputReader &reader)
530{
Greg Clayton63094e02010-06-23 01:19:29 +0000531 if (m_opaque_sp && reader.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000532 {
533 InputReaderSP reader_sp(*reader);
Greg Clayton63094e02010-06-23 01:19:29 +0000534 m_opaque_sp->PushInputReader (reader_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000535 }
536}
Greg Clayton63094e02010-06-23 01:19:29 +0000537
538void
539SBDebugger::reset (const lldb::DebuggerSP &debugger_sp)
540{
541 m_opaque_sp = debugger_sp;
542}
543
544Debugger *
545SBDebugger::get () const
546{
547 return m_opaque_sp.get();
548}
549
550Debugger &
551SBDebugger::ref () const
552{
553 assert (m_opaque_sp.get());
554 return *m_opaque_sp;
555}
556
557
Caroline Tice558be582010-06-30 16:22:25 +0000558SBDebugger
559SBDebugger::FindDebuggerWithID (int id)
560{
561 SBDebugger sb_debugger;
562 lldb::DebuggerSP debugger_sp = Debugger::FindDebuggerWithID (id);
563 if (debugger_sp)
564 sb_debugger.reset (debugger_sp);
565 return sb_debugger;
566}
Jim Ingham74989e82010-08-30 19:44:40 +0000567
Caroline Tice6e4c5ce2010-09-04 00:03:46 +0000568SBError
569SBDebugger::SetInternalVariable (const char *var_name, const char *value)
570{
571 lldb::UserSettingsControllerSP root_settings_controller = lldb_private::Debugger::GetSettingsController();
572
573 Error err = root_settings_controller->SetVariable (var_name, value, lldb::eVarSetOperationAssign, false);
574 SBError sb_error;
575 sb_error.SetError (err);
576
577 return sb_error;
578}
579
580lldb::SBStringList
581SBDebugger::GetInternalVariableValue (const char *var_name)
582{
583 SBStringList ret_value;
584 lldb::UserSettingsControllerSP root_settings_controller = lldb_private::Debugger::GetSettingsController();
585
586 lldb::SettableVariableType var_type;
587 StringList value = root_settings_controller->GetVariable (var_name, var_type);
588 for (int i = 0; i < value.GetSize(); ++i)
589 ret_value.AppendString (value.GetStringAtIndex(i));
590
591 return ret_value;
592}
593
Jim Ingham74989e82010-08-30 19:44:40 +0000594bool
595SBDebugger::SetUseExternalEditor (bool value)
596{
597 if (m_opaque_sp)
598 return m_opaque_sp->SetUseExternalEditor (value);
599 else
600 return false;
601}
602
603bool
604SBDebugger::UseExternalEditor ()
605{
606 if (m_opaque_sp)
607 return m_opaque_sp->UseExternalEditor ();
608 else
609 return false;
610}
611