1 | //===-- SBDebugger.cpp ----------------------------------------------------===// |
---|---|
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "lldb/API/SBDebugger.h" |
10 | #include "SystemInitializerFull.h" |
11 | #include "lldb/Utility/Instrumentation.h" |
12 | #include "lldb/Utility/LLDBLog.h" |
13 | |
14 | #include "lldb/API/SBBroadcaster.h" |
15 | #include "lldb/API/SBCommandInterpreter.h" |
16 | #include "lldb/API/SBCommandInterpreterRunOptions.h" |
17 | #include "lldb/API/SBCommandReturnObject.h" |
18 | #include "lldb/API/SBError.h" |
19 | #include "lldb/API/SBEvent.h" |
20 | #include "lldb/API/SBFile.h" |
21 | #include "lldb/API/SBFrame.h" |
22 | #include "lldb/API/SBListener.h" |
23 | #include "lldb/API/SBProcess.h" |
24 | #include "lldb/API/SBSourceManager.h" |
25 | #include "lldb/API/SBStream.h" |
26 | #include "lldb/API/SBStringList.h" |
27 | #include "lldb/API/SBStructuredData.h" |
28 | #include "lldb/API/SBTarget.h" |
29 | #include "lldb/API/SBThread.h" |
30 | #include "lldb/API/SBTrace.h" |
31 | #include "lldb/API/SBTypeCategory.h" |
32 | #include "lldb/API/SBTypeFilter.h" |
33 | #include "lldb/API/SBTypeFormat.h" |
34 | #include "lldb/API/SBTypeNameSpecifier.h" |
35 | #include "lldb/API/SBTypeSummary.h" |
36 | #include "lldb/API/SBTypeSynthetic.h" |
37 | |
38 | #include "lldb/Core/Debugger.h" |
39 | #include "lldb/Core/DebuggerEvents.h" |
40 | #include "lldb/Core/PluginManager.h" |
41 | #include "lldb/Core/Progress.h" |
42 | #include "lldb/Core/StructuredDataImpl.h" |
43 | #include "lldb/DataFormatters/DataVisualization.h" |
44 | #include "lldb/Host/Config.h" |
45 | #include "lldb/Host/StreamFile.h" |
46 | #include "lldb/Host/XML.h" |
47 | #include "lldb/Initialization/SystemLifetimeManager.h" |
48 | #include "lldb/Interpreter/CommandInterpreter.h" |
49 | #include "lldb/Interpreter/OptionArgParser.h" |
50 | #include "lldb/Interpreter/OptionGroupPlatform.h" |
51 | #include "lldb/Target/Process.h" |
52 | #include "lldb/Target/TargetList.h" |
53 | #include "lldb/Utility/Args.h" |
54 | #include "lldb/Utility/Diagnostics.h" |
55 | #include "lldb/Utility/State.h" |
56 | #include "lldb/Version/Version.h" |
57 | |
58 | #include "llvm/ADT/STLExtras.h" |
59 | #include "llvm/ADT/StringRef.h" |
60 | #include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_CURL |
61 | #include "llvm/Support/DynamicLibrary.h" |
62 | #include "llvm/Support/ManagedStatic.h" |
63 | #include "llvm/Support/PrettyStackTrace.h" |
64 | #include "llvm/Support/Signals.h" |
65 | |
66 | using namespace lldb; |
67 | using namespace lldb_private; |
68 | |
69 | static llvm::ManagedStatic<SystemLifetimeManager> g_debugger_lifetime; |
70 | |
71 | SBError SBInputReader::Initialize( |
72 | lldb::SBDebugger &sb_debugger, |
73 | unsigned long (*callback)(void *, lldb::SBInputReader *, |
74 | lldb::InputReaderAction, char const *, |
75 | unsigned long), |
76 | void *a, lldb::InputReaderGranularity b, char const *c, char const *d, |
77 | bool e) { |
78 | LLDB_INSTRUMENT_VA(this, sb_debugger, callback, a, b, c, d, e); |
79 | |
80 | return SBError(); |
81 | } |
82 | |
83 | void SBInputReader::SetIsDone(bool b) { LLDB_INSTRUMENT_VA(this, b); } |
84 | |
85 | bool SBInputReader::IsActive() const { |
86 | LLDB_INSTRUMENT_VA(this); |
87 | |
88 | return false; |
89 | } |
90 | |
91 | SBDebugger::SBDebugger() { LLDB_INSTRUMENT_VA(this); } |
92 | |
93 | SBDebugger::SBDebugger(const lldb::DebuggerSP &debugger_sp) |
94 | : m_opaque_sp(debugger_sp) { |
95 | LLDB_INSTRUMENT_VA(this, debugger_sp); |
96 | } |
97 | |
98 | SBDebugger::SBDebugger(const SBDebugger &rhs) : m_opaque_sp(rhs.m_opaque_sp) { |
99 | LLDB_INSTRUMENT_VA(this, rhs); |
100 | } |
101 | |
102 | SBDebugger::~SBDebugger() = default; |
103 | |
104 | SBDebugger &SBDebugger::operator=(const SBDebugger &rhs) { |
105 | LLDB_INSTRUMENT_VA(this, rhs); |
106 | |
107 | if (this != &rhs) { |
108 | m_opaque_sp = rhs.m_opaque_sp; |
109 | } |
110 | return *this; |
111 | } |
112 | |
113 | const char *SBDebugger::GetBroadcasterClass() { |
114 | LLDB_INSTRUMENT(); |
115 | |
116 | return ConstString(Debugger::GetStaticBroadcasterClass()).AsCString(); |
117 | } |
118 | |
119 | const char *SBDebugger::GetProgressFromEvent(const lldb::SBEvent &event, |
120 | uint64_t &progress_id, |
121 | uint64_t &completed, |
122 | uint64_t &total, |
123 | bool &is_debugger_specific) { |
124 | LLDB_INSTRUMENT_VA(event); |
125 | |
126 | const ProgressEventData *progress_data = |
127 | ProgressEventData::GetEventDataFromEvent(event_ptr: event.get()); |
128 | if (progress_data == nullptr) |
129 | return nullptr; |
130 | progress_id = progress_data->GetID(); |
131 | completed = progress_data->GetCompleted(); |
132 | total = progress_data->GetTotal(); |
133 | is_debugger_specific = progress_data->IsDebuggerSpecific(); |
134 | ConstString message(progress_data->GetMessage()); |
135 | return message.AsCString(); |
136 | } |
137 | |
138 | lldb::SBStructuredData |
139 | SBDebugger::GetProgressDataFromEvent(const lldb::SBEvent &event) { |
140 | LLDB_INSTRUMENT_VA(event); |
141 | |
142 | StructuredData::DictionarySP dictionary_sp = |
143 | ProgressEventData::GetAsStructuredData(event_ptr: event.get()); |
144 | |
145 | if (!dictionary_sp) |
146 | return {}; |
147 | |
148 | SBStructuredData data; |
149 | data.m_impl_up->SetObjectSP(std::move(dictionary_sp)); |
150 | return data; |
151 | } |
152 | |
153 | lldb::SBStructuredData |
154 | SBDebugger::GetDiagnosticFromEvent(const lldb::SBEvent &event) { |
155 | LLDB_INSTRUMENT_VA(event); |
156 | |
157 | StructuredData::DictionarySP dictionary_sp = |
158 | DiagnosticEventData::GetAsStructuredData(event_ptr: event.get()); |
159 | |
160 | if (!dictionary_sp) |
161 | return {}; |
162 | |
163 | SBStructuredData data; |
164 | data.m_impl_up->SetObjectSP(std::move(dictionary_sp)); |
165 | return data; |
166 | } |
167 | |
168 | SBBroadcaster SBDebugger::GetBroadcaster() { |
169 | LLDB_INSTRUMENT_VA(this); |
170 | SBBroadcaster broadcaster(&m_opaque_sp->GetBroadcaster(), false); |
171 | return broadcaster; |
172 | } |
173 | |
174 | void SBDebugger::Initialize() { |
175 | LLDB_INSTRUMENT(); |
176 | SBError ignored = SBDebugger::InitializeWithErrorHandling(); |
177 | } |
178 | |
179 | lldb::SBError SBDebugger::InitializeWithErrorHandling() { |
180 | LLDB_INSTRUMENT(); |
181 | |
182 | SBError error; |
183 | if (auto e = g_debugger_lifetime->Initialize( |
184 | initializer: std::make_unique<SystemInitializerFull>())) { |
185 | error.SetError(Status::FromError(error: std::move(e))); |
186 | } |
187 | return error; |
188 | } |
189 | |
190 | void SBDebugger::PrintStackTraceOnError() { |
191 | LLDB_INSTRUMENT(); |
192 | |
193 | llvm::EnablePrettyStackTrace(); |
194 | static std::string executable = |
195 | llvm::sys::fs::getMainExecutable(argv0: nullptr, MainExecAddr: nullptr); |
196 | llvm::sys::PrintStackTraceOnErrorSignal(Argv0: executable); |
197 | } |
198 | |
199 | static void DumpDiagnostics(void *cookie) { |
200 | Diagnostics::Instance().Dump(stream&: llvm::errs()); |
201 | } |
202 | |
203 | void SBDebugger::PrintDiagnosticsOnError() { |
204 | LLDB_INSTRUMENT(); |
205 | |
206 | llvm::sys::AddSignalHandler(FnPtr: &DumpDiagnostics, Cookie: nullptr); |
207 | } |
208 | |
209 | void SBDebugger::Terminate() { |
210 | LLDB_INSTRUMENT(); |
211 | |
212 | g_debugger_lifetime->Terminate(); |
213 | } |
214 | |
215 | void SBDebugger::Clear() { |
216 | LLDB_INSTRUMENT_VA(this); |
217 | |
218 | if (m_opaque_sp) |
219 | m_opaque_sp->ClearIOHandlers(); |
220 | |
221 | m_opaque_sp.reset(); |
222 | } |
223 | |
224 | SBDebugger SBDebugger::Create() { |
225 | LLDB_INSTRUMENT(); |
226 | |
227 | return SBDebugger::Create(source_init_files: false, log_callback: nullptr, baton: nullptr); |
228 | } |
229 | |
230 | SBDebugger SBDebugger::Create(bool source_init_files) { |
231 | LLDB_INSTRUMENT_VA(source_init_files); |
232 | |
233 | return SBDebugger::Create(source_init_files, log_callback: nullptr, baton: nullptr); |
234 | } |
235 | |
236 | SBDebugger SBDebugger::Create(bool source_init_files, |
237 | lldb::LogOutputCallback callback, void *baton) |
238 | |
239 | { |
240 | LLDB_INSTRUMENT_VA(source_init_files, callback, baton); |
241 | |
242 | SBDebugger debugger; |
243 | |
244 | // Currently we have issues if this function is called simultaneously on two |
245 | // different threads. The issues mainly revolve around the fact that the |
246 | // lldb_private::FormatManager uses global collections and having two threads |
247 | // parsing the .lldbinit files can cause mayhem. So to get around this for |
248 | // now we need to use a mutex to prevent bad things from happening. |
249 | static std::recursive_mutex g_mutex; |
250 | std::lock_guard<std::recursive_mutex> guard(g_mutex); |
251 | |
252 | debugger.reset(debugger_sp: Debugger::CreateInstance(log_callback: callback, baton)); |
253 | |
254 | SBCommandInterpreter interp = debugger.GetCommandInterpreter(); |
255 | if (source_init_files) { |
256 | interp.get()->SkipLLDBInitFiles(skip_lldbinit_files: false); |
257 | interp.get()->SkipAppInitFiles(skip_app_init_files: false); |
258 | SBCommandReturnObject result; |
259 | interp.SourceInitFileInGlobalDirectory(result); |
260 | interp.SourceInitFileInHomeDirectory(result, is_repl: false); |
261 | } else { |
262 | interp.get()->SkipLLDBInitFiles(skip_lldbinit_files: true); |
263 | interp.get()->SkipAppInitFiles(skip_app_init_files: true); |
264 | } |
265 | return debugger; |
266 | } |
267 | |
268 | void SBDebugger::Destroy(SBDebugger &debugger) { |
269 | LLDB_INSTRUMENT_VA(debugger); |
270 | |
271 | Debugger::Destroy(debugger_sp&: debugger.m_opaque_sp); |
272 | |
273 | if (debugger.m_opaque_sp.get() != nullptr) |
274 | debugger.m_opaque_sp.reset(); |
275 | } |
276 | |
277 | void SBDebugger::MemoryPressureDetected() { |
278 | LLDB_INSTRUMENT(); |
279 | |
280 | // Since this function can be call asynchronously, we allow it to be non- |
281 | // mandatory. We have seen deadlocks with this function when called so we |
282 | // need to safeguard against this until we can determine what is causing the |
283 | // deadlocks. |
284 | |
285 | const bool mandatory = false; |
286 | |
287 | ModuleList::RemoveOrphanSharedModules(mandatory); |
288 | } |
289 | |
290 | bool SBDebugger::IsValid() const { |
291 | LLDB_INSTRUMENT_VA(this); |
292 | return this->operator bool(); |
293 | } |
294 | SBDebugger::operator bool() const { |
295 | LLDB_INSTRUMENT_VA(this); |
296 | |
297 | return m_opaque_sp.get() != nullptr; |
298 | } |
299 | |
300 | void SBDebugger::SetAsync(bool b) { |
301 | LLDB_INSTRUMENT_VA(this, b); |
302 | |
303 | if (m_opaque_sp) |
304 | m_opaque_sp->SetAsyncExecution(b); |
305 | } |
306 | |
307 | bool SBDebugger::GetAsync() { |
308 | LLDB_INSTRUMENT_VA(this); |
309 | |
310 | return (m_opaque_sp ? m_opaque_sp->GetAsyncExecution() : false); |
311 | } |
312 | |
313 | void SBDebugger::SkipLLDBInitFiles(bool b) { |
314 | LLDB_INSTRUMENT_VA(this, b); |
315 | |
316 | if (m_opaque_sp) |
317 | m_opaque_sp->GetCommandInterpreter().SkipLLDBInitFiles(skip_lldbinit_files: b); |
318 | } |
319 | |
320 | void SBDebugger::SkipAppInitFiles(bool b) { |
321 | LLDB_INSTRUMENT_VA(this, b); |
322 | |
323 | if (m_opaque_sp) |
324 | m_opaque_sp->GetCommandInterpreter().SkipAppInitFiles(skip_app_init_files: b); |
325 | } |
326 | |
327 | void SBDebugger::SetInputFileHandle(FILE *fh, bool transfer_ownership) { |
328 | LLDB_INSTRUMENT_VA(this, fh, transfer_ownership); |
329 | if (m_opaque_sp) |
330 | m_opaque_sp->SetInputFile( |
331 | (FileSP)std::make_shared<NativeFile>(args&: fh, args&: transfer_ownership)); |
332 | } |
333 | |
334 | SBError SBDebugger::SetInputString(const char *data) { |
335 | LLDB_INSTRUMENT_VA(this, data); |
336 | SBError sb_error; |
337 | if (data == nullptr) { |
338 | sb_error = Status::FromErrorString(str: "String data is null"); |
339 | return sb_error; |
340 | } |
341 | |
342 | size_t size = strlen(s: data); |
343 | if (size == 0) { |
344 | sb_error = Status::FromErrorString(str: "String data is empty"); |
345 | return sb_error; |
346 | } |
347 | |
348 | if (!m_opaque_sp) { |
349 | sb_error = Status::FromErrorString(str: "invalid debugger"); |
350 | return sb_error; |
351 | } |
352 | |
353 | sb_error.SetError(m_opaque_sp->SetInputString(data)); |
354 | return sb_error; |
355 | } |
356 | |
357 | // Shouldn't really be settable after initialization as this could cause lots |
358 | // of problems; don't want users trying to switch modes in the middle of a |
359 | // debugging session. |
360 | SBError SBDebugger::SetInputFile(SBFile file) { |
361 | LLDB_INSTRUMENT_VA(this, file); |
362 | |
363 | SBError error; |
364 | if (!m_opaque_sp) { |
365 | error.ref() = Status::FromErrorString(str: "invalid debugger"); |
366 | return error; |
367 | } |
368 | if (!file) { |
369 | error.ref() = Status::FromErrorString(str: "invalid file"); |
370 | return error; |
371 | } |
372 | m_opaque_sp->SetInputFile(file.m_opaque_sp); |
373 | return error; |
374 | } |
375 | |
376 | SBError SBDebugger::SetInputFile(FileSP file_sp) { |
377 | LLDB_INSTRUMENT_VA(this, file_sp); |
378 | return SetInputFile(SBFile(file_sp)); |
379 | } |
380 | |
381 | SBError SBDebugger::SetOutputFile(FileSP file_sp) { |
382 | LLDB_INSTRUMENT_VA(this, file_sp); |
383 | return SetOutputFile(SBFile(file_sp)); |
384 | } |
385 | |
386 | void SBDebugger::SetOutputFileHandle(FILE *fh, bool transfer_ownership) { |
387 | LLDB_INSTRUMENT_VA(this, fh, transfer_ownership); |
388 | SetOutputFile((FileSP)std::make_shared<NativeFile>(args&: fh, args&: transfer_ownership)); |
389 | } |
390 | |
391 | SBError SBDebugger::SetOutputFile(SBFile file) { |
392 | LLDB_INSTRUMENT_VA(this, file); |
393 | SBError error; |
394 | if (!m_opaque_sp) { |
395 | error.ref() = Status::FromErrorString(str: "invalid debugger"); |
396 | return error; |
397 | } |
398 | if (!file) { |
399 | error.ref() = Status::FromErrorString(str: "invalid file"); |
400 | return error; |
401 | } |
402 | m_opaque_sp->SetOutputFile(file.m_opaque_sp); |
403 | return error; |
404 | } |
405 | |
406 | void SBDebugger::SetErrorFileHandle(FILE *fh, bool transfer_ownership) { |
407 | LLDB_INSTRUMENT_VA(this, fh, transfer_ownership); |
408 | SetErrorFile((FileSP)std::make_shared<NativeFile>(args&: fh, args&: transfer_ownership)); |
409 | } |
410 | |
411 | SBError SBDebugger::SetErrorFile(FileSP file_sp) { |
412 | LLDB_INSTRUMENT_VA(this, file_sp); |
413 | return SetErrorFile(SBFile(file_sp)); |
414 | } |
415 | |
416 | SBError SBDebugger::SetErrorFile(SBFile file) { |
417 | LLDB_INSTRUMENT_VA(this, file); |
418 | SBError error; |
419 | if (!m_opaque_sp) { |
420 | error.ref() = Status::FromErrorString(str: "invalid debugger"); |
421 | return error; |
422 | } |
423 | if (!file) { |
424 | error.ref() = Status::FromErrorString(str: "invalid file"); |
425 | return error; |
426 | } |
427 | m_opaque_sp->SetErrorFile(file.m_opaque_sp); |
428 | return error; |
429 | } |
430 | |
431 | lldb::SBStructuredData SBDebugger::GetSetting(const char *setting) { |
432 | LLDB_INSTRUMENT_VA(this, setting); |
433 | |
434 | SBStructuredData data; |
435 | if (!m_opaque_sp) |
436 | return data; |
437 | |
438 | StreamString json_strm; |
439 | ExecutionContext exe_ctx( |
440 | m_opaque_sp->GetCommandInterpreter().GetExecutionContext()); |
441 | if (setting && strlen(s: setting) > 0) |
442 | m_opaque_sp->DumpPropertyValue(exe_ctx: &exe_ctx, strm&: json_strm, property_path: setting, |
443 | /*dump_mask*/ 0, |
444 | /*is_json*/ true); |
445 | else |
446 | m_opaque_sp->DumpAllPropertyValues(exe_ctx: &exe_ctx, strm&: json_strm, /*dump_mask*/ 0, |
447 | /*is_json*/ true); |
448 | |
449 | data.m_impl_up->SetObjectSP(StructuredData::ParseJSON(json_text: json_strm.GetString())); |
450 | return data; |
451 | } |
452 | |
453 | FILE *SBDebugger::GetInputFileHandle() { |
454 | LLDB_INSTRUMENT_VA(this); |
455 | if (m_opaque_sp) { |
456 | File &file_sp = m_opaque_sp->GetInputFile(); |
457 | return file_sp.GetStream(); |
458 | } |
459 | return nullptr; |
460 | } |
461 | |
462 | SBFile SBDebugger::GetInputFile() { |
463 | LLDB_INSTRUMENT_VA(this); |
464 | if (m_opaque_sp) { |
465 | return SBFile(m_opaque_sp->GetInputFileSP()); |
466 | } |
467 | return SBFile(); |
468 | } |
469 | |
470 | FILE *SBDebugger::GetOutputFileHandle() { |
471 | LLDB_INSTRUMENT_VA(this); |
472 | if (m_opaque_sp) |
473 | return m_opaque_sp->GetOutputFileSP()->GetStream(); |
474 | return nullptr; |
475 | } |
476 | |
477 | SBFile SBDebugger::GetOutputFile() { |
478 | LLDB_INSTRUMENT_VA(this); |
479 | if (m_opaque_sp) |
480 | return SBFile(m_opaque_sp->GetOutputFileSP()); |
481 | return SBFile(); |
482 | } |
483 | |
484 | FILE *SBDebugger::GetErrorFileHandle() { |
485 | LLDB_INSTRUMENT_VA(this); |
486 | |
487 | if (m_opaque_sp) |
488 | return m_opaque_sp->GetErrorFileSP()->GetStream(); |
489 | return nullptr; |
490 | } |
491 | |
492 | SBFile SBDebugger::GetErrorFile() { |
493 | LLDB_INSTRUMENT_VA(this); |
494 | SBFile file; |
495 | if (m_opaque_sp) |
496 | return SBFile(m_opaque_sp->GetErrorFileSP()); |
497 | return SBFile(); |
498 | } |
499 | |
500 | void SBDebugger::SaveInputTerminalState() { |
501 | LLDB_INSTRUMENT_VA(this); |
502 | |
503 | if (m_opaque_sp) |
504 | m_opaque_sp->SaveInputTerminalState(); |
505 | } |
506 | |
507 | void SBDebugger::RestoreInputTerminalState() { |
508 | LLDB_INSTRUMENT_VA(this); |
509 | |
510 | if (m_opaque_sp) |
511 | m_opaque_sp->RestoreInputTerminalState(); |
512 | } |
513 | SBCommandInterpreter SBDebugger::GetCommandInterpreter() { |
514 | LLDB_INSTRUMENT_VA(this); |
515 | |
516 | SBCommandInterpreter sb_interpreter; |
517 | if (m_opaque_sp) |
518 | sb_interpreter.reset(&m_opaque_sp->GetCommandInterpreter()); |
519 | |
520 | return sb_interpreter; |
521 | } |
522 | |
523 | void SBDebugger::HandleCommand(const char *command) { |
524 | LLDB_INSTRUMENT_VA(this, command); |
525 | |
526 | if (m_opaque_sp) { |
527 | TargetSP target_sp(m_opaque_sp->GetSelectedTarget()); |
528 | std::unique_lock<std::recursive_mutex> lock; |
529 | if (target_sp) |
530 | lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); |
531 | |
532 | SBCommandInterpreter sb_interpreter(GetCommandInterpreter()); |
533 | SBCommandReturnObject result; |
534 | |
535 | sb_interpreter.HandleCommand(command_line: command, result, add_to_history: false); |
536 | |
537 | result.PutError(BORROWED: m_opaque_sp->GetErrorFileSP()); |
538 | result.PutOutput(BORROWED: m_opaque_sp->GetOutputFileSP()); |
539 | |
540 | if (!m_opaque_sp->GetAsyncExecution()) { |
541 | SBProcess process(GetCommandInterpreter().GetProcess()); |
542 | ProcessSP process_sp(process.GetSP()); |
543 | if (process_sp) { |
544 | EventSP event_sp; |
545 | ListenerSP lldb_listener_sp = m_opaque_sp->GetListener(); |
546 | while (lldb_listener_sp->GetEventForBroadcaster( |
547 | broadcaster: process_sp.get(), event_sp, timeout: std::chrono::seconds(0))) { |
548 | SBEvent event(event_sp); |
549 | HandleProcessEvent(process, event, out: GetOutputFile(), err: GetErrorFile()); |
550 | } |
551 | } |
552 | } |
553 | } |
554 | } |
555 | |
556 | SBListener SBDebugger::GetListener() { |
557 | LLDB_INSTRUMENT_VA(this); |
558 | |
559 | SBListener sb_listener; |
560 | if (m_opaque_sp) |
561 | sb_listener.reset(listener_sp: m_opaque_sp->GetListener()); |
562 | |
563 | return sb_listener; |
564 | } |
565 | |
566 | void SBDebugger::HandleProcessEvent(const SBProcess &process, |
567 | const SBEvent &event, SBFile out, |
568 | SBFile err) { |
569 | LLDB_INSTRUMENT_VA(this, process, event, out, err); |
570 | |
571 | return HandleProcessEvent(process, event, out: out.m_opaque_sp, err: err.m_opaque_sp); |
572 | } |
573 | |
574 | void SBDebugger::HandleProcessEvent(const SBProcess &process, |
575 | const SBEvent &event, FILE *out, |
576 | FILE *err) { |
577 | LLDB_INSTRUMENT_VA(this, process, event, out, err); |
578 | |
579 | FileSP outfile = std::make_shared<NativeFile>(args&: out, args: false); |
580 | FileSP errfile = std::make_shared<NativeFile>(args&: err, args: false); |
581 | return HandleProcessEvent(process, event, out: outfile, err: errfile); |
582 | } |
583 | |
584 | void SBDebugger::HandleProcessEvent(const SBProcess &process, |
585 | const SBEvent &event, FileSP out_sp, |
586 | FileSP err_sp) { |
587 | |
588 | LLDB_INSTRUMENT_VA(this, process, event, out_sp, err_sp); |
589 | |
590 | if (!process.IsValid()) |
591 | return; |
592 | |
593 | TargetSP target_sp(process.GetTarget().GetSP()); |
594 | if (!target_sp) |
595 | return; |
596 | |
597 | const uint32_t event_type = event.GetType(); |
598 | char stdio_buffer[1024]; |
599 | size_t len; |
600 | |
601 | std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex()); |
602 | |
603 | if (event_type & |
604 | (Process::eBroadcastBitSTDOUT | Process::eBroadcastBitStateChanged)) { |
605 | // Drain stdout when we stop just in case we have any bytes |
606 | while ((len = process.GetSTDOUT(dst: stdio_buffer, dst_len: sizeof(stdio_buffer))) > 0) |
607 | if (out_sp) |
608 | out_sp->Write(buf: stdio_buffer, num_bytes&: len); |
609 | } |
610 | |
611 | if (event_type & |
612 | (Process::eBroadcastBitSTDERR | Process::eBroadcastBitStateChanged)) { |
613 | // Drain stderr when we stop just in case we have any bytes |
614 | while ((len = process.GetSTDERR(dst: stdio_buffer, dst_len: sizeof(stdio_buffer))) > 0) |
615 | if (err_sp) |
616 | err_sp->Write(buf: stdio_buffer, num_bytes&: len); |
617 | } |
618 | |
619 | if (event_type & Process::eBroadcastBitStateChanged) { |
620 | StateType event_state = SBProcess::GetStateFromEvent(event); |
621 | |
622 | if (event_state == eStateInvalid) |
623 | return; |
624 | |
625 | bool is_stopped = StateIsStoppedState(state: event_state); |
626 | if (!is_stopped) |
627 | process.ReportEventState(event, BORROWED: out_sp); |
628 | } |
629 | } |
630 | |
631 | SBSourceManager SBDebugger::GetSourceManager() { |
632 | LLDB_INSTRUMENT_VA(this); |
633 | |
634 | SBSourceManager sb_source_manager(*this); |
635 | return sb_source_manager; |
636 | } |
637 | |
638 | bool SBDebugger::GetDefaultArchitecture(char *arch_name, size_t arch_name_len) { |
639 | LLDB_INSTRUMENT_VA(arch_name, arch_name_len); |
640 | |
641 | if (arch_name && arch_name_len) { |
642 | ArchSpec default_arch = Target::GetDefaultArchitecture(); |
643 | |
644 | if (default_arch.IsValid()) { |
645 | const std::string &triple_str = default_arch.GetTriple().str(); |
646 | if (!triple_str.empty()) |
647 | ::snprintf(s: arch_name, maxlen: arch_name_len, format: "%s", triple_str.c_str()); |
648 | else |
649 | ::snprintf(s: arch_name, maxlen: arch_name_len, format: "%s", |
650 | default_arch.GetArchitectureName()); |
651 | return true; |
652 | } |
653 | } |
654 | if (arch_name && arch_name_len) |
655 | arch_name[0] = '\0'; |
656 | return false; |
657 | } |
658 | |
659 | bool SBDebugger::SetDefaultArchitecture(const char *arch_name) { |
660 | LLDB_INSTRUMENT_VA(arch_name); |
661 | |
662 | if (arch_name) { |
663 | ArchSpec arch(arch_name); |
664 | if (arch.IsValid()) { |
665 | Target::SetDefaultArchitecture(arch); |
666 | return true; |
667 | } |
668 | } |
669 | return false; |
670 | } |
671 | |
672 | ScriptLanguage |
673 | SBDebugger::GetScriptingLanguage(const char *script_language_name) { |
674 | LLDB_INSTRUMENT_VA(this, script_language_name); |
675 | |
676 | if (!script_language_name) |
677 | return eScriptLanguageDefault; |
678 | return OptionArgParser::ToScriptLanguage( |
679 | s: llvm::StringRef(script_language_name), fail_value: eScriptLanguageDefault, success_ptr: nullptr); |
680 | } |
681 | |
682 | SBStructuredData |
683 | SBDebugger::GetScriptInterpreterInfo(lldb::ScriptLanguage language) { |
684 | LLDB_INSTRUMENT_VA(this, language); |
685 | SBStructuredData data; |
686 | if (m_opaque_sp) { |
687 | lldb_private::ScriptInterpreter *interp = |
688 | m_opaque_sp->GetScriptInterpreter(can_create: language); |
689 | if (interp) { |
690 | data.m_impl_up->SetObjectSP(interp->GetInterpreterInfo()); |
691 | } |
692 | } |
693 | return data; |
694 | } |
695 | |
696 | const char *SBDebugger::GetVersionString() { |
697 | LLDB_INSTRUMENT(); |
698 | |
699 | return lldb_private::GetVersion(); |
700 | } |
701 | |
702 | const char *SBDebugger::StateAsCString(StateType state) { |
703 | LLDB_INSTRUMENT_VA(state); |
704 | |
705 | return lldb_private::StateAsCString(state); |
706 | } |
707 | |
708 | static void AddBoolConfigEntry(StructuredData::Dictionary &dict, |
709 | llvm::StringRef name, bool value, |
710 | llvm::StringRef description) { |
711 | auto entry_up = std::make_unique<StructuredData::Dictionary>(); |
712 | entry_up->AddBooleanItem(key: "value", value); |
713 | entry_up->AddStringItem(key: "description", value: description); |
714 | dict.AddItem(key: name, value_sp: std::move(entry_up)); |
715 | } |
716 | |
717 | static void AddLLVMTargets(StructuredData::Dictionary &dict) { |
718 | auto array_up = std::make_unique<StructuredData::Array>(); |
719 | #define LLVM_TARGET(target) \ |
720 | array_up->AddItem(std::make_unique<StructuredData::String>(#target)); |
721 | #include "llvm/Config/Targets.def" |
722 | auto entry_up = std::make_unique<StructuredData::Dictionary>(); |
723 | entry_up->AddItem(key: "value", value_sp: std::move(array_up)); |
724 | entry_up->AddStringItem(key: "description", value: "A list of configured LLVM targets."); |
725 | dict.AddItem(key: "targets", value_sp: std::move(entry_up)); |
726 | } |
727 | |
728 | SBStructuredData SBDebugger::GetBuildConfiguration() { |
729 | LLDB_INSTRUMENT(); |
730 | |
731 | auto config_up = std::make_unique<StructuredData::Dictionary>(); |
732 | AddBoolConfigEntry( |
733 | dict&: *config_up, name: "xml", value: XMLDocument::XMLEnabled(), |
734 | description: "A boolean value that indicates if XML support is enabled in LLDB"); |
735 | AddBoolConfigEntry( |
736 | dict&: *config_up, name: "curl", LLVM_ENABLE_CURL, |
737 | description: "A boolean value that indicates if CURL support is enabled in LLDB"); |
738 | AddBoolConfigEntry( |
739 | dict&: *config_up, name: "curses", LLDB_ENABLE_CURSES, |
740 | description: "A boolean value that indicates if curses support is enabled in LLDB"); |
741 | AddBoolConfigEntry( |
742 | dict&: *config_up, name: "editline", LLDB_ENABLE_LIBEDIT, |
743 | description: "A boolean value that indicates if editline support is enabled in LLDB"); |
744 | AddBoolConfigEntry(dict&: *config_up, name: "editline_wchar", LLDB_EDITLINE_USE_WCHAR, |
745 | description: "A boolean value that indicates if editline wide " |
746 | "characters support is enabled in LLDB"); |
747 | AddBoolConfigEntry( |
748 | dict&: *config_up, name: "lzma", LLDB_ENABLE_LZMA, |
749 | description: "A boolean value that indicates if lzma support is enabled in LLDB"); |
750 | AddBoolConfigEntry( |
751 | dict&: *config_up, name: "python", LLDB_ENABLE_PYTHON, |
752 | description: "A boolean value that indicates if python support is enabled in LLDB"); |
753 | AddBoolConfigEntry( |
754 | dict&: *config_up, name: "lua", LLDB_ENABLE_LUA, |
755 | description: "A boolean value that indicates if lua support is enabled in LLDB"); |
756 | AddBoolConfigEntry(dict&: *config_up, name: "fbsdvmcore", LLDB_ENABLE_FBSDVMCORE, |
757 | description: "A boolean value that indicates if fbsdvmcore support is " |
758 | "enabled in LLDB"); |
759 | AddLLVMTargets(dict&: *config_up); |
760 | |
761 | SBStructuredData data; |
762 | data.m_impl_up->SetObjectSP(std::move(config_up)); |
763 | return data; |
764 | } |
765 | |
766 | bool SBDebugger::StateIsRunningState(StateType state) { |
767 | LLDB_INSTRUMENT_VA(state); |
768 | |
769 | const bool result = lldb_private::StateIsRunningState(state); |
770 | |
771 | return result; |
772 | } |
773 | |
774 | bool SBDebugger::StateIsStoppedState(StateType state) { |
775 | LLDB_INSTRUMENT_VA(state); |
776 | |
777 | const bool result = lldb_private::StateIsStoppedState(state, must_exist: false); |
778 | |
779 | return result; |
780 | } |
781 | |
782 | lldb::SBTarget SBDebugger::CreateTarget(const char *filename, |
783 | const char *target_triple, |
784 | const char *platform_name, |
785 | bool add_dependent_modules, |
786 | lldb::SBError &sb_error) { |
787 | LLDB_INSTRUMENT_VA(this, filename, target_triple, platform_name, |
788 | add_dependent_modules, sb_error); |
789 | |
790 | SBTarget sb_target; |
791 | TargetSP target_sp; |
792 | if (m_opaque_sp) { |
793 | sb_error.Clear(); |
794 | OptionGroupPlatform platform_options(false); |
795 | platform_options.SetPlatformName(platform_name); |
796 | |
797 | sb_error.ref() = m_opaque_sp->GetTargetList().CreateTarget( |
798 | debugger&: *m_opaque_sp, user_exe_path: filename, triple_str: target_triple, |
799 | get_dependent_modules: add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, |
800 | platform_options: &platform_options, target_sp); |
801 | |
802 | if (sb_error.Success()) |
803 | sb_target.SetSP(target_sp); |
804 | } else { |
805 | sb_error = Status::FromErrorString(str: "invalid debugger"); |
806 | } |
807 | |
808 | Log *log = GetLog(mask: LLDBLog::API); |
809 | LLDB_LOGF(log, |
810 | "SBDebugger(%p)::CreateTarget (filename=\"%s\", triple=%s, " |
811 | "platform_name=%s, add_dependent_modules=%u, error=%s) => " |
812 | "SBTarget(%p)", |
813 | static_cast<void *>(m_opaque_sp.get()), filename, target_triple, |
814 | platform_name, add_dependent_modules, sb_error.GetCString(), |
815 | static_cast<void *>(target_sp.get())); |
816 | |
817 | return sb_target; |
818 | } |
819 | |
820 | SBTarget |
821 | SBDebugger::CreateTargetWithFileAndTargetTriple(const char *filename, |
822 | const char *target_triple) { |
823 | LLDB_INSTRUMENT_VA(this, filename, target_triple); |
824 | |
825 | SBTarget sb_target; |
826 | TargetSP target_sp; |
827 | if (m_opaque_sp) { |
828 | const bool add_dependent_modules = true; |
829 | Status error(m_opaque_sp->GetTargetList().CreateTarget( |
830 | debugger&: *m_opaque_sp, user_exe_path: filename, triple_str: target_triple, |
831 | get_dependent_modules: add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, platform_options: nullptr, |
832 | target_sp)); |
833 | sb_target.SetSP(target_sp); |
834 | } |
835 | |
836 | Log *log = GetLog(mask: LLDBLog::API); |
837 | LLDB_LOGF(log, |
838 | "SBDebugger(%p)::CreateTargetWithFileAndTargetTriple " |
839 | "(filename=\"%s\", triple=%s) => SBTarget(%p)", |
840 | static_cast<void *>(m_opaque_sp.get()), filename, target_triple, |
841 | static_cast<void *>(target_sp.get())); |
842 | |
843 | return sb_target; |
844 | } |
845 | |
846 | SBTarget SBDebugger::CreateTargetWithFileAndArch(const char *filename, |
847 | const char *arch_cstr) { |
848 | LLDB_INSTRUMENT_VA(this, filename, arch_cstr); |
849 | |
850 | Log *log = GetLog(mask: LLDBLog::API); |
851 | |
852 | SBTarget sb_target; |
853 | TargetSP target_sp; |
854 | if (m_opaque_sp) { |
855 | Status error; |
856 | if (arch_cstr == nullptr) { |
857 | // The version of CreateTarget that takes an ArchSpec won't accept an |
858 | // empty ArchSpec, so when the arch hasn't been specified, we need to |
859 | // call the target triple version. |
860 | error = m_opaque_sp->GetTargetList().CreateTarget( |
861 | debugger&: *m_opaque_sp, user_exe_path: filename, triple_str: arch_cstr, get_dependent_modules: eLoadDependentsYes, platform_options: nullptr, |
862 | target_sp); |
863 | } else { |
864 | PlatformSP platform_sp = |
865 | m_opaque_sp->GetPlatformList().GetSelectedPlatform(); |
866 | ArchSpec arch = |
867 | Platform::GetAugmentedArchSpec(platform: platform_sp.get(), triple: arch_cstr); |
868 | if (arch.IsValid()) |
869 | error = m_opaque_sp->GetTargetList().CreateTarget( |
870 | debugger&: *m_opaque_sp, user_exe_path: filename, arch, get_dependent_modules: eLoadDependentsYes, platform_sp, |
871 | target_sp); |
872 | else |
873 | error = Status::FromErrorStringWithFormat(format: "invalid arch_cstr: %s", |
874 | arch_cstr); |
875 | } |
876 | if (error.Success()) |
877 | sb_target.SetSP(target_sp); |
878 | } |
879 | |
880 | LLDB_LOGF(log, |
881 | "SBDebugger(%p)::CreateTargetWithFileAndArch (filename=\"%s\", " |
882 | "arch=%s) => SBTarget(%p)", |
883 | static_cast<void *>(m_opaque_sp.get()), |
884 | filename ? filename : "<unspecified>", |
885 | arch_cstr ? arch_cstr : "<unspecified>", |
886 | static_cast<void *>(target_sp.get())); |
887 | |
888 | return sb_target; |
889 | } |
890 | |
891 | SBTarget SBDebugger::CreateTarget(const char *filename) { |
892 | LLDB_INSTRUMENT_VA(this, filename); |
893 | |
894 | SBTarget sb_target; |
895 | TargetSP target_sp; |
896 | if (m_opaque_sp) { |
897 | Status error; |
898 | const bool add_dependent_modules = true; |
899 | error = m_opaque_sp->GetTargetList().CreateTarget( |
900 | debugger&: *m_opaque_sp, user_exe_path: filename, triple_str: "", |
901 | get_dependent_modules: add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, platform_options: nullptr, |
902 | target_sp); |
903 | |
904 | if (error.Success()) |
905 | sb_target.SetSP(target_sp); |
906 | } |
907 | Log *log = GetLog(mask: LLDBLog::API); |
908 | LLDB_LOGF(log, |
909 | "SBDebugger(%p)::CreateTarget (filename=\"%s\") => SBTarget(%p)", |
910 | static_cast<void *>(m_opaque_sp.get()), filename, |
911 | static_cast<void *>(target_sp.get())); |
912 | return sb_target; |
913 | } |
914 | |
915 | SBTarget SBDebugger::GetDummyTarget() { |
916 | LLDB_INSTRUMENT_VA(this); |
917 | |
918 | SBTarget sb_target; |
919 | if (m_opaque_sp) { |
920 | sb_target.SetSP(m_opaque_sp->GetDummyTarget().shared_from_this()); |
921 | } |
922 | Log *log = GetLog(mask: LLDBLog::API); |
923 | LLDB_LOGF(log, "SBDebugger(%p)::GetDummyTarget() => SBTarget(%p)", |
924 | static_cast<void *>(m_opaque_sp.get()), |
925 | static_cast<void *>(sb_target.GetSP().get())); |
926 | return sb_target; |
927 | } |
928 | |
929 | void SBDebugger::DispatchClientTelemetry(const lldb::SBStructuredData &entry) { |
930 | LLDB_INSTRUMENT_VA(this); |
931 | if (m_opaque_sp) { |
932 | m_opaque_sp->DispatchClientTelemetry(entry: *entry.m_impl_up); |
933 | } else { |
934 | Log *log = GetLog(mask: LLDBLog::API); |
935 | LLDB_LOGF(log, |
936 | "Could not send telemetry from SBDebugger - debugger was null."); |
937 | } |
938 | } |
939 | |
940 | bool SBDebugger::DeleteTarget(lldb::SBTarget &target) { |
941 | LLDB_INSTRUMENT_VA(this, target); |
942 | |
943 | bool result = false; |
944 | if (m_opaque_sp) { |
945 | TargetSP target_sp(target.GetSP()); |
946 | if (target_sp) { |
947 | // No need to lock, the target list is thread safe |
948 | result = m_opaque_sp->GetTargetList().DeleteTarget(target_sp); |
949 | target_sp->Destroy(); |
950 | target.Clear(); |
951 | } |
952 | } |
953 | |
954 | Log *log = GetLog(mask: LLDBLog::API); |
955 | LLDB_LOGF(log, "SBDebugger(%p)::DeleteTarget (SBTarget(%p)) => %i", |
956 | static_cast<void *>(m_opaque_sp.get()), |
957 | static_cast<void *>(target.m_opaque_sp.get()), result); |
958 | |
959 | return result; |
960 | } |
961 | |
962 | SBTarget SBDebugger::GetTargetAtIndex(uint32_t idx) { |
963 | LLDB_INSTRUMENT_VA(this, idx); |
964 | |
965 | SBTarget sb_target; |
966 | if (m_opaque_sp) { |
967 | // No need to lock, the target list is thread safe |
968 | sb_target.SetSP(m_opaque_sp->GetTargetList().GetTargetAtIndex(index: idx)); |
969 | } |
970 | return sb_target; |
971 | } |
972 | |
973 | uint32_t SBDebugger::GetIndexOfTarget(lldb::SBTarget target) { |
974 | LLDB_INSTRUMENT_VA(this, target); |
975 | |
976 | lldb::TargetSP target_sp = target.GetSP(); |
977 | if (!target_sp) |
978 | return UINT32_MAX; |
979 | |
980 | if (!m_opaque_sp) |
981 | return UINT32_MAX; |
982 | |
983 | return m_opaque_sp->GetTargetList().GetIndexOfTarget(target_sp: target.GetSP()); |
984 | } |
985 | |
986 | SBTarget SBDebugger::FindTargetWithProcessID(lldb::pid_t pid) { |
987 | LLDB_INSTRUMENT_VA(this, pid); |
988 | |
989 | SBTarget sb_target; |
990 | if (m_opaque_sp) { |
991 | // No need to lock, the target list is thread safe |
992 | sb_target.SetSP(m_opaque_sp->GetTargetList().FindTargetWithProcessID(pid)); |
993 | } |
994 | return sb_target; |
995 | } |
996 | |
997 | SBTarget SBDebugger::FindTargetWithFileAndArch(const char *filename, |
998 | const char *arch_name) { |
999 | LLDB_INSTRUMENT_VA(this, filename, arch_name); |
1000 | |
1001 | SBTarget sb_target; |
1002 | if (m_opaque_sp && filename && filename[0]) { |
1003 | // No need to lock, the target list is thread safe |
1004 | ArchSpec arch = Platform::GetAugmentedArchSpec( |
1005 | platform: m_opaque_sp->GetPlatformList().GetSelectedPlatform().get(), triple: arch_name); |
1006 | TargetSP target_sp( |
1007 | m_opaque_sp->GetTargetList().FindTargetWithExecutableAndArchitecture( |
1008 | exe_file_spec: FileSpec(filename), exe_arch_ptr: arch_name ? &arch : nullptr)); |
1009 | sb_target.SetSP(target_sp); |
1010 | } |
1011 | return sb_target; |
1012 | } |
1013 | |
1014 | SBTarget SBDebugger::FindTargetWithLLDBProcess(const ProcessSP &process_sp) { |
1015 | SBTarget sb_target; |
1016 | if (m_opaque_sp) { |
1017 | // No need to lock, the target list is thread safe |
1018 | sb_target.SetSP( |
1019 | m_opaque_sp->GetTargetList().FindTargetWithProcess(process: process_sp.get())); |
1020 | } |
1021 | return sb_target; |
1022 | } |
1023 | |
1024 | uint32_t SBDebugger::GetNumTargets() { |
1025 | LLDB_INSTRUMENT_VA(this); |
1026 | |
1027 | if (m_opaque_sp) { |
1028 | // No need to lock, the target list is thread safe |
1029 | return m_opaque_sp->GetTargetList().GetNumTargets(); |
1030 | } |
1031 | return 0; |
1032 | } |
1033 | |
1034 | SBTarget SBDebugger::GetSelectedTarget() { |
1035 | LLDB_INSTRUMENT_VA(this); |
1036 | |
1037 | Log *log = GetLog(mask: LLDBLog::API); |
1038 | |
1039 | SBTarget sb_target; |
1040 | TargetSP target_sp; |
1041 | if (m_opaque_sp) { |
1042 | // No need to lock, the target list is thread safe |
1043 | target_sp = m_opaque_sp->GetTargetList().GetSelectedTarget(); |
1044 | sb_target.SetSP(target_sp); |
1045 | } |
1046 | |
1047 | if (log) { |
1048 | SBStream sstr; |
1049 | sb_target.GetDescription(description&: sstr, description_level: eDescriptionLevelBrief); |
1050 | LLDB_LOGF(log, "SBDebugger(%p)::GetSelectedTarget () => SBTarget(%p): %s", |
1051 | static_cast<void *>(m_opaque_sp.get()), |
1052 | static_cast<void *>(target_sp.get()), sstr.GetData()); |
1053 | } |
1054 | |
1055 | return sb_target; |
1056 | } |
1057 | |
1058 | void SBDebugger::SetSelectedTarget(SBTarget &sb_target) { |
1059 | LLDB_INSTRUMENT_VA(this, sb_target); |
1060 | |
1061 | Log *log = GetLog(mask: LLDBLog::API); |
1062 | |
1063 | TargetSP target_sp(sb_target.GetSP()); |
1064 | if (m_opaque_sp) { |
1065 | m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp); |
1066 | } |
1067 | if (log) { |
1068 | SBStream sstr; |
1069 | sb_target.GetDescription(description&: sstr, description_level: eDescriptionLevelBrief); |
1070 | LLDB_LOGF(log, "SBDebugger(%p)::SetSelectedTarget () => SBTarget(%p): %s", |
1071 | static_cast<void *>(m_opaque_sp.get()), |
1072 | static_cast<void *>(target_sp.get()), sstr.GetData()); |
1073 | } |
1074 | } |
1075 | |
1076 | SBPlatform SBDebugger::GetSelectedPlatform() { |
1077 | LLDB_INSTRUMENT_VA(this); |
1078 | |
1079 | Log *log = GetLog(mask: LLDBLog::API); |
1080 | |
1081 | SBPlatform sb_platform; |
1082 | DebuggerSP debugger_sp(m_opaque_sp); |
1083 | if (debugger_sp) { |
1084 | sb_platform.SetSP(debugger_sp->GetPlatformList().GetSelectedPlatform()); |
1085 | } |
1086 | LLDB_LOGF(log, "SBDebugger(%p)::GetSelectedPlatform () => SBPlatform(%p): %s", |
1087 | static_cast<void *>(m_opaque_sp.get()), |
1088 | static_cast<void *>(sb_platform.GetSP().get()), |
1089 | sb_platform.GetName()); |
1090 | return sb_platform; |
1091 | } |
1092 | |
1093 | void SBDebugger::SetSelectedPlatform(SBPlatform &sb_platform) { |
1094 | LLDB_INSTRUMENT_VA(this, sb_platform); |
1095 | |
1096 | Log *log = GetLog(mask: LLDBLog::API); |
1097 | |
1098 | DebuggerSP debugger_sp(m_opaque_sp); |
1099 | if (debugger_sp) { |
1100 | debugger_sp->GetPlatformList().SetSelectedPlatform(sb_platform.GetSP()); |
1101 | } |
1102 | |
1103 | LLDB_LOGF(log, "SBDebugger(%p)::SetSelectedPlatform (SBPlatform(%p) %s)", |
1104 | static_cast<void *>(m_opaque_sp.get()), |
1105 | static_cast<void *>(sb_platform.GetSP().get()), |
1106 | sb_platform.GetName()); |
1107 | } |
1108 | |
1109 | uint32_t SBDebugger::GetNumPlatforms() { |
1110 | LLDB_INSTRUMENT_VA(this); |
1111 | |
1112 | if (m_opaque_sp) { |
1113 | // No need to lock, the platform list is thread safe |
1114 | return m_opaque_sp->GetPlatformList().GetSize(); |
1115 | } |
1116 | return 0; |
1117 | } |
1118 | |
1119 | SBPlatform SBDebugger::GetPlatformAtIndex(uint32_t idx) { |
1120 | LLDB_INSTRUMENT_VA(this, idx); |
1121 | |
1122 | SBPlatform sb_platform; |
1123 | if (m_opaque_sp) { |
1124 | // No need to lock, the platform list is thread safe |
1125 | sb_platform.SetSP(m_opaque_sp->GetPlatformList().GetAtIndex(idx)); |
1126 | } |
1127 | return sb_platform; |
1128 | } |
1129 | |
1130 | uint32_t SBDebugger::GetNumAvailablePlatforms() { |
1131 | LLDB_INSTRUMENT_VA(this); |
1132 | |
1133 | uint32_t idx = 0; |
1134 | while (true) { |
1135 | if (PluginManager::GetPlatformPluginNameAtIndex(idx).empty()) { |
1136 | break; |
1137 | } |
1138 | ++idx; |
1139 | } |
1140 | // +1 for the host platform, which should always appear first in the list. |
1141 | return idx + 1; |
1142 | } |
1143 | |
1144 | SBStructuredData SBDebugger::GetAvailablePlatformInfoAtIndex(uint32_t idx) { |
1145 | LLDB_INSTRUMENT_VA(this, idx); |
1146 | |
1147 | SBStructuredData data; |
1148 | auto platform_dict = std::make_unique<StructuredData::Dictionary>(); |
1149 | llvm::StringRef name_str("name"), desc_str( "description"); |
1150 | |
1151 | if (idx == 0) { |
1152 | PlatformSP host_platform_sp(Platform::GetHostPlatform()); |
1153 | platform_dict->AddStringItem(key: name_str, value: host_platform_sp->GetPluginName()); |
1154 | platform_dict->AddStringItem( |
1155 | key: desc_str, value: llvm::StringRef(host_platform_sp->GetDescription())); |
1156 | } else if (idx > 0) { |
1157 | llvm::StringRef plugin_name = |
1158 | PluginManager::GetPlatformPluginNameAtIndex(idx: idx - 1); |
1159 | if (plugin_name.empty()) { |
1160 | return data; |
1161 | } |
1162 | platform_dict->AddStringItem(key: name_str, value: llvm::StringRef(plugin_name)); |
1163 | |
1164 | llvm::StringRef plugin_desc = |
1165 | PluginManager::GetPlatformPluginDescriptionAtIndex(idx: idx - 1); |
1166 | platform_dict->AddStringItem(key: desc_str, value: llvm::StringRef(plugin_desc)); |
1167 | } |
1168 | |
1169 | data.m_impl_up->SetObjectSP( |
1170 | StructuredData::ObjectSP(platform_dict.release())); |
1171 | return data; |
1172 | } |
1173 | |
1174 | void SBDebugger::DispatchInput(void *baton, const void *data, size_t data_len) { |
1175 | LLDB_INSTRUMENT_VA(this, baton, data, data_len); |
1176 | |
1177 | DispatchInput(data, data_len); |
1178 | } |
1179 | |
1180 | void SBDebugger::DispatchInput(const void *data, size_t data_len) { |
1181 | LLDB_INSTRUMENT_VA(this, data, data_len); |
1182 | |
1183 | // Log *log(GetLog (LLDBLog::API)); |
1184 | // |
1185 | // if (log) |
1186 | // LLDB_LOGF(log, "SBDebugger(%p)::DispatchInput (data=\"%.*s\", |
1187 | // size_t=%" PRIu64 ")", |
1188 | // m_opaque_sp.get(), |
1189 | // (int) data_len, |
1190 | // (const char *) data, |
1191 | // (uint64_t)data_len); |
1192 | // |
1193 | // if (m_opaque_sp) |
1194 | // m_opaque_sp->DispatchInput ((const char *) data, data_len); |
1195 | } |
1196 | |
1197 | void SBDebugger::DispatchInputInterrupt() { |
1198 | LLDB_INSTRUMENT_VA(this); |
1199 | |
1200 | if (m_opaque_sp) |
1201 | m_opaque_sp->DispatchInputInterrupt(); |
1202 | } |
1203 | |
1204 | void SBDebugger::DispatchInputEndOfFile() { |
1205 | LLDB_INSTRUMENT_VA(this); |
1206 | |
1207 | if (m_opaque_sp) |
1208 | m_opaque_sp->DispatchInputEndOfFile(); |
1209 | } |
1210 | |
1211 | void SBDebugger::PushInputReader(SBInputReader &reader) { |
1212 | LLDB_INSTRUMENT_VA(this, reader); |
1213 | } |
1214 | |
1215 | void SBDebugger::RunCommandInterpreter(bool auto_handle_events, |
1216 | bool spawn_thread) { |
1217 | LLDB_INSTRUMENT_VA(this, auto_handle_events, spawn_thread); |
1218 | |
1219 | if (m_opaque_sp) { |
1220 | CommandInterpreterRunOptions options; |
1221 | options.SetAutoHandleEvents(auto_handle_events); |
1222 | options.SetSpawnThread(spawn_thread); |
1223 | m_opaque_sp->GetCommandInterpreter().RunCommandInterpreter(options); |
1224 | } |
1225 | } |
1226 | |
1227 | void SBDebugger::RunCommandInterpreter(bool auto_handle_events, |
1228 | bool spawn_thread, |
1229 | SBCommandInterpreterRunOptions &options, |
1230 | int &num_errors, bool &quit_requested, |
1231 | bool &stopped_for_crash) |
1232 | |
1233 | { |
1234 | LLDB_INSTRUMENT_VA(this, auto_handle_events, spawn_thread, options, |
1235 | num_errors, quit_requested, stopped_for_crash); |
1236 | |
1237 | if (m_opaque_sp) { |
1238 | options.SetAutoHandleEvents(auto_handle_events); |
1239 | options.SetSpawnThread(spawn_thread); |
1240 | CommandInterpreter &interp = m_opaque_sp->GetCommandInterpreter(); |
1241 | CommandInterpreterRunResult result = |
1242 | interp.RunCommandInterpreter(options&: options.ref()); |
1243 | num_errors = result.GetNumErrors(); |
1244 | quit_requested = |
1245 | result.IsResult(result: lldb::eCommandInterpreterResultQuitRequested); |
1246 | stopped_for_crash = |
1247 | result.IsResult(result: lldb::eCommandInterpreterResultInferiorCrash); |
1248 | } |
1249 | } |
1250 | |
1251 | SBCommandInterpreterRunResult SBDebugger::RunCommandInterpreter( |
1252 | const SBCommandInterpreterRunOptions &options) { |
1253 | LLDB_INSTRUMENT_VA(this, options); |
1254 | |
1255 | if (!m_opaque_sp) |
1256 | return SBCommandInterpreterRunResult(); |
1257 | |
1258 | CommandInterpreter &interp = m_opaque_sp->GetCommandInterpreter(); |
1259 | CommandInterpreterRunResult result = |
1260 | interp.RunCommandInterpreter(options&: options.ref()); |
1261 | |
1262 | return SBCommandInterpreterRunResult(result); |
1263 | } |
1264 | |
1265 | SBError SBDebugger::RunREPL(lldb::LanguageType language, |
1266 | const char *repl_options) { |
1267 | LLDB_INSTRUMENT_VA(this, language, repl_options); |
1268 | |
1269 | SBError error; |
1270 | if (m_opaque_sp) |
1271 | error.ref() = m_opaque_sp->RunREPL(language, repl_options); |
1272 | else |
1273 | error = Status::FromErrorString(str: "invalid debugger"); |
1274 | return error; |
1275 | } |
1276 | |
1277 | void SBDebugger::reset(const DebuggerSP &debugger_sp) { |
1278 | m_opaque_sp = debugger_sp; |
1279 | } |
1280 | |
1281 | Debugger *SBDebugger::get() const { return m_opaque_sp.get(); } |
1282 | |
1283 | Debugger &SBDebugger::ref() const { |
1284 | assert(m_opaque_sp.get()); |
1285 | return *m_opaque_sp; |
1286 | } |
1287 | |
1288 | const lldb::DebuggerSP &SBDebugger::get_sp() const { return m_opaque_sp; } |
1289 | |
1290 | SBDebugger SBDebugger::FindDebuggerWithID(int id) { |
1291 | LLDB_INSTRUMENT_VA(id); |
1292 | |
1293 | // No need to lock, the debugger list is thread safe |
1294 | SBDebugger sb_debugger; |
1295 | DebuggerSP debugger_sp = Debugger::FindDebuggerWithID(id); |
1296 | if (debugger_sp) |
1297 | sb_debugger.reset(debugger_sp); |
1298 | return sb_debugger; |
1299 | } |
1300 | |
1301 | const char *SBDebugger::GetInstanceName() { |
1302 | LLDB_INSTRUMENT_VA(this); |
1303 | |
1304 | if (!m_opaque_sp) |
1305 | return nullptr; |
1306 | |
1307 | return ConstString(m_opaque_sp->GetInstanceName()).AsCString(); |
1308 | } |
1309 | |
1310 | SBError SBDebugger::SetInternalVariable(const char *var_name, const char *value, |
1311 | const char *debugger_instance_name) { |
1312 | LLDB_INSTRUMENT_VA(var_name, value, debugger_instance_name); |
1313 | |
1314 | SBError sb_error; |
1315 | DebuggerSP debugger_sp( |
1316 | Debugger::FindDebuggerWithInstanceName(instance_name: debugger_instance_name)); |
1317 | Status error; |
1318 | if (debugger_sp) { |
1319 | ExecutionContext exe_ctx( |
1320 | debugger_sp->GetCommandInterpreter().GetExecutionContext()); |
1321 | error = debugger_sp->SetPropertyValue(exe_ctx: &exe_ctx, op: eVarSetOperationAssign, |
1322 | property_path: var_name, value); |
1323 | } else { |
1324 | error = Status::FromErrorStringWithFormat( |
1325 | format: "invalid debugger instance name '%s'", debugger_instance_name); |
1326 | } |
1327 | if (error.Fail()) |
1328 | sb_error.SetError(std::move(error)); |
1329 | return sb_error; |
1330 | } |
1331 | |
1332 | SBStringList |
1333 | SBDebugger::GetInternalVariableValue(const char *var_name, |
1334 | const char *debugger_instance_name) { |
1335 | LLDB_INSTRUMENT_VA(var_name, debugger_instance_name); |
1336 | |
1337 | DebuggerSP debugger_sp( |
1338 | Debugger::FindDebuggerWithInstanceName(instance_name: debugger_instance_name)); |
1339 | Status error; |
1340 | if (debugger_sp) { |
1341 | ExecutionContext exe_ctx( |
1342 | debugger_sp->GetCommandInterpreter().GetExecutionContext()); |
1343 | lldb::OptionValueSP value_sp( |
1344 | debugger_sp->GetPropertyValue(exe_ctx: &exe_ctx, property_path: var_name, error)); |
1345 | if (value_sp) { |
1346 | StreamString value_strm; |
1347 | value_sp->DumpValue(exe_ctx: &exe_ctx, strm&: value_strm, dump_mask: OptionValue::eDumpOptionValue); |
1348 | const std::string &value_str = std::string(value_strm.GetString()); |
1349 | if (!value_str.empty()) { |
1350 | StringList string_list; |
1351 | string_list.SplitIntoLines(lines: value_str); |
1352 | return SBStringList(&string_list); |
1353 | } |
1354 | } |
1355 | } |
1356 | return SBStringList(); |
1357 | } |
1358 | |
1359 | uint32_t SBDebugger::GetTerminalWidth() const { |
1360 | LLDB_INSTRUMENT_VA(this); |
1361 | |
1362 | return (m_opaque_sp ? m_opaque_sp->GetTerminalWidth() : 0); |
1363 | } |
1364 | |
1365 | void SBDebugger::SetTerminalWidth(uint32_t term_width) { |
1366 | LLDB_INSTRUMENT_VA(this, term_width); |
1367 | |
1368 | if (m_opaque_sp) |
1369 | m_opaque_sp->SetTerminalWidth(term_width); |
1370 | } |
1371 | |
1372 | uint32_t SBDebugger::GetTerminalHeight() const { |
1373 | LLDB_INSTRUMENT_VA(this); |
1374 | |
1375 | return (m_opaque_sp ? m_opaque_sp->GetTerminalWidth() : 0); |
1376 | } |
1377 | |
1378 | void SBDebugger::SetTerminalHeight(uint32_t term_height) { |
1379 | LLDB_INSTRUMENT_VA(this, term_height); |
1380 | |
1381 | if (m_opaque_sp) |
1382 | m_opaque_sp->SetTerminalHeight(term_height); |
1383 | } |
1384 | |
1385 | const char *SBDebugger::GetPrompt() const { |
1386 | LLDB_INSTRUMENT_VA(this); |
1387 | |
1388 | Log *log = GetLog(mask: LLDBLog::API); |
1389 | |
1390 | LLDB_LOG(log, "SBDebugger({0:x})::GetPrompt () => \"{1}\"", |
1391 | static_cast<void *>(m_opaque_sp.get()), |
1392 | (m_opaque_sp ? m_opaque_sp->GetPrompt() : "")); |
1393 | |
1394 | return (m_opaque_sp ? ConstString(m_opaque_sp->GetPrompt()).GetCString() |
1395 | : nullptr); |
1396 | } |
1397 | |
1398 | void SBDebugger::SetPrompt(const char *prompt) { |
1399 | LLDB_INSTRUMENT_VA(this, prompt); |
1400 | |
1401 | if (m_opaque_sp) |
1402 | m_opaque_sp->SetPrompt(llvm::StringRef(prompt)); |
1403 | } |
1404 | |
1405 | const char *SBDebugger::GetReproducerPath() const { |
1406 | LLDB_INSTRUMENT_VA(this); |
1407 | |
1408 | return "GetReproducerPath has been deprecated"; |
1409 | } |
1410 | |
1411 | ScriptLanguage SBDebugger::GetScriptLanguage() const { |
1412 | LLDB_INSTRUMENT_VA(this); |
1413 | |
1414 | return (m_opaque_sp ? m_opaque_sp->GetScriptLanguage() : eScriptLanguageNone); |
1415 | } |
1416 | |
1417 | void SBDebugger::SetScriptLanguage(ScriptLanguage script_lang) { |
1418 | LLDB_INSTRUMENT_VA(this, script_lang); |
1419 | |
1420 | if (m_opaque_sp) { |
1421 | m_opaque_sp->SetScriptLanguage(script_lang); |
1422 | } |
1423 | } |
1424 | |
1425 | LanguageType SBDebugger::GetREPLLanguage() const { |
1426 | LLDB_INSTRUMENT_VA(this); |
1427 | |
1428 | return (m_opaque_sp ? m_opaque_sp->GetREPLLanguage() : eLanguageTypeUnknown); |
1429 | } |
1430 | |
1431 | void SBDebugger::SetREPLLanguage(LanguageType repl_lang) { |
1432 | LLDB_INSTRUMENT_VA(this, repl_lang); |
1433 | |
1434 | if (m_opaque_sp) { |
1435 | m_opaque_sp->SetREPLLanguage(repl_lang); |
1436 | } |
1437 | } |
1438 | |
1439 | bool SBDebugger::SetUseExternalEditor(bool value) { |
1440 | LLDB_INSTRUMENT_VA(this, value); |
1441 | |
1442 | return (m_opaque_sp ? m_opaque_sp->SetUseExternalEditor(value) : false); |
1443 | } |
1444 | |
1445 | bool SBDebugger::GetUseExternalEditor() { |
1446 | LLDB_INSTRUMENT_VA(this); |
1447 | |
1448 | return (m_opaque_sp ? m_opaque_sp->GetUseExternalEditor() : false); |
1449 | } |
1450 | |
1451 | bool SBDebugger::SetUseColor(bool value) { |
1452 | LLDB_INSTRUMENT_VA(this, value); |
1453 | |
1454 | return (m_opaque_sp ? m_opaque_sp->SetUseColor(value) : false); |
1455 | } |
1456 | |
1457 | bool SBDebugger::GetUseColor() const { |
1458 | LLDB_INSTRUMENT_VA(this); |
1459 | |
1460 | return (m_opaque_sp ? m_opaque_sp->GetUseColor() : false); |
1461 | } |
1462 | |
1463 | bool SBDebugger::SetShowInlineDiagnostics(bool value) { |
1464 | LLDB_INSTRUMENT_VA(this, value); |
1465 | |
1466 | return (m_opaque_sp ? m_opaque_sp->SetShowInlineDiagnostics(value) : false); |
1467 | } |
1468 | |
1469 | bool SBDebugger::SetUseSourceCache(bool value) { |
1470 | LLDB_INSTRUMENT_VA(this, value); |
1471 | |
1472 | return (m_opaque_sp ? m_opaque_sp->SetUseSourceCache(value) : false); |
1473 | } |
1474 | |
1475 | bool SBDebugger::GetUseSourceCache() const { |
1476 | LLDB_INSTRUMENT_VA(this); |
1477 | |
1478 | return (m_opaque_sp ? m_opaque_sp->GetUseSourceCache() : false); |
1479 | } |
1480 | |
1481 | bool SBDebugger::GetDescription(SBStream &description) { |
1482 | LLDB_INSTRUMENT_VA(this, description); |
1483 | |
1484 | Stream &strm = description.ref(); |
1485 | |
1486 | if (m_opaque_sp) { |
1487 | const char *name = m_opaque_sp->GetInstanceName().c_str(); |
1488 | user_id_t id = m_opaque_sp->GetID(); |
1489 | strm.Printf(format: "Debugger (instance: \"%s\", id: %"PRIu64 ")", name, id); |
1490 | } else |
1491 | strm.PutCString(cstr: "No value"); |
1492 | |
1493 | return true; |
1494 | } |
1495 | |
1496 | user_id_t SBDebugger::GetID() { |
1497 | LLDB_INSTRUMENT_VA(this); |
1498 | |
1499 | return (m_opaque_sp ? m_opaque_sp->GetID() : LLDB_INVALID_UID); |
1500 | } |
1501 | |
1502 | SBError SBDebugger::SetCurrentPlatform(const char *platform_name_cstr) { |
1503 | LLDB_INSTRUMENT_VA(this, platform_name_cstr); |
1504 | |
1505 | SBError sb_error; |
1506 | if (m_opaque_sp) { |
1507 | if (platform_name_cstr && platform_name_cstr[0]) { |
1508 | PlatformList &platforms = m_opaque_sp->GetPlatformList(); |
1509 | if (PlatformSP platform_sp = platforms.GetOrCreate(name: platform_name_cstr)) |
1510 | platforms.SetSelectedPlatform(platform_sp); |
1511 | else |
1512 | sb_error.ref() = Status::FromErrorString(str: "platform not found"); |
1513 | } else { |
1514 | sb_error.ref() = Status::FromErrorString(str: "invalid platform name"); |
1515 | } |
1516 | } else { |
1517 | sb_error.ref() = Status::FromErrorString(str: "invalid debugger"); |
1518 | } |
1519 | return sb_error; |
1520 | } |
1521 | |
1522 | bool SBDebugger::SetCurrentPlatformSDKRoot(const char *sysroot) { |
1523 | LLDB_INSTRUMENT_VA(this, sysroot); |
1524 | |
1525 | if (SBPlatform platform = GetSelectedPlatform()) { |
1526 | platform.SetSDKRoot(sysroot); |
1527 | return true; |
1528 | } |
1529 | return false; |
1530 | } |
1531 | |
1532 | bool SBDebugger::GetCloseInputOnEOF() const { |
1533 | LLDB_INSTRUMENT_VA(this); |
1534 | |
1535 | return false; |
1536 | } |
1537 | |
1538 | void SBDebugger::SetCloseInputOnEOF(bool b) { |
1539 | LLDB_INSTRUMENT_VA(this, b); |
1540 | } |
1541 | |
1542 | SBTypeCategory SBDebugger::GetCategory(const char *category_name) { |
1543 | LLDB_INSTRUMENT_VA(this, category_name); |
1544 | |
1545 | if (!category_name || *category_name == 0) |
1546 | return SBTypeCategory(); |
1547 | |
1548 | TypeCategoryImplSP category_sp; |
1549 | |
1550 | if (DataVisualization::Categories::GetCategory(category: ConstString(category_name), |
1551 | entry&: category_sp, allow_create: false)) { |
1552 | return SBTypeCategory(category_sp); |
1553 | } else { |
1554 | return SBTypeCategory(); |
1555 | } |
1556 | } |
1557 | |
1558 | SBTypeCategory SBDebugger::GetCategory(lldb::LanguageType lang_type) { |
1559 | LLDB_INSTRUMENT_VA(this, lang_type); |
1560 | |
1561 | TypeCategoryImplSP category_sp; |
1562 | if (DataVisualization::Categories::GetCategory(language: lang_type, entry&: category_sp)) { |
1563 | return SBTypeCategory(category_sp); |
1564 | } else { |
1565 | return SBTypeCategory(); |
1566 | } |
1567 | } |
1568 | |
1569 | SBTypeCategory SBDebugger::CreateCategory(const char *category_name) { |
1570 | LLDB_INSTRUMENT_VA(this, category_name); |
1571 | |
1572 | if (!category_name || *category_name == 0) |
1573 | return SBTypeCategory(); |
1574 | |
1575 | TypeCategoryImplSP category_sp; |
1576 | |
1577 | if (DataVisualization::Categories::GetCategory(category: ConstString(category_name), |
1578 | entry&: category_sp, allow_create: true)) { |
1579 | return SBTypeCategory(category_sp); |
1580 | } else { |
1581 | return SBTypeCategory(); |
1582 | } |
1583 | } |
1584 | |
1585 | bool SBDebugger::DeleteCategory(const char *category_name) { |
1586 | LLDB_INSTRUMENT_VA(this, category_name); |
1587 | |
1588 | if (!category_name || *category_name == 0) |
1589 | return false; |
1590 | |
1591 | return DataVisualization::Categories::Delete(category: ConstString(category_name)); |
1592 | } |
1593 | |
1594 | uint32_t SBDebugger::GetNumCategories() { |
1595 | LLDB_INSTRUMENT_VA(this); |
1596 | |
1597 | return DataVisualization::Categories::GetCount(); |
1598 | } |
1599 | |
1600 | SBTypeCategory SBDebugger::GetCategoryAtIndex(uint32_t index) { |
1601 | LLDB_INSTRUMENT_VA(this, index); |
1602 | |
1603 | return SBTypeCategory( |
1604 | DataVisualization::Categories::GetCategoryAtIndex(index)); |
1605 | } |
1606 | |
1607 | SBTypeCategory SBDebugger::GetDefaultCategory() { |
1608 | LLDB_INSTRUMENT_VA(this); |
1609 | |
1610 | return GetCategory(category_name: "default"); |
1611 | } |
1612 | |
1613 | SBTypeFormat SBDebugger::GetFormatForType(SBTypeNameSpecifier type_name) { |
1614 | LLDB_INSTRUMENT_VA(this, type_name); |
1615 | |
1616 | SBTypeCategory default_category_sb = GetDefaultCategory(); |
1617 | if (default_category_sb.GetEnabled()) |
1618 | return default_category_sb.GetFormatForType(type_name); |
1619 | return SBTypeFormat(); |
1620 | } |
1621 | |
1622 | SBTypeSummary SBDebugger::GetSummaryForType(SBTypeNameSpecifier type_name) { |
1623 | LLDB_INSTRUMENT_VA(this, type_name); |
1624 | |
1625 | if (!type_name.IsValid()) |
1626 | return SBTypeSummary(); |
1627 | return SBTypeSummary(DataVisualization::GetSummaryForType(type_sp: type_name.GetSP())); |
1628 | } |
1629 | |
1630 | SBTypeFilter SBDebugger::GetFilterForType(SBTypeNameSpecifier type_name) { |
1631 | LLDB_INSTRUMENT_VA(this, type_name); |
1632 | |
1633 | if (!type_name.IsValid()) |
1634 | return SBTypeFilter(); |
1635 | return SBTypeFilter(DataVisualization::GetFilterForType(type_sp: type_name.GetSP())); |
1636 | } |
1637 | |
1638 | SBTypeSynthetic SBDebugger::GetSyntheticForType(SBTypeNameSpecifier type_name) { |
1639 | LLDB_INSTRUMENT_VA(this, type_name); |
1640 | |
1641 | if (!type_name.IsValid()) |
1642 | return SBTypeSynthetic(); |
1643 | return SBTypeSynthetic( |
1644 | DataVisualization::GetSyntheticForType(type_sp: type_name.GetSP())); |
1645 | } |
1646 | |
1647 | void SBDebugger::ResetStatistics() { |
1648 | LLDB_INSTRUMENT_VA(this); |
1649 | if (m_opaque_sp) |
1650 | DebuggerStats::ResetStatistics(debugger&: *m_opaque_sp, target: nullptr); |
1651 | } |
1652 | |
1653 | static llvm::ArrayRef<const char *> GetCategoryArray(const char **categories) { |
1654 | if (categories == nullptr) |
1655 | return {}; |
1656 | size_t len = 0; |
1657 | while (categories[len] != nullptr) |
1658 | ++len; |
1659 | return llvm::ArrayRef(categories, len); |
1660 | } |
1661 | |
1662 | bool SBDebugger::EnableLog(const char *channel, const char **categories) { |
1663 | LLDB_INSTRUMENT_VA(this, channel, categories); |
1664 | |
1665 | if (m_opaque_sp) { |
1666 | uint32_t log_options = |
1667 | LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; |
1668 | std::string error; |
1669 | llvm::raw_string_ostream error_stream(error); |
1670 | return m_opaque_sp->EnableLog(channel, categories: GetCategoryArray(categories), log_file: "", |
1671 | log_options, /*buffer_size=*/0, |
1672 | log_handler_kind: eLogHandlerStream, error_stream); |
1673 | } else |
1674 | return false; |
1675 | } |
1676 | |
1677 | void SBDebugger::SetLoggingCallback(lldb::LogOutputCallback log_callback, |
1678 | void *baton) { |
1679 | LLDB_INSTRUMENT_VA(this, log_callback, baton); |
1680 | |
1681 | if (m_opaque_sp) { |
1682 | return m_opaque_sp->SetLoggingCallback(log_callback, baton); |
1683 | } |
1684 | } |
1685 | |
1686 | void SBDebugger::SetDestroyCallback( |
1687 | lldb::SBDebuggerDestroyCallback destroy_callback, void *baton) { |
1688 | LLDB_INSTRUMENT_VA(this, destroy_callback, baton); |
1689 | if (m_opaque_sp) { |
1690 | return m_opaque_sp->SetDestroyCallback( |
1691 | destroy_callback, baton); |
1692 | } |
1693 | } |
1694 | |
1695 | lldb::callback_token_t |
1696 | SBDebugger::AddDestroyCallback(lldb::SBDebuggerDestroyCallback destroy_callback, |
1697 | void *baton) { |
1698 | LLDB_INSTRUMENT_VA(this, destroy_callback, baton); |
1699 | |
1700 | if (m_opaque_sp) |
1701 | return m_opaque_sp->AddDestroyCallback(destroy_callback, baton); |
1702 | |
1703 | return LLDB_INVALID_CALLBACK_TOKEN; |
1704 | } |
1705 | |
1706 | bool SBDebugger::RemoveDestroyCallback(lldb::callback_token_t token) { |
1707 | LLDB_INSTRUMENT_VA(this, token); |
1708 | |
1709 | if (m_opaque_sp) |
1710 | return m_opaque_sp->RemoveDestroyCallback(token); |
1711 | |
1712 | return false; |
1713 | } |
1714 | |
1715 | SBTrace |
1716 | SBDebugger::LoadTraceFromFile(SBError &error, |
1717 | const SBFileSpec &trace_description_file) { |
1718 | LLDB_INSTRUMENT_VA(this, error, trace_description_file); |
1719 | return SBTrace::LoadTraceFromFile(error, debugger&: *this, trace_description_file); |
1720 | } |
1721 | |
1722 | void SBDebugger::RequestInterrupt() { |
1723 | LLDB_INSTRUMENT_VA(this); |
1724 | |
1725 | if (m_opaque_sp) |
1726 | m_opaque_sp->RequestInterrupt(); |
1727 | } |
1728 | void SBDebugger::CancelInterruptRequest() { |
1729 | LLDB_INSTRUMENT_VA(this); |
1730 | |
1731 | if (m_opaque_sp) |
1732 | m_opaque_sp->CancelInterruptRequest(); |
1733 | } |
1734 | |
1735 | bool SBDebugger::InterruptRequested() { |
1736 | LLDB_INSTRUMENT_VA(this); |
1737 | |
1738 | if (m_opaque_sp) |
1739 | return m_opaque_sp->InterruptRequested(); |
1740 | return false; |
1741 | } |
1742 | |
1743 | bool SBDebugger::SupportsLanguage(lldb::LanguageType language) { |
1744 | return TypeSystem::SupportsLanguageStatic(language); |
1745 | } |
1746 |
Definitions
- g_debugger_lifetime
- Initialize
- SetIsDone
- IsActive
- SBDebugger
- SBDebugger
- SBDebugger
- ~SBDebugger
- operator=
- GetBroadcasterClass
- GetProgressFromEvent
- GetProgressDataFromEvent
- GetDiagnosticFromEvent
- GetBroadcaster
- Initialize
- InitializeWithErrorHandling
- PrintStackTraceOnError
- DumpDiagnostics
- PrintDiagnosticsOnError
- Terminate
- Clear
- Create
- Create
- Create
- Destroy
- MemoryPressureDetected
- IsValid
- operator bool
- SetAsync
- GetAsync
- SkipLLDBInitFiles
- SkipAppInitFiles
- SetInputFileHandle
- SetInputString
- SetInputFile
- SetInputFile
- SetOutputFile
- SetOutputFileHandle
- SetOutputFile
- SetErrorFileHandle
- SetErrorFile
- SetErrorFile
- GetSetting
- GetInputFileHandle
- GetInputFile
- GetOutputFileHandle
- GetOutputFile
- GetErrorFileHandle
- GetErrorFile
- SaveInputTerminalState
- RestoreInputTerminalState
- GetCommandInterpreter
- HandleCommand
- GetListener
- HandleProcessEvent
- HandleProcessEvent
- HandleProcessEvent
- GetSourceManager
- GetDefaultArchitecture
- SetDefaultArchitecture
- GetScriptingLanguage
- GetScriptInterpreterInfo
- GetVersionString
- StateAsCString
- AddBoolConfigEntry
- AddLLVMTargets
- GetBuildConfiguration
- StateIsRunningState
- StateIsStoppedState
- CreateTarget
- CreateTargetWithFileAndTargetTriple
- CreateTargetWithFileAndArch
- CreateTarget
- GetDummyTarget
- DispatchClientTelemetry
- DeleteTarget
- GetTargetAtIndex
- GetIndexOfTarget
- FindTargetWithProcessID
- FindTargetWithFileAndArch
- FindTargetWithLLDBProcess
- GetNumTargets
- GetSelectedTarget
- SetSelectedTarget
- GetSelectedPlatform
- SetSelectedPlatform
- GetNumPlatforms
- GetPlatformAtIndex
- GetNumAvailablePlatforms
- GetAvailablePlatformInfoAtIndex
- DispatchInput
- DispatchInput
- DispatchInputInterrupt
- DispatchInputEndOfFile
- PushInputReader
- RunCommandInterpreter
- RunCommandInterpreter
- RunCommandInterpreter
- RunREPL
- reset
- get
- ref
- get_sp
- FindDebuggerWithID
- GetInstanceName
- SetInternalVariable
- GetInternalVariableValue
- GetTerminalWidth
- SetTerminalWidth
- GetTerminalHeight
- SetTerminalHeight
- GetPrompt
- SetPrompt
- GetReproducerPath
- GetScriptLanguage
- SetScriptLanguage
- GetREPLLanguage
- SetREPLLanguage
- SetUseExternalEditor
- GetUseExternalEditor
- SetUseColor
- GetUseColor
- SetShowInlineDiagnostics
- SetUseSourceCache
- GetUseSourceCache
- GetDescription
- GetID
- SetCurrentPlatform
- SetCurrentPlatformSDKRoot
- GetCloseInputOnEOF
- SetCloseInputOnEOF
- GetCategory
- GetCategory
- CreateCategory
- DeleteCategory
- GetNumCategories
- GetCategoryAtIndex
- GetDefaultCategory
- GetFormatForType
- GetSummaryForType
- GetFilterForType
- GetSyntheticForType
- ResetStatistics
- GetCategoryArray
- EnableLog
- SetLoggingCallback
- SetDestroyCallback
- AddDestroyCallback
- RemoveDestroyCallback
- LoadTraceFromFile
- RequestInterrupt
- CancelInterruptRequest
- InterruptRequested
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more