blob: 84856ef988b41f95dfaf81f7c60d957d9f543a95 [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
Greg Clayton63094e02010-06-23 01:19:29 +000054SBDebugger::SBDebugger () :
55 m_opaque_sp ()
56{
57}
58
59SBDebugger::~SBDebugger ()
60{
61}
62
63bool
64SBDebugger::IsValid() const
65{
66 return m_opaque_sp.get() != NULL;
67}
68
69
Chris Lattner24943d22010-06-08 16:52:24 +000070void
71SBDebugger::SetAsync (bool b)
72{
Greg Clayton63094e02010-06-23 01:19:29 +000073 if (m_opaque_sp)
74 m_opaque_sp->SetAsyncExecution(b);
Chris Lattner24943d22010-06-08 16:52:24 +000075}
76
Chris Lattner24943d22010-06-08 16:52:24 +000077// Shouldn't really be settable after initialization as this could cause lots of problems; don't want users
78// trying to switch modes in the middle of a debugging session.
79void
80SBDebugger::SetInputFileHandle (FILE *fh, bool transfer_ownership)
81{
Greg Clayton63094e02010-06-23 01:19:29 +000082 if (m_opaque_sp)
83 m_opaque_sp->SetInputFileHandle (fh, transfer_ownership);
Chris Lattner24943d22010-06-08 16:52:24 +000084}
85
86void
87SBDebugger::SetOutputFileHandle (FILE *fh, bool transfer_ownership)
88{
Greg Clayton63094e02010-06-23 01:19:29 +000089 if (m_opaque_sp)
90 m_opaque_sp->SetOutputFileHandle (fh, transfer_ownership);
Chris Lattner24943d22010-06-08 16:52:24 +000091}
92
93void
94SBDebugger::SetErrorFileHandle (FILE *fh, bool transfer_ownership)
95{
Greg Clayton63094e02010-06-23 01:19:29 +000096 if (m_opaque_sp)
97 m_opaque_sp->SetErrorFileHandle (fh, transfer_ownership);
Chris Lattner24943d22010-06-08 16:52:24 +000098}
99
100FILE *
101SBDebugger::GetInputFileHandle ()
102{
Greg Clayton63094e02010-06-23 01:19:29 +0000103 if (m_opaque_sp)
104 return m_opaque_sp->GetInputFileHandle();
105 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000106}
107
108FILE *
109SBDebugger::GetOutputFileHandle ()
110{
Greg Clayton63094e02010-06-23 01:19:29 +0000111 if (m_opaque_sp)
112 return m_opaque_sp->GetOutputFileHandle();
113 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000114}
115
116FILE *
117SBDebugger::GetErrorFileHandle ()
118{
Greg Clayton63094e02010-06-23 01:19:29 +0000119 if (m_opaque_sp)
120 return m_opaque_sp->GetErrorFileHandle();
121 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000122}
123
124SBCommandInterpreter
125SBDebugger::GetCommandInterpreter ()
126{
Greg Clayton63094e02010-06-23 01:19:29 +0000127 SBCommandInterpreter sb_interpreter;
128 if (m_opaque_sp)
129 sb_interpreter.reset (&m_opaque_sp->GetCommandInterpreter());
Chris Lattner24943d22010-06-08 16:52:24 +0000130 return sb_interpreter;
131}
132
133void
134SBDebugger::HandleCommand (const char *command)
135{
Greg Clayton63094e02010-06-23 01:19:29 +0000136 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000137 {
Greg Clayton63094e02010-06-23 01:19:29 +0000138 SBCommandInterpreter sb_interpreter(GetCommandInterpreter ());
139 SBCommandReturnObject result;
140
141 sb_interpreter.HandleCommand (command, result, false);
142
143 if (GetErrorFileHandle() != NULL)
144 result.PutError (GetErrorFileHandle());
145 if (GetOutputFileHandle() != NULL)
146 result.PutOutput (GetOutputFileHandle());
147
148 if (m_opaque_sp->GetAsyncExecution() == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000149 {
Greg Clayton63094e02010-06-23 01:19:29 +0000150 SBProcess process(GetCommandInterpreter().GetProcess ());
151 if (process.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000152 {
Greg Clayton63094e02010-06-23 01:19:29 +0000153 EventSP event_sp;
154 Listener &lldb_listener = m_opaque_sp->GetListener();
155 while (lldb_listener.GetNextEventForBroadcaster (process.get(), event_sp))
156 {
157 SBEvent event(event_sp);
158 HandleProcessEvent (process, event, GetOutputFileHandle(), GetErrorFileHandle());
159 }
Chris Lattner24943d22010-06-08 16:52:24 +0000160 }
161 }
162 }
163}
164
165SBListener
166SBDebugger::GetListener ()
167{
Greg Clayton63094e02010-06-23 01:19:29 +0000168 SBListener sb_listener;
169 if (m_opaque_sp)
170 sb_listener.reset(&m_opaque_sp->GetListener(), false);
Chris Lattner24943d22010-06-08 16:52:24 +0000171 return sb_listener;
172}
173
174void
175SBDebugger::HandleProcessEvent (const SBProcess &process, const SBEvent &event, FILE *out, FILE *err)
176{
177 const uint32_t event_type = event.GetType();
178 char stdio_buffer[1024];
179 size_t len;
180
181 if (event_type & Process::eBroadcastBitSTDOUT)
182 {
183 while ((len = process.GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
184 if (out != NULL)
185 ::fwrite (stdio_buffer, 1, len, out);
186 }
187 else if (event_type & Process::eBroadcastBitSTDERR)
188 {
189 while ((len = process.GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
190 if (out != NULL)
191 ::fwrite (stdio_buffer, 1, len, out);
192 }
193 else if (event_type & Process::eBroadcastBitStateChanged)
194 {
195 // Drain any stdout messages.
196 while ((len = process.GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
197 if (out != NULL)
198 ::fwrite (stdio_buffer, 1, len, out);
199
200 // Drain any stderr messages.
201 while ((len = process.GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
202 if (out != NULL)
203 ::fwrite (stdio_buffer, 1, len, out);
204
205 StateType event_state = SBProcess::GetStateFromEvent (event);
206
207 if (event_state == eStateInvalid)
208 return;
209
210 bool is_stopped = StateIsStoppedState (event_state);
211 if (!is_stopped)
212 process.ReportCurrentState (event, out);
213 }
214}
215
216void
217SBDebugger::UpdateCurrentThread (SBProcess &process)
218{
219 if (process.IsValid())
220 {
221 SBThread curr_thread = process.GetCurrentThread ();
222 SBThread thread;
223 StopReason curr_thread_stop_reason = eStopReasonInvalid;
224 if (curr_thread.IsValid())
225 {
226 if (curr_thread.GetStopReason() != eStopReasonInvalid)
227 curr_thread_stop_reason = curr_thread.GetStopReason ();
228 }
229
230 if (! curr_thread.IsValid()
231 || curr_thread_stop_reason == eStopReasonInvalid
232 || curr_thread_stop_reason == eStopReasonNone)
233 {
234 // Prefer a thread that has just completed its plan over another thread as current thread.
235 SBThread plan_thread;
236 SBThread other_thread;
237 const size_t num_threads = process.GetNumThreads ();
238 size_t i;
239 for (i = 0; i < num_threads; ++i)
240 {
241 thread = process.GetThreadAtIndex(i);
242 if (thread.GetStopReason () != eStopReasonInvalid)
243 {
244 switch (thread.GetStopReason ())
245 {
246 default:
247 case eStopReasonInvalid:
248 case eStopReasonNone:
249 break;
250
251 case eStopReasonTrace:
252 case eStopReasonBreakpoint:
253 case eStopReasonWatchpoint:
254 case eStopReasonSignal:
255 case eStopReasonException:
256 if (! other_thread.IsValid())
257 other_thread = thread;
258 break;
259 case eStopReasonPlanComplete:
260 if (! plan_thread.IsValid())
261 plan_thread = thread;
262 break;
263 }
264 }
265 }
266 if (plan_thread.IsValid())
267 process.SetCurrentThreadByID (plan_thread.GetThreadID());
268 else if (other_thread.IsValid())
269 process.SetCurrentThreadByID (other_thread.GetThreadID());
270 else
271 {
272 if (curr_thread.IsValid())
273 thread = curr_thread;
274 else
275 thread = process.GetThreadAtIndex(0);
276
277 if (thread.IsValid())
278 process.SetCurrentThreadByID (thread.GetThreadID());
279 }
280 }
281 }
282}
283
Chris Lattner24943d22010-06-08 16:52:24 +0000284SBSourceManager &
285SBDebugger::GetSourceManager ()
286{
287 static SourceManager g_lldb_source_manager;
288 static SBSourceManager g_sb_source_manager (g_lldb_source_manager);
289 return g_sb_source_manager;
290}
291
292
293bool
294SBDebugger::GetDefaultArchitecture (char *arch_name, size_t arch_name_len)
295{
296 if (arch_name && arch_name_len)
297 {
298 ArchSpec &default_arch = lldb_private::GetDefaultArchitecture ();
299 if (default_arch.IsValid())
300 {
301 ::snprintf (arch_name, arch_name_len, "%s", default_arch.AsCString());
302 return true;
303 }
304 }
305 if (arch_name && arch_name_len)
306 arch_name[0] = '\0';
307 return false;
308}
309
310
311bool
312SBDebugger::SetDefaultArchitecture (const char *arch_name)
313{
314 if (arch_name)
315 {
316 ArchSpec arch (arch_name);
317 if (arch.IsValid())
318 {
319 lldb_private::GetDefaultArchitecture () = arch;
320 return true;
321 }
322 }
323 return false;
324}
325
326ScriptLanguage
327SBDebugger::GetScriptingLanguage (const char *script_language_name)
328{
329 return Args::StringToScriptLanguage (script_language_name,
330 eScriptLanguageDefault,
331 NULL);
332}
Chris Lattner24943d22010-06-08 16:52:24 +0000333
334const char *
335SBDebugger::GetVersionString ()
336{
337 return lldb_private::GetVersion();
338}
339
340const char *
341SBDebugger::StateAsCString (lldb::StateType state)
342{
343 return lldb_private::StateAsCString (state);
344}
345
346bool
347SBDebugger::StateIsRunningState (lldb::StateType state)
348{
349 return lldb_private::StateIsRunningState (state);
350}
351
352bool
353SBDebugger::StateIsStoppedState (lldb::StateType state)
354{
355 return lldb_private::StateIsStoppedState (state);
356}
357
358
359SBTarget
360SBDebugger::CreateTargetWithFileAndTargetTriple (const char *filename,
361 const char *target_triple)
362{
Greg Clayton63094e02010-06-23 01:19:29 +0000363 SBTarget target;
364 if (m_opaque_sp)
365 {
366 ArchSpec arch;
367 FileSpec file_spec (filename);
368 arch.SetArchFromTargetTriple(target_triple);
369 TargetSP target_sp;
370 Error error (m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file_spec, arch, NULL, true, target_sp));
371 target.reset (target_sp);
372 }
Chris Lattner24943d22010-06-08 16:52:24 +0000373 return target;
374}
375
376SBTarget
377SBDebugger::CreateTargetWithFileAndArch (const char *filename, const char *archname)
378{
Greg Clayton63094e02010-06-23 01:19:29 +0000379 SBTarget target;
380 if (m_opaque_sp)
381 {
382 FileSpec file (filename);
383 ArchSpec arch = lldb_private::GetDefaultArchitecture();
384 TargetSP target_sp;
385 Error error;
Chris Lattner24943d22010-06-08 16:52:24 +0000386
Greg Clayton63094e02010-06-23 01:19:29 +0000387 if (archname != NULL)
388 {
389 ArchSpec arch2 (archname);
390 error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch2, NULL, true, target_sp);
391 }
392 else
393 {
394 if (!arch.IsValid())
395 arch = LLDB_ARCH_DEFAULT;
396
397 error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, NULL, true, target_sp);
398
399 if (error.Fail())
400 {
401 if (arch == LLDB_ARCH_DEFAULT_32BIT)
402 arch = LLDB_ARCH_DEFAULT_64BIT;
403 else
404 arch = LLDB_ARCH_DEFAULT_32BIT;
405
406 error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, NULL, true, target_sp);
407 }
408 }
409
410 if (error.Success())
411 {
412 m_opaque_sp->GetTargetList().SetCurrentTarget (target_sp.get());
413 target.reset(target_sp);
414 }
Chris Lattner24943d22010-06-08 16:52:24 +0000415 }
Greg Clayton63094e02010-06-23 01:19:29 +0000416 return target;
417}
418
419SBTarget
420SBDebugger::CreateTarget (const char *filename)
421{
422 SBTarget target;
423 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000424 {
Greg Clayton63094e02010-06-23 01:19:29 +0000425 FileSpec file (filename);
426 ArchSpec arch = lldb_private::GetDefaultArchitecture();
427 TargetSP target_sp;
428 Error error;
429
Chris Lattner24943d22010-06-08 16:52:24 +0000430 if (!arch.IsValid())
431 arch = LLDB_ARCH_DEFAULT;
432
Greg Clayton63094e02010-06-23 01:19:29 +0000433 error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, NULL, true, target_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000434
435 if (error.Fail())
436 {
437 if (arch == LLDB_ARCH_DEFAULT_32BIT)
438 arch = LLDB_ARCH_DEFAULT_64BIT;
439 else
440 arch = LLDB_ARCH_DEFAULT_32BIT;
441
Greg Clayton63094e02010-06-23 01:19:29 +0000442 error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, NULL, true, target_sp);
443 }
444
445 if (error.Success())
446 {
447 m_opaque_sp->GetTargetList().SetCurrentTarget (target_sp.get());
448 target.reset (target_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000449 }
450 }
Greg Clayton63094e02010-06-23 01:19:29 +0000451 return target;
Chris Lattner24943d22010-06-08 16:52:24 +0000452}
453
454SBTarget
455SBDebugger::GetTargetAtIndex (uint32_t idx)
456{
Greg Clayton63094e02010-06-23 01:19:29 +0000457 SBTarget sb_target;
458 if (m_opaque_sp)
459 sb_target.reset(m_opaque_sp->GetTargetList().GetTargetAtIndex (idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000460 return sb_target;
461}
462
463SBTarget
464SBDebugger::FindTargetWithProcessID (pid_t pid)
465{
Greg Clayton63094e02010-06-23 01:19:29 +0000466 SBTarget sb_target;
467 if (m_opaque_sp)
468 sb_target.reset(m_opaque_sp->GetTargetList().FindTargetWithProcessID (pid));
Chris Lattner24943d22010-06-08 16:52:24 +0000469 return sb_target;
470}
471
472SBTarget
473SBDebugger::FindTargetWithFileAndArch (const char *filename, const char *arch_name)
474{
Greg Clayton63094e02010-06-23 01:19:29 +0000475 SBTarget sb_target;
476 if (m_opaque_sp && filename && filename[0])
477 {
478 ArchSpec arch;
479 if (arch_name)
480 arch.SetArch(arch_name);
481 TargetSP target_sp (m_opaque_sp->GetTargetList().FindTargetWithExecutableAndArchitecture (FileSpec(filename), arch_name ? &arch : NULL));
482 sb_target.reset(target_sp);
483 }
484 return sb_target;
Chris Lattner24943d22010-06-08 16:52:24 +0000485}
486
487SBTarget
488SBDebugger::FindTargetWithLLDBProcess (const lldb::ProcessSP &process_sp)
489{
Greg Clayton63094e02010-06-23 01:19:29 +0000490 SBTarget sb_target;
491 if (m_opaque_sp)
492 sb_target.reset(m_opaque_sp->GetTargetList().FindTargetWithProcess (process_sp.get()));
Chris Lattner24943d22010-06-08 16:52:24 +0000493 return sb_target;
494}
495
496
497uint32_t
498SBDebugger::GetNumTargets ()
499{
Greg Clayton63094e02010-06-23 01:19:29 +0000500 if (m_opaque_sp)
501 return m_opaque_sp->GetTargetList().GetNumTargets ();
502 return 0;
503}
Chris Lattner24943d22010-06-08 16:52:24 +0000504
505SBTarget
506SBDebugger::GetCurrentTarget ()
507{
Greg Clayton63094e02010-06-23 01:19:29 +0000508 SBTarget sb_target;
509 if (m_opaque_sp)
510 sb_target.reset(m_opaque_sp->GetTargetList().GetCurrentTarget ());
Chris Lattner24943d22010-06-08 16:52:24 +0000511 return sb_target;
512}
513
514void
515SBDebugger::DispatchInput (void *baton, const void *data, size_t data_len)
516{
Greg Clayton63094e02010-06-23 01:19:29 +0000517 if (m_opaque_sp)
518 m_opaque_sp->DispatchInput ((const char *) data, data_len);
Chris Lattner24943d22010-06-08 16:52:24 +0000519}
520
521void
522SBDebugger::PushInputReader (SBInputReader &reader)
523{
Greg Clayton63094e02010-06-23 01:19:29 +0000524 if (m_opaque_sp && reader.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000525 {
526 InputReaderSP reader_sp(*reader);
Greg Clayton63094e02010-06-23 01:19:29 +0000527 m_opaque_sp->PushInputReader (reader_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000528 }
529}
Greg Clayton63094e02010-06-23 01:19:29 +0000530
531void
532SBDebugger::reset (const lldb::DebuggerSP &debugger_sp)
533{
534 m_opaque_sp = debugger_sp;
535}
536
537Debugger *
538SBDebugger::get () const
539{
540 return m_opaque_sp.get();
541}
542
543Debugger &
544SBDebugger::ref () const
545{
546 assert (m_opaque_sp.get());
547 return *m_opaque_sp;
548}
549
550
Caroline Tice558be582010-06-30 16:22:25 +0000551SBDebugger
552SBDebugger::FindDebuggerWithID (int id)
553{
554 SBDebugger sb_debugger;
555 lldb::DebuggerSP debugger_sp = Debugger::FindDebuggerWithID (id);
556 if (debugger_sp)
557 sb_debugger.reset (debugger_sp);
558 return sb_debugger;
559}