blob: d8d0dbbacb7d46c5cd633def0111723263d37d32 [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 Clayton63094e02010-06-23 01:19:29 +000046SBDebugger
47SBDebugger::Create()
48{
49 SBDebugger debugger;
50 debugger.reset(Debugger::CreateInstance());
51 return debugger;
52}
53
54
55SBDebugger::SBDebugger () :
56 m_opaque_sp ()
57{
58}
59
60SBDebugger::~SBDebugger ()
61{
62}
63
64bool
65SBDebugger::IsValid() const
66{
67 return m_opaque_sp.get() != NULL;
68}
69
70
Chris Lattner24943d22010-06-08 16:52:24 +000071void
72SBDebugger::SetAsync (bool b)
73{
Greg Clayton63094e02010-06-23 01:19:29 +000074 if (m_opaque_sp)
75 m_opaque_sp->SetAsyncExecution(b);
Chris Lattner24943d22010-06-08 16:52:24 +000076}
77
Chris Lattner24943d22010-06-08 16:52:24 +000078// Shouldn't really be settable after initialization as this could cause lots of problems; don't want users
79// trying to switch modes in the middle of a debugging session.
80void
81SBDebugger::SetInputFileHandle (FILE *fh, bool transfer_ownership)
82{
Greg Clayton63094e02010-06-23 01:19:29 +000083 if (m_opaque_sp)
84 m_opaque_sp->SetInputFileHandle (fh, transfer_ownership);
Chris Lattner24943d22010-06-08 16:52:24 +000085}
86
87void
88SBDebugger::SetOutputFileHandle (FILE *fh, bool transfer_ownership)
89{
Greg Clayton63094e02010-06-23 01:19:29 +000090 if (m_opaque_sp)
91 m_opaque_sp->SetOutputFileHandle (fh, transfer_ownership);
Chris Lattner24943d22010-06-08 16:52:24 +000092}
93
94void
95SBDebugger::SetErrorFileHandle (FILE *fh, bool transfer_ownership)
96{
Greg Clayton63094e02010-06-23 01:19:29 +000097 if (m_opaque_sp)
98 m_opaque_sp->SetErrorFileHandle (fh, transfer_ownership);
Chris Lattner24943d22010-06-08 16:52:24 +000099}
100
101FILE *
102SBDebugger::GetInputFileHandle ()
103{
Greg Clayton63094e02010-06-23 01:19:29 +0000104 if (m_opaque_sp)
105 return m_opaque_sp->GetInputFileHandle();
106 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000107}
108
109FILE *
110SBDebugger::GetOutputFileHandle ()
111{
Greg Clayton63094e02010-06-23 01:19:29 +0000112 if (m_opaque_sp)
113 return m_opaque_sp->GetOutputFileHandle();
114 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000115}
116
117FILE *
118SBDebugger::GetErrorFileHandle ()
119{
Greg Clayton63094e02010-06-23 01:19:29 +0000120 if (m_opaque_sp)
121 return m_opaque_sp->GetErrorFileHandle();
122 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000123}
124
125SBCommandInterpreter
126SBDebugger::GetCommandInterpreter ()
127{
Greg Clayton63094e02010-06-23 01:19:29 +0000128 SBCommandInterpreter sb_interpreter;
129 if (m_opaque_sp)
130 sb_interpreter.reset (&m_opaque_sp->GetCommandInterpreter());
Chris Lattner24943d22010-06-08 16:52:24 +0000131 return sb_interpreter;
132}
133
134void
135SBDebugger::HandleCommand (const char *command)
136{
Greg Clayton63094e02010-06-23 01:19:29 +0000137 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000138 {
Greg Clayton63094e02010-06-23 01:19:29 +0000139 SBCommandInterpreter sb_interpreter(GetCommandInterpreter ());
140 SBCommandReturnObject result;
141
142 sb_interpreter.HandleCommand (command, result, false);
143
144 if (GetErrorFileHandle() != NULL)
145 result.PutError (GetErrorFileHandle());
146 if (GetOutputFileHandle() != NULL)
147 result.PutOutput (GetOutputFileHandle());
148
149 if (m_opaque_sp->GetAsyncExecution() == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000150 {
Greg Clayton63094e02010-06-23 01:19:29 +0000151 SBProcess process(GetCommandInterpreter().GetProcess ());
152 if (process.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000153 {
Greg Clayton63094e02010-06-23 01:19:29 +0000154 EventSP event_sp;
155 Listener &lldb_listener = m_opaque_sp->GetListener();
156 while (lldb_listener.GetNextEventForBroadcaster (process.get(), event_sp))
157 {
158 SBEvent event(event_sp);
159 HandleProcessEvent (process, event, GetOutputFileHandle(), GetErrorFileHandle());
160 }
Chris Lattner24943d22010-06-08 16:52:24 +0000161 }
162 }
163 }
164}
165
166SBListener
167SBDebugger::GetListener ()
168{
Greg Clayton63094e02010-06-23 01:19:29 +0000169 SBListener sb_listener;
170 if (m_opaque_sp)
171 sb_listener.reset(&m_opaque_sp->GetListener(), false);
Chris Lattner24943d22010-06-08 16:52:24 +0000172 return sb_listener;
173}
174
175void
176SBDebugger::HandleProcessEvent (const SBProcess &process, const SBEvent &event, FILE *out, FILE *err)
177{
178 const uint32_t event_type = event.GetType();
179 char stdio_buffer[1024];
180 size_t len;
181
182 if (event_type & Process::eBroadcastBitSTDOUT)
183 {
184 while ((len = process.GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
185 if (out != NULL)
186 ::fwrite (stdio_buffer, 1, len, out);
187 }
188 else if (event_type & Process::eBroadcastBitSTDERR)
189 {
190 while ((len = process.GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
191 if (out != NULL)
192 ::fwrite (stdio_buffer, 1, len, out);
193 }
194 else if (event_type & Process::eBroadcastBitStateChanged)
195 {
196 // Drain any stdout messages.
197 while ((len = process.GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
198 if (out != NULL)
199 ::fwrite (stdio_buffer, 1, len, out);
200
201 // Drain any stderr messages.
202 while ((len = process.GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
203 if (out != NULL)
204 ::fwrite (stdio_buffer, 1, len, out);
205
206 StateType event_state = SBProcess::GetStateFromEvent (event);
207
208 if (event_state == eStateInvalid)
209 return;
210
211 bool is_stopped = StateIsStoppedState (event_state);
212 if (!is_stopped)
213 process.ReportCurrentState (event, out);
214 }
215}
216
217void
218SBDebugger::UpdateCurrentThread (SBProcess &process)
219{
220 if (process.IsValid())
221 {
222 SBThread curr_thread = process.GetCurrentThread ();
223 SBThread thread;
224 StopReason curr_thread_stop_reason = eStopReasonInvalid;
225 if (curr_thread.IsValid())
226 {
227 if (curr_thread.GetStopReason() != eStopReasonInvalid)
228 curr_thread_stop_reason = curr_thread.GetStopReason ();
229 }
230
231 if (! curr_thread.IsValid()
232 || curr_thread_stop_reason == eStopReasonInvalid
233 || curr_thread_stop_reason == eStopReasonNone)
234 {
235 // Prefer a thread that has just completed its plan over another thread as current thread.
236 SBThread plan_thread;
237 SBThread other_thread;
238 const size_t num_threads = process.GetNumThreads ();
239 size_t i;
240 for (i = 0; i < num_threads; ++i)
241 {
242 thread = process.GetThreadAtIndex(i);
243 if (thread.GetStopReason () != eStopReasonInvalid)
244 {
245 switch (thread.GetStopReason ())
246 {
247 default:
248 case eStopReasonInvalid:
249 case eStopReasonNone:
250 break;
251
252 case eStopReasonTrace:
253 case eStopReasonBreakpoint:
254 case eStopReasonWatchpoint:
255 case eStopReasonSignal:
256 case eStopReasonException:
257 if (! other_thread.IsValid())
258 other_thread = thread;
259 break;
260 case eStopReasonPlanComplete:
261 if (! plan_thread.IsValid())
262 plan_thread = thread;
263 break;
264 }
265 }
266 }
267 if (plan_thread.IsValid())
268 process.SetCurrentThreadByID (plan_thread.GetThreadID());
269 else if (other_thread.IsValid())
270 process.SetCurrentThreadByID (other_thread.GetThreadID());
271 else
272 {
273 if (curr_thread.IsValid())
274 thread = curr_thread;
275 else
276 thread = process.GetThreadAtIndex(0);
277
278 if (thread.IsValid())
279 process.SetCurrentThreadByID (thread.GetThreadID());
280 }
281 }
282 }
283}
284
Chris Lattner24943d22010-06-08 16:52:24 +0000285SBSourceManager &
286SBDebugger::GetSourceManager ()
287{
288 static SourceManager g_lldb_source_manager;
289 static SBSourceManager g_sb_source_manager (g_lldb_source_manager);
290 return g_sb_source_manager;
291}
292
293
294bool
295SBDebugger::GetDefaultArchitecture (char *arch_name, size_t arch_name_len)
296{
297 if (arch_name && arch_name_len)
298 {
299 ArchSpec &default_arch = lldb_private::GetDefaultArchitecture ();
300 if (default_arch.IsValid())
301 {
302 ::snprintf (arch_name, arch_name_len, "%s", default_arch.AsCString());
303 return true;
304 }
305 }
306 if (arch_name && arch_name_len)
307 arch_name[0] = '\0';
308 return false;
309}
310
311
312bool
313SBDebugger::SetDefaultArchitecture (const char *arch_name)
314{
315 if (arch_name)
316 {
317 ArchSpec arch (arch_name);
318 if (arch.IsValid())
319 {
320 lldb_private::GetDefaultArchitecture () = arch;
321 return true;
322 }
323 }
324 return false;
325}
326
327ScriptLanguage
328SBDebugger::GetScriptingLanguage (const char *script_language_name)
329{
330 return Args::StringToScriptLanguage (script_language_name,
331 eScriptLanguageDefault,
332 NULL);
333}
Chris Lattner24943d22010-06-08 16:52:24 +0000334
335const char *
336SBDebugger::GetVersionString ()
337{
338 return lldb_private::GetVersion();
339}
340
341const char *
342SBDebugger::StateAsCString (lldb::StateType state)
343{
344 return lldb_private::StateAsCString (state);
345}
346
347bool
348SBDebugger::StateIsRunningState (lldb::StateType state)
349{
350 return lldb_private::StateIsRunningState (state);
351}
352
353bool
354SBDebugger::StateIsStoppedState (lldb::StateType state)
355{
356 return lldb_private::StateIsStoppedState (state);
357}
358
359
360SBTarget
361SBDebugger::CreateTargetWithFileAndTargetTriple (const char *filename,
362 const char *target_triple)
363{
Greg Clayton63094e02010-06-23 01:19:29 +0000364 SBTarget target;
365 if (m_opaque_sp)
366 {
367 ArchSpec arch;
368 FileSpec file_spec (filename);
369 arch.SetArchFromTargetTriple(target_triple);
370 TargetSP target_sp;
371 Error error (m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file_spec, arch, NULL, true, target_sp));
372 target.reset (target_sp);
373 }
Chris Lattner24943d22010-06-08 16:52:24 +0000374 return target;
375}
376
377SBTarget
378SBDebugger::CreateTargetWithFileAndArch (const char *filename, const char *archname)
379{
Greg Clayton63094e02010-06-23 01:19:29 +0000380 SBTarget target;
381 if (m_opaque_sp)
382 {
383 FileSpec file (filename);
384 ArchSpec arch = lldb_private::GetDefaultArchitecture();
385 TargetSP target_sp;
386 Error error;
Chris Lattner24943d22010-06-08 16:52:24 +0000387
Greg Clayton63094e02010-06-23 01:19:29 +0000388 if (archname != NULL)
389 {
390 ArchSpec arch2 (archname);
391 error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch2, NULL, true, target_sp);
392 }
393 else
394 {
395 if (!arch.IsValid())
396 arch = LLDB_ARCH_DEFAULT;
397
398 error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, NULL, true, target_sp);
399
400 if (error.Fail())
401 {
402 if (arch == LLDB_ARCH_DEFAULT_32BIT)
403 arch = LLDB_ARCH_DEFAULT_64BIT;
404 else
405 arch = LLDB_ARCH_DEFAULT_32BIT;
406
407 error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, NULL, true, target_sp);
408 }
409 }
410
411 if (error.Success())
412 {
413 m_opaque_sp->GetTargetList().SetCurrentTarget (target_sp.get());
414 target.reset(target_sp);
415 }
Chris Lattner24943d22010-06-08 16:52:24 +0000416 }
Greg Clayton63094e02010-06-23 01:19:29 +0000417 return target;
418}
419
420SBTarget
421SBDebugger::CreateTarget (const char *filename)
422{
423 SBTarget target;
424 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000425 {
Greg Clayton63094e02010-06-23 01:19:29 +0000426 FileSpec file (filename);
427 ArchSpec arch = lldb_private::GetDefaultArchitecture();
428 TargetSP target_sp;
429 Error error;
430
Chris Lattner24943d22010-06-08 16:52:24 +0000431 if (!arch.IsValid())
432 arch = LLDB_ARCH_DEFAULT;
433
Greg Clayton63094e02010-06-23 01:19:29 +0000434 error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, NULL, true, target_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000435
436 if (error.Fail())
437 {
438 if (arch == LLDB_ARCH_DEFAULT_32BIT)
439 arch = LLDB_ARCH_DEFAULT_64BIT;
440 else
441 arch = LLDB_ARCH_DEFAULT_32BIT;
442
Greg Clayton63094e02010-06-23 01:19:29 +0000443 error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, NULL, true, target_sp);
444 }
445
446 if (error.Success())
447 {
448 m_opaque_sp->GetTargetList().SetCurrentTarget (target_sp.get());
449 target.reset (target_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000450 }
451 }
Greg Clayton63094e02010-06-23 01:19:29 +0000452 return target;
Chris Lattner24943d22010-06-08 16:52:24 +0000453}
454
455SBTarget
456SBDebugger::GetTargetAtIndex (uint32_t idx)
457{
Greg Clayton63094e02010-06-23 01:19:29 +0000458 SBTarget sb_target;
459 if (m_opaque_sp)
460 sb_target.reset(m_opaque_sp->GetTargetList().GetTargetAtIndex (idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000461 return sb_target;
462}
463
464SBTarget
465SBDebugger::FindTargetWithProcessID (pid_t pid)
466{
Greg Clayton63094e02010-06-23 01:19:29 +0000467 SBTarget sb_target;
468 if (m_opaque_sp)
469 sb_target.reset(m_opaque_sp->GetTargetList().FindTargetWithProcessID (pid));
Chris Lattner24943d22010-06-08 16:52:24 +0000470 return sb_target;
471}
472
473SBTarget
474SBDebugger::FindTargetWithFileAndArch (const char *filename, const char *arch_name)
475{
Greg Clayton63094e02010-06-23 01:19:29 +0000476 SBTarget sb_target;
477 if (m_opaque_sp && filename && filename[0])
478 {
479 ArchSpec arch;
480 if (arch_name)
481 arch.SetArch(arch_name);
482 TargetSP target_sp (m_opaque_sp->GetTargetList().FindTargetWithExecutableAndArchitecture (FileSpec(filename), arch_name ? &arch : NULL));
483 sb_target.reset(target_sp);
484 }
485 return sb_target;
Chris Lattner24943d22010-06-08 16:52:24 +0000486}
487
488SBTarget
489SBDebugger::FindTargetWithLLDBProcess (const lldb::ProcessSP &process_sp)
490{
Greg Clayton63094e02010-06-23 01:19:29 +0000491 SBTarget sb_target;
492 if (m_opaque_sp)
493 sb_target.reset(m_opaque_sp->GetTargetList().FindTargetWithProcess (process_sp.get()));
Chris Lattner24943d22010-06-08 16:52:24 +0000494 return sb_target;
495}
496
497
498uint32_t
499SBDebugger::GetNumTargets ()
500{
Greg Clayton63094e02010-06-23 01:19:29 +0000501 if (m_opaque_sp)
502 return m_opaque_sp->GetTargetList().GetNumTargets ();
503 return 0;
504}
Chris Lattner24943d22010-06-08 16:52:24 +0000505
506SBTarget
507SBDebugger::GetCurrentTarget ()
508{
Greg Clayton63094e02010-06-23 01:19:29 +0000509 SBTarget sb_target;
510 if (m_opaque_sp)
511 sb_target.reset(m_opaque_sp->GetTargetList().GetCurrentTarget ());
Chris Lattner24943d22010-06-08 16:52:24 +0000512 return sb_target;
513}
514
515void
516SBDebugger::DispatchInput (void *baton, const void *data, size_t data_len)
517{
Greg Clayton63094e02010-06-23 01:19:29 +0000518 if (m_opaque_sp)
519 m_opaque_sp->DispatchInput ((const char *) data, data_len);
Chris Lattner24943d22010-06-08 16:52:24 +0000520}
521
522void
523SBDebugger::PushInputReader (SBInputReader &reader)
524{
Greg Clayton63094e02010-06-23 01:19:29 +0000525 if (m_opaque_sp && reader.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000526 {
527 InputReaderSP reader_sp(*reader);
Greg Clayton63094e02010-06-23 01:19:29 +0000528 m_opaque_sp->PushInputReader (reader_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000529 }
530}
Greg Clayton63094e02010-06-23 01:19:29 +0000531
532void
533SBDebugger::reset (const lldb::DebuggerSP &debugger_sp)
534{
535 m_opaque_sp = debugger_sp;
536}
537
538Debugger *
539SBDebugger::get () const
540{
541 return m_opaque_sp.get();
542}
543
544Debugger &
545SBDebugger::ref () const
546{
547 assert (m_opaque_sp.get());
548 return *m_opaque_sp;
549}
550
551