blob: 73f125bcb8a847009de13f4862a572db480630be [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"
25#include "lldb/API/SBTarget.h"
26#include "lldb/API/SBProcess.h"
27#include "lldb/API/SBThread.h"
28#include "lldb/API/SBSourceManager.h"
29#include "lldb/API/SBInputReader.h"
Chris Lattner24943d22010-06-08 16:52:24 +000030
31using namespace lldb;
32using namespace lldb_private;
33
34void
35SBDebugger::Initialize ()
36{
37 Debugger::Initialize();
38}
39
40void
41SBDebugger::Terminate ()
42{
43 Debugger::Terminate();
44}
45
Greg Clayton43490d12010-07-30 20:12:55 +000046void
47SBDebugger::Clear ()
48{
49 m_opaque_sp.reset();
50}
51
Greg Clayton63094e02010-06-23 01:19:29 +000052SBDebugger
53SBDebugger::Create()
54{
55 SBDebugger debugger;
56 debugger.reset(Debugger::CreateInstance());
57 return debugger;
58}
59
Greg Clayton63094e02010-06-23 01:19:29 +000060SBDebugger::SBDebugger () :
61 m_opaque_sp ()
62{
63}
64
65SBDebugger::~SBDebugger ()
66{
67}
68
69bool
70SBDebugger::IsValid() const
71{
72 return m_opaque_sp.get() != NULL;
73}
74
75
Chris Lattner24943d22010-06-08 16:52:24 +000076void
77SBDebugger::SetAsync (bool b)
78{
Greg Clayton63094e02010-06-23 01:19:29 +000079 if (m_opaque_sp)
80 m_opaque_sp->SetAsyncExecution(b);
Chris Lattner24943d22010-06-08 16:52:24 +000081}
82
Chris Lattner24943d22010-06-08 16:52:24 +000083// Shouldn't really be settable after initialization as this could cause lots of problems; don't want users
84// trying to switch modes in the middle of a debugging session.
85void
86SBDebugger::SetInputFileHandle (FILE *fh, bool transfer_ownership)
87{
Greg Clayton63094e02010-06-23 01:19:29 +000088 if (m_opaque_sp)
89 m_opaque_sp->SetInputFileHandle (fh, transfer_ownership);
Chris Lattner24943d22010-06-08 16:52:24 +000090}
91
92void
93SBDebugger::SetOutputFileHandle (FILE *fh, bool transfer_ownership)
94{
Greg Clayton63094e02010-06-23 01:19:29 +000095 if (m_opaque_sp)
96 m_opaque_sp->SetOutputFileHandle (fh, transfer_ownership);
Chris Lattner24943d22010-06-08 16:52:24 +000097}
98
99void
100SBDebugger::SetErrorFileHandle (FILE *fh, bool transfer_ownership)
101{
Greg Clayton63094e02010-06-23 01:19:29 +0000102 if (m_opaque_sp)
103 m_opaque_sp->SetErrorFileHandle (fh, transfer_ownership);
Chris Lattner24943d22010-06-08 16:52:24 +0000104}
105
106FILE *
107SBDebugger::GetInputFileHandle ()
108{
Greg Clayton63094e02010-06-23 01:19:29 +0000109 if (m_opaque_sp)
110 return m_opaque_sp->GetInputFileHandle();
111 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000112}
113
114FILE *
115SBDebugger::GetOutputFileHandle ()
116{
Greg Clayton63094e02010-06-23 01:19:29 +0000117 if (m_opaque_sp)
118 return m_opaque_sp->GetOutputFileHandle();
119 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000120}
121
122FILE *
123SBDebugger::GetErrorFileHandle ()
124{
Greg Clayton63094e02010-06-23 01:19:29 +0000125 if (m_opaque_sp)
126 return m_opaque_sp->GetErrorFileHandle();
127 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000128}
129
130SBCommandInterpreter
131SBDebugger::GetCommandInterpreter ()
132{
Greg Clayton63094e02010-06-23 01:19:29 +0000133 SBCommandInterpreter sb_interpreter;
134 if (m_opaque_sp)
135 sb_interpreter.reset (&m_opaque_sp->GetCommandInterpreter());
Chris Lattner24943d22010-06-08 16:52:24 +0000136 return sb_interpreter;
137}
138
139void
140SBDebugger::HandleCommand (const char *command)
141{
Greg Clayton63094e02010-06-23 01:19:29 +0000142 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000143 {
Greg Clayton63094e02010-06-23 01:19:29 +0000144 SBCommandInterpreter sb_interpreter(GetCommandInterpreter ());
145 SBCommandReturnObject result;
146
147 sb_interpreter.HandleCommand (command, result, false);
148
149 if (GetErrorFileHandle() != NULL)
150 result.PutError (GetErrorFileHandle());
151 if (GetOutputFileHandle() != NULL)
152 result.PutOutput (GetOutputFileHandle());
153
154 if (m_opaque_sp->GetAsyncExecution() == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000155 {
Greg Clayton63094e02010-06-23 01:19:29 +0000156 SBProcess process(GetCommandInterpreter().GetProcess ());
157 if (process.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000158 {
Greg Clayton63094e02010-06-23 01:19:29 +0000159 EventSP event_sp;
160 Listener &lldb_listener = m_opaque_sp->GetListener();
161 while (lldb_listener.GetNextEventForBroadcaster (process.get(), event_sp))
162 {
163 SBEvent event(event_sp);
164 HandleProcessEvent (process, event, GetOutputFileHandle(), GetErrorFileHandle());
165 }
Chris Lattner24943d22010-06-08 16:52:24 +0000166 }
167 }
168 }
169}
170
171SBListener
172SBDebugger::GetListener ()
173{
Greg Clayton63094e02010-06-23 01:19:29 +0000174 SBListener sb_listener;
175 if (m_opaque_sp)
176 sb_listener.reset(&m_opaque_sp->GetListener(), false);
Chris Lattner24943d22010-06-08 16:52:24 +0000177 return sb_listener;
178}
179
180void
181SBDebugger::HandleProcessEvent (const SBProcess &process, const SBEvent &event, FILE *out, FILE *err)
182{
183 const uint32_t event_type = event.GetType();
184 char stdio_buffer[1024];
185 size_t len;
186
187 if (event_type & Process::eBroadcastBitSTDOUT)
188 {
189 while ((len = process.GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
190 if (out != NULL)
191 ::fwrite (stdio_buffer, 1, len, out);
192 }
193 else if (event_type & Process::eBroadcastBitSTDERR)
194 {
195 while ((len = process.GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
196 if (out != NULL)
197 ::fwrite (stdio_buffer, 1, len, out);
198 }
199 else if (event_type & Process::eBroadcastBitStateChanged)
200 {
201 // Drain any stdout messages.
202 while ((len = process.GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
203 if (out != NULL)
204 ::fwrite (stdio_buffer, 1, len, out);
205
206 // Drain any stderr messages.
207 while ((len = process.GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
208 if (out != NULL)
209 ::fwrite (stdio_buffer, 1, len, out);
210
211 StateType event_state = SBProcess::GetStateFromEvent (event);
212
213 if (event_state == eStateInvalid)
214 return;
215
216 bool is_stopped = StateIsStoppedState (event_state);
217 if (!is_stopped)
Jim Inghamc8332952010-08-26 21:32:51 +0000218 process.ReportEventState (event, out);
Chris Lattner24943d22010-06-08 16:52:24 +0000219 }
220}
221
222void
Jim Inghamc8332952010-08-26 21:32:51 +0000223SBDebugger::UpdateSelectedThread (SBProcess &process)
Chris Lattner24943d22010-06-08 16:52:24 +0000224{
225 if (process.IsValid())
226 {
Jim Inghamc8332952010-08-26 21:32:51 +0000227 SBThread curr_thread = process.GetSelectedThread ();
Chris Lattner24943d22010-06-08 16:52:24 +0000228 SBThread thread;
229 StopReason curr_thread_stop_reason = eStopReasonInvalid;
230 if (curr_thread.IsValid())
231 {
232 if (curr_thread.GetStopReason() != eStopReasonInvalid)
233 curr_thread_stop_reason = curr_thread.GetStopReason ();
234 }
235
236 if (! curr_thread.IsValid()
237 || curr_thread_stop_reason == eStopReasonInvalid
238 || curr_thread_stop_reason == eStopReasonNone)
239 {
240 // Prefer a thread that has just completed its plan over another thread as current thread.
241 SBThread plan_thread;
242 SBThread other_thread;
243 const size_t num_threads = process.GetNumThreads ();
244 size_t i;
245 for (i = 0; i < num_threads; ++i)
246 {
247 thread = process.GetThreadAtIndex(i);
248 if (thread.GetStopReason () != eStopReasonInvalid)
249 {
250 switch (thread.GetStopReason ())
251 {
252 default:
253 case eStopReasonInvalid:
254 case eStopReasonNone:
255 break;
256
257 case eStopReasonTrace:
258 case eStopReasonBreakpoint:
259 case eStopReasonWatchpoint:
260 case eStopReasonSignal:
261 case eStopReasonException:
262 if (! other_thread.IsValid())
263 other_thread = thread;
264 break;
265 case eStopReasonPlanComplete:
266 if (! plan_thread.IsValid())
267 plan_thread = thread;
268 break;
269 }
270 }
271 }
272 if (plan_thread.IsValid())
Jim Inghamc8332952010-08-26 21:32:51 +0000273 process.SetSelectedThreadByID (plan_thread.GetThreadID());
Chris Lattner24943d22010-06-08 16:52:24 +0000274 else if (other_thread.IsValid())
Jim Inghamc8332952010-08-26 21:32:51 +0000275 process.SetSelectedThreadByID (other_thread.GetThreadID());
Chris Lattner24943d22010-06-08 16:52:24 +0000276 else
277 {
278 if (curr_thread.IsValid())
279 thread = curr_thread;
280 else
281 thread = process.GetThreadAtIndex(0);
282
283 if (thread.IsValid())
Jim Inghamc8332952010-08-26 21:32:51 +0000284 process.SetSelectedThreadByID (thread.GetThreadID());
Chris Lattner24943d22010-06-08 16:52:24 +0000285 }
286 }
287 }
288}
289
Chris Lattner24943d22010-06-08 16:52:24 +0000290SBSourceManager &
291SBDebugger::GetSourceManager ()
292{
293 static SourceManager g_lldb_source_manager;
294 static SBSourceManager g_sb_source_manager (g_lldb_source_manager);
295 return g_sb_source_manager;
296}
297
298
299bool
300SBDebugger::GetDefaultArchitecture (char *arch_name, size_t arch_name_len)
301{
302 if (arch_name && arch_name_len)
303 {
304 ArchSpec &default_arch = lldb_private::GetDefaultArchitecture ();
305 if (default_arch.IsValid())
306 {
307 ::snprintf (arch_name, arch_name_len, "%s", default_arch.AsCString());
308 return true;
309 }
310 }
311 if (arch_name && arch_name_len)
312 arch_name[0] = '\0';
313 return false;
314}
315
316
317bool
318SBDebugger::SetDefaultArchitecture (const char *arch_name)
319{
320 if (arch_name)
321 {
322 ArchSpec arch (arch_name);
323 if (arch.IsValid())
324 {
325 lldb_private::GetDefaultArchitecture () = arch;
326 return true;
327 }
328 }
329 return false;
330}
331
332ScriptLanguage
333SBDebugger::GetScriptingLanguage (const char *script_language_name)
334{
335 return Args::StringToScriptLanguage (script_language_name,
336 eScriptLanguageDefault,
337 NULL);
338}
Chris Lattner24943d22010-06-08 16:52:24 +0000339
340const char *
341SBDebugger::GetVersionString ()
342{
343 return lldb_private::GetVersion();
344}
345
346const char *
347SBDebugger::StateAsCString (lldb::StateType state)
348{
349 return lldb_private::StateAsCString (state);
350}
351
352bool
353SBDebugger::StateIsRunningState (lldb::StateType state)
354{
355 return lldb_private::StateIsRunningState (state);
356}
357
358bool
359SBDebugger::StateIsStoppedState (lldb::StateType state)
360{
361 return lldb_private::StateIsStoppedState (state);
362}
363
364
365SBTarget
366SBDebugger::CreateTargetWithFileAndTargetTriple (const char *filename,
367 const char *target_triple)
368{
Greg Clayton63094e02010-06-23 01:19:29 +0000369 SBTarget target;
370 if (m_opaque_sp)
371 {
372 ArchSpec arch;
373 FileSpec file_spec (filename);
374 arch.SetArchFromTargetTriple(target_triple);
375 TargetSP target_sp;
376 Error error (m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file_spec, arch, NULL, true, target_sp));
377 target.reset (target_sp);
378 }
Chris Lattner24943d22010-06-08 16:52:24 +0000379 return target;
380}
381
382SBTarget
383SBDebugger::CreateTargetWithFileAndArch (const char *filename, const char *archname)
384{
Greg Clayton63094e02010-06-23 01:19:29 +0000385 SBTarget target;
386 if (m_opaque_sp)
387 {
388 FileSpec file (filename);
389 ArchSpec arch = lldb_private::GetDefaultArchitecture();
390 TargetSP target_sp;
391 Error error;
Chris Lattner24943d22010-06-08 16:52:24 +0000392
Greg Clayton63094e02010-06-23 01:19:29 +0000393 if (archname != NULL)
394 {
395 ArchSpec arch2 (archname);
396 error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch2, NULL, true, target_sp);
397 }
398 else
399 {
400 if (!arch.IsValid())
401 arch = LLDB_ARCH_DEFAULT;
402
403 error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, NULL, true, target_sp);
404
405 if (error.Fail())
406 {
407 if (arch == LLDB_ARCH_DEFAULT_32BIT)
408 arch = LLDB_ARCH_DEFAULT_64BIT;
409 else
410 arch = LLDB_ARCH_DEFAULT_32BIT;
411
412 error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, NULL, true, target_sp);
413 }
414 }
415
416 if (error.Success())
417 {
Jim Inghamc8332952010-08-26 21:32:51 +0000418 m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get());
Greg Clayton63094e02010-06-23 01:19:29 +0000419 target.reset(target_sp);
420 }
Chris Lattner24943d22010-06-08 16:52:24 +0000421 }
Greg Clayton63094e02010-06-23 01:19:29 +0000422 return target;
423}
424
425SBTarget
426SBDebugger::CreateTarget (const char *filename)
427{
428 SBTarget target;
429 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000430 {
Greg Clayton63094e02010-06-23 01:19:29 +0000431 FileSpec file (filename);
432 ArchSpec arch = lldb_private::GetDefaultArchitecture();
433 TargetSP target_sp;
434 Error error;
435
Chris Lattner24943d22010-06-08 16:52:24 +0000436 if (!arch.IsValid())
437 arch = LLDB_ARCH_DEFAULT;
438
Greg Clayton63094e02010-06-23 01:19:29 +0000439 error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, NULL, true, target_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000440
441 if (error.Fail())
442 {
443 if (arch == LLDB_ARCH_DEFAULT_32BIT)
444 arch = LLDB_ARCH_DEFAULT_64BIT;
445 else
446 arch = LLDB_ARCH_DEFAULT_32BIT;
447
Greg Clayton63094e02010-06-23 01:19:29 +0000448 error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, NULL, true, target_sp);
449 }
450
451 if (error.Success())
452 {
Jim Inghamc8332952010-08-26 21:32:51 +0000453 m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get());
Greg Clayton63094e02010-06-23 01:19:29 +0000454 target.reset (target_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000455 }
456 }
Greg Clayton63094e02010-06-23 01:19:29 +0000457 return target;
Chris Lattner24943d22010-06-08 16:52:24 +0000458}
459
460SBTarget
461SBDebugger::GetTargetAtIndex (uint32_t idx)
462{
Greg Clayton63094e02010-06-23 01:19:29 +0000463 SBTarget sb_target;
464 if (m_opaque_sp)
465 sb_target.reset(m_opaque_sp->GetTargetList().GetTargetAtIndex (idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000466 return sb_target;
467}
468
469SBTarget
470SBDebugger::FindTargetWithProcessID (pid_t pid)
471{
Greg Clayton63094e02010-06-23 01:19:29 +0000472 SBTarget sb_target;
473 if (m_opaque_sp)
474 sb_target.reset(m_opaque_sp->GetTargetList().FindTargetWithProcessID (pid));
Chris Lattner24943d22010-06-08 16:52:24 +0000475 return sb_target;
476}
477
478SBTarget
479SBDebugger::FindTargetWithFileAndArch (const char *filename, const char *arch_name)
480{
Greg Clayton63094e02010-06-23 01:19:29 +0000481 SBTarget sb_target;
482 if (m_opaque_sp && filename && filename[0])
483 {
484 ArchSpec arch;
485 if (arch_name)
486 arch.SetArch(arch_name);
487 TargetSP target_sp (m_opaque_sp->GetTargetList().FindTargetWithExecutableAndArchitecture (FileSpec(filename), arch_name ? &arch : NULL));
488 sb_target.reset(target_sp);
489 }
490 return sb_target;
Chris Lattner24943d22010-06-08 16:52:24 +0000491}
492
493SBTarget
494SBDebugger::FindTargetWithLLDBProcess (const lldb::ProcessSP &process_sp)
495{
Greg Clayton63094e02010-06-23 01:19:29 +0000496 SBTarget sb_target;
497 if (m_opaque_sp)
498 sb_target.reset(m_opaque_sp->GetTargetList().FindTargetWithProcess (process_sp.get()));
Chris Lattner24943d22010-06-08 16:52:24 +0000499 return sb_target;
500}
501
502
503uint32_t
504SBDebugger::GetNumTargets ()
505{
Greg Clayton63094e02010-06-23 01:19:29 +0000506 if (m_opaque_sp)
507 return m_opaque_sp->GetTargetList().GetNumTargets ();
508 return 0;
509}
Chris Lattner24943d22010-06-08 16:52:24 +0000510
511SBTarget
Jim Inghamc8332952010-08-26 21:32:51 +0000512SBDebugger::GetSelectedTarget ()
Chris Lattner24943d22010-06-08 16:52:24 +0000513{
Greg Clayton63094e02010-06-23 01:19:29 +0000514 SBTarget sb_target;
515 if (m_opaque_sp)
Jim Inghamc8332952010-08-26 21:32:51 +0000516 sb_target.reset(m_opaque_sp->GetTargetList().GetSelectedTarget ());
Chris Lattner24943d22010-06-08 16:52:24 +0000517 return sb_target;
518}
519
520void
521SBDebugger::DispatchInput (void *baton, const void *data, size_t data_len)
522{
Greg Clayton63094e02010-06-23 01:19:29 +0000523 if (m_opaque_sp)
524 m_opaque_sp->DispatchInput ((const char *) data, data_len);
Chris Lattner24943d22010-06-08 16:52:24 +0000525}
526
527void
528SBDebugger::PushInputReader (SBInputReader &reader)
529{
Greg Clayton63094e02010-06-23 01:19:29 +0000530 if (m_opaque_sp && reader.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000531 {
532 InputReaderSP reader_sp(*reader);
Greg Clayton63094e02010-06-23 01:19:29 +0000533 m_opaque_sp->PushInputReader (reader_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000534 }
535}
Greg Clayton63094e02010-06-23 01:19:29 +0000536
537void
538SBDebugger::reset (const lldb::DebuggerSP &debugger_sp)
539{
540 m_opaque_sp = debugger_sp;
541}
542
543Debugger *
544SBDebugger::get () const
545{
546 return m_opaque_sp.get();
547}
548
549Debugger &
550SBDebugger::ref () const
551{
552 assert (m_opaque_sp.get());
553 return *m_opaque_sp;
554}
555
556
Caroline Tice558be582010-06-30 16:22:25 +0000557SBDebugger
558SBDebugger::FindDebuggerWithID (int id)
559{
560 SBDebugger sb_debugger;
561 lldb::DebuggerSP debugger_sp = Debugger::FindDebuggerWithID (id);
562 if (debugger_sp)
563 sb_debugger.reset (debugger_sp);
564 return sb_debugger;
565}