Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Core/Debugger.cpp
39587 views
1
//===-- Debugger.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/Core/Debugger.h"
10
11
#include "lldb/Breakpoint/Breakpoint.h"
12
#include "lldb/Core/DebuggerEvents.h"
13
#include "lldb/Core/FormatEntity.h"
14
#include "lldb/Core/Mangled.h"
15
#include "lldb/Core/ModuleList.h"
16
#include "lldb/Core/ModuleSpec.h"
17
#include "lldb/Core/PluginManager.h"
18
#include "lldb/Core/Progress.h"
19
#include "lldb/Core/StreamAsynchronousIO.h"
20
#include "lldb/DataFormatters/DataVisualization.h"
21
#include "lldb/Expression/REPL.h"
22
#include "lldb/Host/File.h"
23
#include "lldb/Host/FileSystem.h"
24
#include "lldb/Host/HostInfo.h"
25
#include "lldb/Host/StreamFile.h"
26
#include "lldb/Host/Terminal.h"
27
#include "lldb/Host/ThreadLauncher.h"
28
#include "lldb/Interpreter/CommandInterpreter.h"
29
#include "lldb/Interpreter/CommandReturnObject.h"
30
#include "lldb/Interpreter/OptionValue.h"
31
#include "lldb/Interpreter/OptionValueLanguage.h"
32
#include "lldb/Interpreter/OptionValueProperties.h"
33
#include "lldb/Interpreter/OptionValueSInt64.h"
34
#include "lldb/Interpreter/OptionValueString.h"
35
#include "lldb/Interpreter/Property.h"
36
#include "lldb/Interpreter/ScriptInterpreter.h"
37
#include "lldb/Symbol/Function.h"
38
#include "lldb/Symbol/Symbol.h"
39
#include "lldb/Symbol/SymbolContext.h"
40
#include "lldb/Target/Language.h"
41
#include "lldb/Target/Process.h"
42
#include "lldb/Target/StructuredDataPlugin.h"
43
#include "lldb/Target/Target.h"
44
#include "lldb/Target/TargetList.h"
45
#include "lldb/Target/Thread.h"
46
#include "lldb/Target/ThreadList.h"
47
#include "lldb/Utility/AnsiTerminal.h"
48
#include "lldb/Utility/Event.h"
49
#include "lldb/Utility/LLDBLog.h"
50
#include "lldb/Utility/Listener.h"
51
#include "lldb/Utility/Log.h"
52
#include "lldb/Utility/State.h"
53
#include "lldb/Utility/Stream.h"
54
#include "lldb/Utility/StreamString.h"
55
#include "lldb/lldb-enumerations.h"
56
57
#if defined(_WIN32)
58
#include "lldb/Host/windows/PosixApi.h"
59
#include "lldb/Host/windows/windows.h"
60
#endif
61
62
#include "llvm/ADT/STLExtras.h"
63
#include "llvm/ADT/StringRef.h"
64
#include "llvm/ADT/iterator.h"
65
#include "llvm/Support/DynamicLibrary.h"
66
#include "llvm/Support/FileSystem.h"
67
#include "llvm/Support/Process.h"
68
#include "llvm/Support/ThreadPool.h"
69
#include "llvm/Support/Threading.h"
70
#include "llvm/Support/raw_ostream.h"
71
72
#include <cstdio>
73
#include <cstdlib>
74
#include <cstring>
75
#include <list>
76
#include <memory>
77
#include <mutex>
78
#include <optional>
79
#include <set>
80
#include <string>
81
#include <system_error>
82
83
// Includes for pipe()
84
#if defined(_WIN32)
85
#include <fcntl.h>
86
#include <io.h>
87
#else
88
#include <unistd.h>
89
#endif
90
91
namespace lldb_private {
92
class Address;
93
}
94
95
using namespace lldb;
96
using namespace lldb_private;
97
98
static lldb::user_id_t g_unique_id = 1;
99
static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024;
100
101
#pragma mark Static Functions
102
103
static std::recursive_mutex *g_debugger_list_mutex_ptr =
104
nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
105
static Debugger::DebuggerList *g_debugger_list_ptr =
106
nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
107
static llvm::DefaultThreadPool *g_thread_pool = nullptr;
108
109
static constexpr OptionEnumValueElement g_show_disassembly_enum_values[] = {
110
{
111
Debugger::eStopDisassemblyTypeNever,
112
"never",
113
"Never show disassembly when displaying a stop context.",
114
},
115
{
116
Debugger::eStopDisassemblyTypeNoDebugInfo,
117
"no-debuginfo",
118
"Show disassembly when there is no debug information.",
119
},
120
{
121
Debugger::eStopDisassemblyTypeNoSource,
122
"no-source",
123
"Show disassembly when there is no source information, or the source "
124
"file "
125
"is missing when displaying a stop context.",
126
},
127
{
128
Debugger::eStopDisassemblyTypeAlways,
129
"always",
130
"Always show disassembly when displaying a stop context.",
131
},
132
};
133
134
static constexpr OptionEnumValueElement g_language_enumerators[] = {
135
{
136
eScriptLanguageNone,
137
"none",
138
"Disable scripting languages.",
139
},
140
{
141
eScriptLanguagePython,
142
"python",
143
"Select python as the default scripting language.",
144
},
145
{
146
eScriptLanguageDefault,
147
"default",
148
"Select the lldb default as the default scripting language.",
149
},
150
};
151
152
static constexpr OptionEnumValueElement g_dwim_print_verbosities[] = {
153
{eDWIMPrintVerbosityNone, "none",
154
"Use no verbosity when running dwim-print."},
155
{eDWIMPrintVerbosityExpression, "expression",
156
"Use partial verbosity when running dwim-print - display a message when "
157
"`expression` evaluation is used."},
158
{eDWIMPrintVerbosityFull, "full",
159
"Use full verbosity when running dwim-print."},
160
};
161
162
static constexpr OptionEnumValueElement s_stop_show_column_values[] = {
163
{
164
eStopShowColumnAnsiOrCaret,
165
"ansi-or-caret",
166
"Highlight the stop column with ANSI terminal codes when color/ANSI "
167
"mode is enabled; otherwise, fall back to using a text-only caret (^) "
168
"as if \"caret-only\" mode was selected.",
169
},
170
{
171
eStopShowColumnAnsi,
172
"ansi",
173
"Highlight the stop column with ANSI terminal codes when running LLDB "
174
"with color/ANSI enabled.",
175
},
176
{
177
eStopShowColumnCaret,
178
"caret",
179
"Highlight the stop column with a caret character (^) underneath the "
180
"stop column. This method introduces a new line in source listings "
181
"that display thread stop locations.",
182
},
183
{
184
eStopShowColumnNone,
185
"none",
186
"Do not highlight the stop column.",
187
},
188
};
189
190
#define LLDB_PROPERTIES_debugger
191
#include "CoreProperties.inc"
192
193
enum {
194
#define LLDB_PROPERTIES_debugger
195
#include "CorePropertiesEnum.inc"
196
};
197
198
LoadPluginCallbackType Debugger::g_load_plugin_callback = nullptr;
199
200
Status Debugger::SetPropertyValue(const ExecutionContext *exe_ctx,
201
VarSetOperationType op,
202
llvm::StringRef property_path,
203
llvm::StringRef value) {
204
bool is_load_script =
205
(property_path == "target.load-script-from-symbol-file");
206
// These properties might change how we visualize data.
207
bool invalidate_data_vis = (property_path == "escape-non-printables");
208
invalidate_data_vis |=
209
(property_path == "target.max-zero-padding-in-float-format");
210
if (invalidate_data_vis) {
211
DataVisualization::ForceUpdate();
212
}
213
214
TargetSP target_sp;
215
LoadScriptFromSymFile load_script_old_value = eLoadScriptFromSymFileFalse;
216
if (is_load_script && exe_ctx && exe_ctx->GetTargetSP()) {
217
target_sp = exe_ctx->GetTargetSP();
218
load_script_old_value =
219
target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
220
}
221
Status error(Properties::SetPropertyValue(exe_ctx, op, property_path, value));
222
if (error.Success()) {
223
// FIXME it would be nice to have "on-change" callbacks for properties
224
if (property_path == g_debugger_properties[ePropertyPrompt].name) {
225
llvm::StringRef new_prompt = GetPrompt();
226
std::string str = lldb_private::ansi::FormatAnsiTerminalCodes(
227
new_prompt, GetUseColor());
228
if (str.length())
229
new_prompt = str;
230
GetCommandInterpreter().UpdatePrompt(new_prompt);
231
auto bytes = std::make_unique<EventDataBytes>(new_prompt);
232
auto prompt_change_event_sp = std::make_shared<Event>(
233
CommandInterpreter::eBroadcastBitResetPrompt, bytes.release());
234
GetCommandInterpreter().BroadcastEvent(prompt_change_event_sp);
235
} else if (property_path == g_debugger_properties[ePropertyUseColor].name) {
236
// use-color changed. Ping the prompt so it can reset the ansi terminal
237
// codes.
238
SetPrompt(GetPrompt());
239
} else if (property_path ==
240
g_debugger_properties[ePropertyPromptAnsiPrefix].name ||
241
property_path ==
242
g_debugger_properties[ePropertyPromptAnsiSuffix].name) {
243
// Prompt colors changed. Ping the prompt so it can reset the ansi
244
// terminal codes.
245
SetPrompt(GetPrompt());
246
} else if (property_path ==
247
g_debugger_properties[ePropertyUseSourceCache].name) {
248
// use-source-cache changed. Wipe out the cache contents if it was
249
// disabled.
250
if (!GetUseSourceCache()) {
251
m_source_file_cache.Clear();
252
}
253
} else if (is_load_script && target_sp &&
254
load_script_old_value == eLoadScriptFromSymFileWarn) {
255
if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() ==
256
eLoadScriptFromSymFileTrue) {
257
std::list<Status> errors;
258
StreamString feedback_stream;
259
if (!target_sp->LoadScriptingResources(errors, feedback_stream)) {
260
Stream &s = GetErrorStream();
261
for (auto error : errors) {
262
s.Printf("%s\n", error.AsCString());
263
}
264
if (feedback_stream.GetSize())
265
s.PutCString(feedback_stream.GetString());
266
}
267
}
268
}
269
}
270
return error;
271
}
272
273
bool Debugger::GetAutoConfirm() const {
274
constexpr uint32_t idx = ePropertyAutoConfirm;
275
return GetPropertyAtIndexAs<bool>(
276
idx, g_debugger_properties[idx].default_uint_value != 0);
277
}
278
279
const FormatEntity::Entry *Debugger::GetDisassemblyFormat() const {
280
constexpr uint32_t idx = ePropertyDisassemblyFormat;
281
return GetPropertyAtIndexAs<const FormatEntity::Entry *>(idx);
282
}
283
284
const FormatEntity::Entry *Debugger::GetFrameFormat() const {
285
constexpr uint32_t idx = ePropertyFrameFormat;
286
return GetPropertyAtIndexAs<const FormatEntity::Entry *>(idx);
287
}
288
289
const FormatEntity::Entry *Debugger::GetFrameFormatUnique() const {
290
constexpr uint32_t idx = ePropertyFrameFormatUnique;
291
return GetPropertyAtIndexAs<const FormatEntity::Entry *>(idx);
292
}
293
294
uint64_t Debugger::GetStopDisassemblyMaxSize() const {
295
constexpr uint32_t idx = ePropertyStopDisassemblyMaxSize;
296
return GetPropertyAtIndexAs<uint64_t>(
297
idx, g_debugger_properties[idx].default_uint_value);
298
}
299
300
bool Debugger::GetNotifyVoid() const {
301
constexpr uint32_t idx = ePropertyNotiftVoid;
302
return GetPropertyAtIndexAs<uint64_t>(
303
idx, g_debugger_properties[idx].default_uint_value != 0);
304
}
305
306
llvm::StringRef Debugger::GetPrompt() const {
307
constexpr uint32_t idx = ePropertyPrompt;
308
return GetPropertyAtIndexAs<llvm::StringRef>(
309
idx, g_debugger_properties[idx].default_cstr_value);
310
}
311
312
llvm::StringRef Debugger::GetPromptAnsiPrefix() const {
313
const uint32_t idx = ePropertyPromptAnsiPrefix;
314
return GetPropertyAtIndexAs<llvm::StringRef>(
315
idx, g_debugger_properties[idx].default_cstr_value);
316
}
317
318
llvm::StringRef Debugger::GetPromptAnsiSuffix() const {
319
const uint32_t idx = ePropertyPromptAnsiSuffix;
320
return GetPropertyAtIndexAs<llvm::StringRef>(
321
idx, g_debugger_properties[idx].default_cstr_value);
322
}
323
324
void Debugger::SetPrompt(llvm::StringRef p) {
325
constexpr uint32_t idx = ePropertyPrompt;
326
SetPropertyAtIndex(idx, p);
327
llvm::StringRef new_prompt = GetPrompt();
328
std::string str =
329
lldb_private::ansi::FormatAnsiTerminalCodes(new_prompt, GetUseColor());
330
if (str.length())
331
new_prompt = str;
332
GetCommandInterpreter().UpdatePrompt(new_prompt);
333
}
334
335
const FormatEntity::Entry *Debugger::GetThreadFormat() const {
336
constexpr uint32_t idx = ePropertyThreadFormat;
337
return GetPropertyAtIndexAs<const FormatEntity::Entry *>(idx);
338
}
339
340
const FormatEntity::Entry *Debugger::GetThreadStopFormat() const {
341
constexpr uint32_t idx = ePropertyThreadStopFormat;
342
return GetPropertyAtIndexAs<const FormatEntity::Entry *>(idx);
343
}
344
345
lldb::ScriptLanguage Debugger::GetScriptLanguage() const {
346
const uint32_t idx = ePropertyScriptLanguage;
347
return GetPropertyAtIndexAs<lldb::ScriptLanguage>(
348
idx, static_cast<lldb::ScriptLanguage>(
349
g_debugger_properties[idx].default_uint_value));
350
}
351
352
bool Debugger::SetScriptLanguage(lldb::ScriptLanguage script_lang) {
353
const uint32_t idx = ePropertyScriptLanguage;
354
return SetPropertyAtIndex(idx, script_lang);
355
}
356
357
lldb::LanguageType Debugger::GetREPLLanguage() const {
358
const uint32_t idx = ePropertyREPLLanguage;
359
return GetPropertyAtIndexAs<LanguageType>(idx, {});
360
}
361
362
bool Debugger::SetREPLLanguage(lldb::LanguageType repl_lang) {
363
const uint32_t idx = ePropertyREPLLanguage;
364
return SetPropertyAtIndex(idx, repl_lang);
365
}
366
367
uint64_t Debugger::GetTerminalWidth() const {
368
const uint32_t idx = ePropertyTerminalWidth;
369
return GetPropertyAtIndexAs<uint64_t>(
370
idx, g_debugger_properties[idx].default_uint_value);
371
}
372
373
bool Debugger::SetTerminalWidth(uint64_t term_width) {
374
if (auto handler_sp = m_io_handler_stack.Top())
375
handler_sp->TerminalSizeChanged();
376
377
const uint32_t idx = ePropertyTerminalWidth;
378
return SetPropertyAtIndex(idx, term_width);
379
}
380
381
bool Debugger::GetUseExternalEditor() const {
382
const uint32_t idx = ePropertyUseExternalEditor;
383
return GetPropertyAtIndexAs<bool>(
384
idx, g_debugger_properties[idx].default_uint_value != 0);
385
}
386
387
bool Debugger::SetUseExternalEditor(bool b) {
388
const uint32_t idx = ePropertyUseExternalEditor;
389
return SetPropertyAtIndex(idx, b);
390
}
391
392
llvm::StringRef Debugger::GetExternalEditor() const {
393
const uint32_t idx = ePropertyExternalEditor;
394
return GetPropertyAtIndexAs<llvm::StringRef>(
395
idx, g_debugger_properties[idx].default_cstr_value);
396
}
397
398
bool Debugger::SetExternalEditor(llvm::StringRef editor) {
399
const uint32_t idx = ePropertyExternalEditor;
400
return SetPropertyAtIndex(idx, editor);
401
}
402
403
bool Debugger::GetUseColor() const {
404
const uint32_t idx = ePropertyUseColor;
405
return GetPropertyAtIndexAs<bool>(
406
idx, g_debugger_properties[idx].default_uint_value != 0);
407
}
408
409
bool Debugger::SetUseColor(bool b) {
410
const uint32_t idx = ePropertyUseColor;
411
bool ret = SetPropertyAtIndex(idx, b);
412
SetPrompt(GetPrompt());
413
return ret;
414
}
415
416
bool Debugger::GetShowProgress() const {
417
const uint32_t idx = ePropertyShowProgress;
418
return GetPropertyAtIndexAs<bool>(
419
idx, g_debugger_properties[idx].default_uint_value != 0);
420
}
421
422
bool Debugger::SetShowProgress(bool show_progress) {
423
const uint32_t idx = ePropertyShowProgress;
424
return SetPropertyAtIndex(idx, show_progress);
425
}
426
427
llvm::StringRef Debugger::GetShowProgressAnsiPrefix() const {
428
const uint32_t idx = ePropertyShowProgressAnsiPrefix;
429
return GetPropertyAtIndexAs<llvm::StringRef>(
430
idx, g_debugger_properties[idx].default_cstr_value);
431
}
432
433
llvm::StringRef Debugger::GetShowProgressAnsiSuffix() const {
434
const uint32_t idx = ePropertyShowProgressAnsiSuffix;
435
return GetPropertyAtIndexAs<llvm::StringRef>(
436
idx, g_debugger_properties[idx].default_cstr_value);
437
}
438
439
bool Debugger::GetUseAutosuggestion() const {
440
const uint32_t idx = ePropertyShowAutosuggestion;
441
return GetPropertyAtIndexAs<bool>(
442
idx, g_debugger_properties[idx].default_uint_value != 0);
443
}
444
445
llvm::StringRef Debugger::GetAutosuggestionAnsiPrefix() const {
446
const uint32_t idx = ePropertyShowAutosuggestionAnsiPrefix;
447
return GetPropertyAtIndexAs<llvm::StringRef>(
448
idx, g_debugger_properties[idx].default_cstr_value);
449
}
450
451
llvm::StringRef Debugger::GetAutosuggestionAnsiSuffix() const {
452
const uint32_t idx = ePropertyShowAutosuggestionAnsiSuffix;
453
return GetPropertyAtIndexAs<llvm::StringRef>(
454
idx, g_debugger_properties[idx].default_cstr_value);
455
}
456
457
llvm::StringRef Debugger::GetRegexMatchAnsiPrefix() const {
458
const uint32_t idx = ePropertyShowRegexMatchAnsiPrefix;
459
return GetPropertyAtIndexAs<llvm::StringRef>(
460
idx, g_debugger_properties[idx].default_cstr_value);
461
}
462
463
llvm::StringRef Debugger::GetRegexMatchAnsiSuffix() const {
464
const uint32_t idx = ePropertyShowRegexMatchAnsiSuffix;
465
return GetPropertyAtIndexAs<llvm::StringRef>(
466
idx, g_debugger_properties[idx].default_cstr_value);
467
}
468
469
bool Debugger::GetShowDontUsePoHint() const {
470
const uint32_t idx = ePropertyShowDontUsePoHint;
471
return GetPropertyAtIndexAs<bool>(
472
idx, g_debugger_properties[idx].default_uint_value != 0);
473
}
474
475
bool Debugger::GetUseSourceCache() const {
476
const uint32_t idx = ePropertyUseSourceCache;
477
return GetPropertyAtIndexAs<bool>(
478
idx, g_debugger_properties[idx].default_uint_value != 0);
479
}
480
481
bool Debugger::SetUseSourceCache(bool b) {
482
const uint32_t idx = ePropertyUseSourceCache;
483
bool ret = SetPropertyAtIndex(idx, b);
484
if (!ret) {
485
m_source_file_cache.Clear();
486
}
487
return ret;
488
}
489
bool Debugger::GetHighlightSource() const {
490
const uint32_t idx = ePropertyHighlightSource;
491
return GetPropertyAtIndexAs<bool>(
492
idx, g_debugger_properties[idx].default_uint_value != 0);
493
}
494
495
StopShowColumn Debugger::GetStopShowColumn() const {
496
const uint32_t idx = ePropertyStopShowColumn;
497
return GetPropertyAtIndexAs<lldb::StopShowColumn>(
498
idx, static_cast<lldb::StopShowColumn>(
499
g_debugger_properties[idx].default_uint_value));
500
}
501
502
llvm::StringRef Debugger::GetStopShowColumnAnsiPrefix() const {
503
const uint32_t idx = ePropertyStopShowColumnAnsiPrefix;
504
return GetPropertyAtIndexAs<llvm::StringRef>(
505
idx, g_debugger_properties[idx].default_cstr_value);
506
}
507
508
llvm::StringRef Debugger::GetStopShowColumnAnsiSuffix() const {
509
const uint32_t idx = ePropertyStopShowColumnAnsiSuffix;
510
return GetPropertyAtIndexAs<llvm::StringRef>(
511
idx, g_debugger_properties[idx].default_cstr_value);
512
}
513
514
llvm::StringRef Debugger::GetStopShowLineMarkerAnsiPrefix() const {
515
const uint32_t idx = ePropertyStopShowLineMarkerAnsiPrefix;
516
return GetPropertyAtIndexAs<llvm::StringRef>(
517
idx, g_debugger_properties[idx].default_cstr_value);
518
}
519
520
llvm::StringRef Debugger::GetStopShowLineMarkerAnsiSuffix() const {
521
const uint32_t idx = ePropertyStopShowLineMarkerAnsiSuffix;
522
return GetPropertyAtIndexAs<llvm::StringRef>(
523
idx, g_debugger_properties[idx].default_cstr_value);
524
}
525
526
uint64_t Debugger::GetStopSourceLineCount(bool before) const {
527
const uint32_t idx =
528
before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
529
return GetPropertyAtIndexAs<uint64_t>(
530
idx, g_debugger_properties[idx].default_uint_value);
531
}
532
533
Debugger::StopDisassemblyType Debugger::GetStopDisassemblyDisplay() const {
534
const uint32_t idx = ePropertyStopDisassemblyDisplay;
535
return GetPropertyAtIndexAs<Debugger::StopDisassemblyType>(
536
idx, static_cast<Debugger::StopDisassemblyType>(
537
g_debugger_properties[idx].default_uint_value));
538
}
539
540
uint64_t Debugger::GetDisassemblyLineCount() const {
541
const uint32_t idx = ePropertyStopDisassemblyCount;
542
return GetPropertyAtIndexAs<uint64_t>(
543
idx, g_debugger_properties[idx].default_uint_value);
544
}
545
546
bool Debugger::GetAutoOneLineSummaries() const {
547
const uint32_t idx = ePropertyAutoOneLineSummaries;
548
return GetPropertyAtIndexAs<bool>(
549
idx, g_debugger_properties[idx].default_uint_value != 0);
550
}
551
552
bool Debugger::GetEscapeNonPrintables() const {
553
const uint32_t idx = ePropertyEscapeNonPrintables;
554
return GetPropertyAtIndexAs<bool>(
555
idx, g_debugger_properties[idx].default_uint_value != 0);
556
}
557
558
bool Debugger::GetAutoIndent() const {
559
const uint32_t idx = ePropertyAutoIndent;
560
return GetPropertyAtIndexAs<bool>(
561
idx, g_debugger_properties[idx].default_uint_value != 0);
562
}
563
564
bool Debugger::SetAutoIndent(bool b) {
565
const uint32_t idx = ePropertyAutoIndent;
566
return SetPropertyAtIndex(idx, b);
567
}
568
569
bool Debugger::GetPrintDecls() const {
570
const uint32_t idx = ePropertyPrintDecls;
571
return GetPropertyAtIndexAs<bool>(
572
idx, g_debugger_properties[idx].default_uint_value != 0);
573
}
574
575
bool Debugger::SetPrintDecls(bool b) {
576
const uint32_t idx = ePropertyPrintDecls;
577
return SetPropertyAtIndex(idx, b);
578
}
579
580
uint64_t Debugger::GetTabSize() const {
581
const uint32_t idx = ePropertyTabSize;
582
return GetPropertyAtIndexAs<uint64_t>(
583
idx, g_debugger_properties[idx].default_uint_value);
584
}
585
586
bool Debugger::SetTabSize(uint64_t tab_size) {
587
const uint32_t idx = ePropertyTabSize;
588
return SetPropertyAtIndex(idx, tab_size);
589
}
590
591
lldb::DWIMPrintVerbosity Debugger::GetDWIMPrintVerbosity() const {
592
const uint32_t idx = ePropertyDWIMPrintVerbosity;
593
return GetPropertyAtIndexAs<lldb::DWIMPrintVerbosity>(
594
idx, static_cast<lldb::DWIMPrintVerbosity>(
595
g_debugger_properties[idx].default_uint_value));
596
}
597
598
#pragma mark Debugger
599
600
// const DebuggerPropertiesSP &
601
// Debugger::GetSettings() const
602
//{
603
// return m_properties_sp;
604
//}
605
//
606
607
void Debugger::Initialize(LoadPluginCallbackType load_plugin_callback) {
608
assert(g_debugger_list_ptr == nullptr &&
609
"Debugger::Initialize called more than once!");
610
g_debugger_list_mutex_ptr = new std::recursive_mutex();
611
g_debugger_list_ptr = new DebuggerList();
612
g_thread_pool = new llvm::DefaultThreadPool(llvm::optimal_concurrency());
613
g_load_plugin_callback = load_plugin_callback;
614
}
615
616
void Debugger::Terminate() {
617
assert(g_debugger_list_ptr &&
618
"Debugger::Terminate called without a matching Debugger::Initialize!");
619
620
if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
621
std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
622
for (const auto &debugger : *g_debugger_list_ptr)
623
debugger->HandleDestroyCallback();
624
}
625
626
if (g_thread_pool) {
627
// The destructor will wait for all the threads to complete.
628
delete g_thread_pool;
629
}
630
631
if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
632
// Clear our global list of debugger objects
633
{
634
std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
635
for (const auto &debugger : *g_debugger_list_ptr)
636
debugger->Clear();
637
g_debugger_list_ptr->clear();
638
}
639
}
640
}
641
642
void Debugger::SettingsInitialize() { Target::SettingsInitialize(); }
643
644
void Debugger::SettingsTerminate() { Target::SettingsTerminate(); }
645
646
bool Debugger::LoadPlugin(const FileSpec &spec, Status &error) {
647
if (g_load_plugin_callback) {
648
llvm::sys::DynamicLibrary dynlib =
649
g_load_plugin_callback(shared_from_this(), spec, error);
650
if (dynlib.isValid()) {
651
m_loaded_plugins.push_back(dynlib);
652
return true;
653
}
654
} else {
655
// The g_load_plugin_callback is registered in SBDebugger::Initialize() and
656
// if the public API layer isn't available (code is linking against all of
657
// the internal LLDB static libraries), then we can't load plugins
658
error.SetErrorString("Public API layer is not available");
659
}
660
return false;
661
}
662
663
static FileSystem::EnumerateDirectoryResult
664
LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
665
llvm::StringRef path) {
666
Status error;
667
668
static constexpr llvm::StringLiteral g_dylibext(".dylib");
669
static constexpr llvm::StringLiteral g_solibext(".so");
670
671
if (!baton)
672
return FileSystem::eEnumerateDirectoryResultQuit;
673
674
Debugger *debugger = (Debugger *)baton;
675
676
namespace fs = llvm::sys::fs;
677
// If we have a regular file, a symbolic link or unknown file type, try and
678
// process the file. We must handle unknown as sometimes the directory
679
// enumeration might be enumerating a file system that doesn't have correct
680
// file type information.
681
if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file ||
682
ft == fs::file_type::type_unknown) {
683
FileSpec plugin_file_spec(path);
684
FileSystem::Instance().Resolve(plugin_file_spec);
685
686
if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
687
plugin_file_spec.GetFileNameExtension() != g_solibext) {
688
return FileSystem::eEnumerateDirectoryResultNext;
689
}
690
691
Status plugin_load_error;
692
debugger->LoadPlugin(plugin_file_spec, plugin_load_error);
693
694
return FileSystem::eEnumerateDirectoryResultNext;
695
} else if (ft == fs::file_type::directory_file ||
696
ft == fs::file_type::symlink_file ||
697
ft == fs::file_type::type_unknown) {
698
// Try and recurse into anything that a directory or symbolic link. We must
699
// also do this for unknown as sometimes the directory enumeration might be
700
// enumerating a file system that doesn't have correct file type
701
// information.
702
return FileSystem::eEnumerateDirectoryResultEnter;
703
}
704
705
return FileSystem::eEnumerateDirectoryResultNext;
706
}
707
708
void Debugger::InstanceInitialize() {
709
const bool find_directories = true;
710
const bool find_files = true;
711
const bool find_other = true;
712
char dir_path[PATH_MAX];
713
if (FileSpec dir_spec = HostInfo::GetSystemPluginDir()) {
714
if (FileSystem::Instance().Exists(dir_spec) &&
715
dir_spec.GetPath(dir_path, sizeof(dir_path))) {
716
FileSystem::Instance().EnumerateDirectory(dir_path, find_directories,
717
find_files, find_other,
718
LoadPluginCallback, this);
719
}
720
}
721
722
if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) {
723
if (FileSystem::Instance().Exists(dir_spec) &&
724
dir_spec.GetPath(dir_path, sizeof(dir_path))) {
725
FileSystem::Instance().EnumerateDirectory(dir_path, find_directories,
726
find_files, find_other,
727
LoadPluginCallback, this);
728
}
729
}
730
731
PluginManager::DebuggerInitialize(*this);
732
}
733
734
DebuggerSP Debugger::CreateInstance(lldb::LogOutputCallback log_callback,
735
void *baton) {
736
DebuggerSP debugger_sp(new Debugger(log_callback, baton));
737
if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
738
std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
739
g_debugger_list_ptr->push_back(debugger_sp);
740
}
741
debugger_sp->InstanceInitialize();
742
return debugger_sp;
743
}
744
745
void Debugger::HandleDestroyCallback() {
746
const lldb::user_id_t user_id = GetID();
747
// Invoke and remove all the callbacks in an FIFO order. Callbacks which are
748
// added during this loop will be appended, invoked and then removed last.
749
// Callbacks which are removed during this loop will not be invoked.
750
while (true) {
751
DestroyCallbackInfo callback_info;
752
{
753
std::lock_guard<std::mutex> guard(m_destroy_callback_mutex);
754
if (m_destroy_callbacks.empty())
755
break;
756
// Pop the first item in the list
757
callback_info = m_destroy_callbacks.front();
758
m_destroy_callbacks.erase(m_destroy_callbacks.begin());
759
}
760
// Call the destroy callback with user id and baton
761
callback_info.callback(user_id, callback_info.baton);
762
}
763
}
764
765
void Debugger::Destroy(DebuggerSP &debugger_sp) {
766
if (!debugger_sp)
767
return;
768
769
debugger_sp->HandleDestroyCallback();
770
CommandInterpreter &cmd_interpreter = debugger_sp->GetCommandInterpreter();
771
772
if (cmd_interpreter.GetSaveSessionOnQuit()) {
773
CommandReturnObject result(debugger_sp->GetUseColor());
774
cmd_interpreter.SaveTranscript(result);
775
if (result.Succeeded())
776
(*debugger_sp->GetAsyncOutputStream()) << result.GetOutputData() << '\n';
777
else
778
(*debugger_sp->GetAsyncErrorStream()) << result.GetErrorData() << '\n';
779
}
780
781
debugger_sp->Clear();
782
783
if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
784
std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
785
DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
786
for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
787
if ((*pos).get() == debugger_sp.get()) {
788
g_debugger_list_ptr->erase(pos);
789
return;
790
}
791
}
792
}
793
}
794
795
DebuggerSP
796
Debugger::FindDebuggerWithInstanceName(llvm::StringRef instance_name) {
797
if (!g_debugger_list_ptr || !g_debugger_list_mutex_ptr)
798
return DebuggerSP();
799
800
std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
801
for (const DebuggerSP &debugger_sp : *g_debugger_list_ptr) {
802
if (!debugger_sp)
803
continue;
804
805
if (llvm::StringRef(debugger_sp->GetInstanceName()) == instance_name)
806
return debugger_sp;
807
}
808
return DebuggerSP();
809
}
810
811
TargetSP Debugger::FindTargetWithProcessID(lldb::pid_t pid) {
812
TargetSP target_sp;
813
if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
814
std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
815
DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
816
for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
817
target_sp = (*pos)->GetTargetList().FindTargetWithProcessID(pid);
818
if (target_sp)
819
break;
820
}
821
}
822
return target_sp;
823
}
824
825
TargetSP Debugger::FindTargetWithProcess(Process *process) {
826
TargetSP target_sp;
827
if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
828
std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
829
DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
830
for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
831
target_sp = (*pos)->GetTargetList().FindTargetWithProcess(process);
832
if (target_sp)
833
break;
834
}
835
}
836
return target_sp;
837
}
838
839
llvm::StringRef Debugger::GetStaticBroadcasterClass() {
840
static constexpr llvm::StringLiteral class_name("lldb.debugger");
841
return class_name;
842
}
843
844
Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton)
845
: UserID(g_unique_id++),
846
Properties(std::make_shared<OptionValueProperties>()),
847
m_input_file_sp(std::make_shared<NativeFile>(stdin, false)),
848
m_output_stream_sp(std::make_shared<StreamFile>(stdout, false)),
849
m_error_stream_sp(std::make_shared<StreamFile>(stderr, false)),
850
m_input_recorder(nullptr),
851
m_broadcaster_manager_sp(BroadcasterManager::MakeBroadcasterManager()),
852
m_terminal_state(), m_target_list(*this), m_platform_list(),
853
m_listener_sp(Listener::MakeListener("lldb.Debugger")),
854
m_source_manager_up(), m_source_file_cache(),
855
m_command_interpreter_up(
856
std::make_unique<CommandInterpreter>(*this, false)),
857
m_io_handler_stack(),
858
m_instance_name(llvm::formatv("debugger_{0}", GetID()).str()),
859
m_loaded_plugins(), m_event_handler_thread(), m_io_handler_thread(),
860
m_sync_broadcaster(nullptr, "lldb.debugger.sync"),
861
m_broadcaster(m_broadcaster_manager_sp,
862
GetStaticBroadcasterClass().str()),
863
m_forward_listener_sp(), m_clear_once() {
864
// Initialize the debugger properties as early as possible as other parts of
865
// LLDB will start querying them during construction.
866
m_collection_sp->Initialize(g_debugger_properties);
867
m_collection_sp->AppendProperty(
868
"target", "Settings specify to debugging targets.", true,
869
Target::GetGlobalProperties().GetValueProperties());
870
m_collection_sp->AppendProperty(
871
"platform", "Platform settings.", true,
872
Platform::GetGlobalPlatformProperties().GetValueProperties());
873
m_collection_sp->AppendProperty(
874
"symbols", "Symbol lookup and cache settings.", true,
875
ModuleList::GetGlobalModuleListProperties().GetValueProperties());
876
m_collection_sp->AppendProperty(
877
LanguageProperties::GetSettingName(), "Language settings.", true,
878
Language::GetGlobalLanguageProperties().GetValueProperties());
879
if (m_command_interpreter_up) {
880
m_collection_sp->AppendProperty(
881
"interpreter",
882
"Settings specify to the debugger's command interpreter.", true,
883
m_command_interpreter_up->GetValueProperties());
884
}
885
if (log_callback)
886
m_callback_handler_sp =
887
std::make_shared<CallbackLogHandler>(log_callback, baton);
888
m_command_interpreter_up->Initialize();
889
// Always add our default platform to the platform list
890
PlatformSP default_platform_sp(Platform::GetHostPlatform());
891
assert(default_platform_sp);
892
m_platform_list.Append(default_platform_sp, true);
893
894
// Create the dummy target.
895
{
896
ArchSpec arch(Target::GetDefaultArchitecture());
897
if (!arch.IsValid())
898
arch = HostInfo::GetArchitecture();
899
assert(arch.IsValid() && "No valid default or host archspec");
900
const bool is_dummy_target = true;
901
m_dummy_target_sp.reset(
902
new Target(*this, arch, default_platform_sp, is_dummy_target));
903
}
904
assert(m_dummy_target_sp.get() && "Couldn't construct dummy target?");
905
906
OptionValueUInt64 *term_width =
907
m_collection_sp->GetPropertyAtIndexAsOptionValueUInt64(
908
ePropertyTerminalWidth);
909
term_width->SetMinimumValue(10);
910
term_width->SetMaximumValue(1024);
911
912
// Turn off use-color if this is a dumb terminal.
913
const char *term = getenv("TERM");
914
if (term && !strcmp(term, "dumb"))
915
SetUseColor(false);
916
// Turn off use-color if we don't write to a terminal with color support.
917
if (!GetOutputFile().GetIsTerminalWithColors())
918
SetUseColor(false);
919
920
if (Diagnostics::Enabled()) {
921
m_diagnostics_callback_id = Diagnostics::Instance().AddCallback(
922
[this](const FileSpec &dir) -> llvm::Error {
923
for (auto &entry : m_stream_handlers) {
924
llvm::StringRef log_path = entry.first();
925
llvm::StringRef file_name = llvm::sys::path::filename(log_path);
926
FileSpec destination = dir.CopyByAppendingPathComponent(file_name);
927
std::error_code ec =
928
llvm::sys::fs::copy_file(log_path, destination.GetPath());
929
if (ec)
930
return llvm::errorCodeToError(ec);
931
}
932
return llvm::Error::success();
933
});
934
}
935
936
#if defined(_WIN32) && defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING)
937
// Enabling use of ANSI color codes because LLDB is using them to highlight
938
// text.
939
llvm::sys::Process::UseANSIEscapeCodes(true);
940
#endif
941
}
942
943
Debugger::~Debugger() { Clear(); }
944
945
void Debugger::Clear() {
946
// Make sure we call this function only once. With the C++ global destructor
947
// chain having a list of debuggers and with code that can be running on
948
// other threads, we need to ensure this doesn't happen multiple times.
949
//
950
// The following functions call Debugger::Clear():
951
// Debugger::~Debugger();
952
// static void Debugger::Destroy(lldb::DebuggerSP &debugger_sp);
953
// static void Debugger::Terminate();
954
llvm::call_once(m_clear_once, [this]() {
955
ClearIOHandlers();
956
StopIOHandlerThread();
957
StopEventHandlerThread();
958
m_listener_sp->Clear();
959
for (TargetSP target_sp : m_target_list.Targets()) {
960
if (target_sp) {
961
if (ProcessSP process_sp = target_sp->GetProcessSP())
962
process_sp->Finalize(false /* not destructing */);
963
target_sp->Destroy();
964
}
965
}
966
m_broadcaster_manager_sp->Clear();
967
968
// Close the input file _before_ we close the input read communications
969
// class as it does NOT own the input file, our m_input_file does.
970
m_terminal_state.Clear();
971
GetInputFile().Close();
972
973
m_command_interpreter_up->Clear();
974
975
if (Diagnostics::Enabled())
976
Diagnostics::Instance().RemoveCallback(m_diagnostics_callback_id);
977
});
978
}
979
980
bool Debugger::GetAsyncExecution() {
981
return !m_command_interpreter_up->GetSynchronous();
982
}
983
984
void Debugger::SetAsyncExecution(bool async_execution) {
985
m_command_interpreter_up->SetSynchronous(!async_execution);
986
}
987
988
repro::DataRecorder *Debugger::GetInputRecorder() { return m_input_recorder; }
989
990
static inline int OpenPipe(int fds[2], std::size_t size) {
991
#ifdef _WIN32
992
return _pipe(fds, size, O_BINARY);
993
#else
994
(void)size;
995
return pipe(fds);
996
#endif
997
}
998
999
Status Debugger::SetInputString(const char *data) {
1000
Status result;
1001
enum PIPES { READ, WRITE }; // Indexes for the read and write fds
1002
int fds[2] = {-1, -1};
1003
1004
if (data == nullptr) {
1005
result.SetErrorString("String data is null");
1006
return result;
1007
}
1008
1009
size_t size = strlen(data);
1010
if (size == 0) {
1011
result.SetErrorString("String data is empty");
1012
return result;
1013
}
1014
1015
if (OpenPipe(fds, size) != 0) {
1016
result.SetErrorString(
1017
"can't create pipe file descriptors for LLDB commands");
1018
return result;
1019
}
1020
1021
int r = write(fds[WRITE], data, size);
1022
(void)r;
1023
// Close the write end of the pipe, so that the command interpreter will exit
1024
// when it consumes all the data.
1025
llvm::sys::Process::SafelyCloseFileDescriptor(fds[WRITE]);
1026
1027
// Open the read file descriptor as a FILE * that we can return as an input
1028
// handle.
1029
FILE *commands_file = fdopen(fds[READ], "rb");
1030
if (commands_file == nullptr) {
1031
result.SetErrorStringWithFormat("fdopen(%i, \"rb\") failed (errno = %i) "
1032
"when trying to open LLDB commands pipe",
1033
fds[READ], errno);
1034
llvm::sys::Process::SafelyCloseFileDescriptor(fds[READ]);
1035
return result;
1036
}
1037
1038
SetInputFile((FileSP)std::make_shared<NativeFile>(commands_file, true));
1039
return result;
1040
}
1041
1042
void Debugger::SetInputFile(FileSP file_sp) {
1043
assert(file_sp && file_sp->IsValid());
1044
m_input_file_sp = std::move(file_sp);
1045
// Save away the terminal state if that is relevant, so that we can restore
1046
// it in RestoreInputState.
1047
SaveInputTerminalState();
1048
}
1049
1050
void Debugger::SetOutputFile(FileSP file_sp) {
1051
assert(file_sp && file_sp->IsValid());
1052
m_output_stream_sp = std::make_shared<StreamFile>(file_sp);
1053
}
1054
1055
void Debugger::SetErrorFile(FileSP file_sp) {
1056
assert(file_sp && file_sp->IsValid());
1057
m_error_stream_sp = std::make_shared<StreamFile>(file_sp);
1058
}
1059
1060
void Debugger::SaveInputTerminalState() {
1061
int fd = GetInputFile().GetDescriptor();
1062
if (fd != File::kInvalidDescriptor)
1063
m_terminal_state.Save(fd, true);
1064
}
1065
1066
void Debugger::RestoreInputTerminalState() { m_terminal_state.Restore(); }
1067
1068
ExecutionContext Debugger::GetSelectedExecutionContext() {
1069
bool adopt_selected = true;
1070
ExecutionContextRef exe_ctx_ref(GetSelectedTarget().get(), adopt_selected);
1071
return ExecutionContext(exe_ctx_ref);
1072
}
1073
1074
void Debugger::DispatchInputInterrupt() {
1075
std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex());
1076
IOHandlerSP reader_sp(m_io_handler_stack.Top());
1077
if (reader_sp)
1078
reader_sp->Interrupt();
1079
}
1080
1081
void Debugger::DispatchInputEndOfFile() {
1082
std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex());
1083
IOHandlerSP reader_sp(m_io_handler_stack.Top());
1084
if (reader_sp)
1085
reader_sp->GotEOF();
1086
}
1087
1088
void Debugger::ClearIOHandlers() {
1089
// The bottom input reader should be the main debugger input reader. We do
1090
// not want to close that one here.
1091
std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex());
1092
while (m_io_handler_stack.GetSize() > 1) {
1093
IOHandlerSP reader_sp(m_io_handler_stack.Top());
1094
if (reader_sp)
1095
PopIOHandler(reader_sp);
1096
}
1097
}
1098
1099
void Debugger::RunIOHandlers() {
1100
IOHandlerSP reader_sp = m_io_handler_stack.Top();
1101
while (true) {
1102
if (!reader_sp)
1103
break;
1104
1105
reader_sp->Run();
1106
{
1107
std::lock_guard<std::recursive_mutex> guard(
1108
m_io_handler_synchronous_mutex);
1109
1110
// Remove all input readers that are done from the top of the stack
1111
while (true) {
1112
IOHandlerSP top_reader_sp = m_io_handler_stack.Top();
1113
if (top_reader_sp && top_reader_sp->GetIsDone())
1114
PopIOHandler(top_reader_sp);
1115
else
1116
break;
1117
}
1118
reader_sp = m_io_handler_stack.Top();
1119
}
1120
}
1121
ClearIOHandlers();
1122
}
1123
1124
void Debugger::RunIOHandlerSync(const IOHandlerSP &reader_sp) {
1125
std::lock_guard<std::recursive_mutex> guard(m_io_handler_synchronous_mutex);
1126
1127
PushIOHandler(reader_sp);
1128
IOHandlerSP top_reader_sp = reader_sp;
1129
1130
while (top_reader_sp) {
1131
top_reader_sp->Run();
1132
1133
// Don't unwind past the starting point.
1134
if (top_reader_sp.get() == reader_sp.get()) {
1135
if (PopIOHandler(reader_sp))
1136
break;
1137
}
1138
1139
// If we pushed new IO handlers, pop them if they're done or restart the
1140
// loop to run them if they're not.
1141
while (true) {
1142
top_reader_sp = m_io_handler_stack.Top();
1143
if (top_reader_sp && top_reader_sp->GetIsDone()) {
1144
PopIOHandler(top_reader_sp);
1145
// Don't unwind past the starting point.
1146
if (top_reader_sp.get() == reader_sp.get())
1147
return;
1148
} else {
1149
break;
1150
}
1151
}
1152
}
1153
}
1154
1155
bool Debugger::IsTopIOHandler(const lldb::IOHandlerSP &reader_sp) {
1156
return m_io_handler_stack.IsTop(reader_sp);
1157
}
1158
1159
bool Debugger::CheckTopIOHandlerTypes(IOHandler::Type top_type,
1160
IOHandler::Type second_top_type) {
1161
return m_io_handler_stack.CheckTopIOHandlerTypes(top_type, second_top_type);
1162
}
1163
1164
void Debugger::PrintAsync(const char *s, size_t len, bool is_stdout) {
1165
bool printed = m_io_handler_stack.PrintAsync(s, len, is_stdout);
1166
if (!printed) {
1167
lldb::StreamFileSP stream =
1168
is_stdout ? m_output_stream_sp : m_error_stream_sp;
1169
stream->Write(s, len);
1170
}
1171
}
1172
1173
llvm::StringRef Debugger::GetTopIOHandlerControlSequence(char ch) {
1174
return m_io_handler_stack.GetTopIOHandlerControlSequence(ch);
1175
}
1176
1177
const char *Debugger::GetIOHandlerCommandPrefix() {
1178
return m_io_handler_stack.GetTopIOHandlerCommandPrefix();
1179
}
1180
1181
const char *Debugger::GetIOHandlerHelpPrologue() {
1182
return m_io_handler_stack.GetTopIOHandlerHelpPrologue();
1183
}
1184
1185
bool Debugger::RemoveIOHandler(const IOHandlerSP &reader_sp) {
1186
return PopIOHandler(reader_sp);
1187
}
1188
1189
void Debugger::RunIOHandlerAsync(const IOHandlerSP &reader_sp,
1190
bool cancel_top_handler) {
1191
PushIOHandler(reader_sp, cancel_top_handler);
1192
}
1193
1194
void Debugger::AdoptTopIOHandlerFilesIfInvalid(FileSP &in, StreamFileSP &out,
1195
StreamFileSP &err) {
1196
// Before an IOHandler runs, it must have in/out/err streams. This function
1197
// is called when one ore more of the streams are nullptr. We use the top
1198
// input reader's in/out/err streams, or fall back to the debugger file
1199
// handles, or we fall back onto stdin/stdout/stderr as a last resort.
1200
1201
std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex());
1202
IOHandlerSP top_reader_sp(m_io_handler_stack.Top());
1203
// If no STDIN has been set, then set it appropriately
1204
if (!in || !in->IsValid()) {
1205
if (top_reader_sp)
1206
in = top_reader_sp->GetInputFileSP();
1207
else
1208
in = GetInputFileSP();
1209
// If there is nothing, use stdin
1210
if (!in)
1211
in = std::make_shared<NativeFile>(stdin, false);
1212
}
1213
// If no STDOUT has been set, then set it appropriately
1214
if (!out || !out->GetFile().IsValid()) {
1215
if (top_reader_sp)
1216
out = top_reader_sp->GetOutputStreamFileSP();
1217
else
1218
out = GetOutputStreamSP();
1219
// If there is nothing, use stdout
1220
if (!out)
1221
out = std::make_shared<StreamFile>(stdout, false);
1222
}
1223
// If no STDERR has been set, then set it appropriately
1224
if (!err || !err->GetFile().IsValid()) {
1225
if (top_reader_sp)
1226
err = top_reader_sp->GetErrorStreamFileSP();
1227
else
1228
err = GetErrorStreamSP();
1229
// If there is nothing, use stderr
1230
if (!err)
1231
err = std::make_shared<StreamFile>(stderr, false);
1232
}
1233
}
1234
1235
void Debugger::PushIOHandler(const IOHandlerSP &reader_sp,
1236
bool cancel_top_handler) {
1237
if (!reader_sp)
1238
return;
1239
1240
std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex());
1241
1242
// Get the current top input reader...
1243
IOHandlerSP top_reader_sp(m_io_handler_stack.Top());
1244
1245
// Don't push the same IO handler twice...
1246
if (reader_sp == top_reader_sp)
1247
return;
1248
1249
// Push our new input reader
1250
m_io_handler_stack.Push(reader_sp);
1251
reader_sp->Activate();
1252
1253
// Interrupt the top input reader to it will exit its Run() function and let
1254
// this new input reader take over
1255
if (top_reader_sp) {
1256
top_reader_sp->Deactivate();
1257
if (cancel_top_handler)
1258
top_reader_sp->Cancel();
1259
}
1260
}
1261
1262
bool Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp) {
1263
if (!pop_reader_sp)
1264
return false;
1265
1266
std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex());
1267
1268
// The reader on the stop of the stack is done, so let the next read on the
1269
// stack refresh its prompt and if there is one...
1270
if (m_io_handler_stack.IsEmpty())
1271
return false;
1272
1273
IOHandlerSP reader_sp(m_io_handler_stack.Top());
1274
1275
if (pop_reader_sp != reader_sp)
1276
return false;
1277
1278
reader_sp->Deactivate();
1279
reader_sp->Cancel();
1280
m_io_handler_stack.Pop();
1281
1282
reader_sp = m_io_handler_stack.Top();
1283
if (reader_sp)
1284
reader_sp->Activate();
1285
1286
return true;
1287
}
1288
1289
StreamSP Debugger::GetAsyncOutputStream() {
1290
return std::make_shared<StreamAsynchronousIO>(*this, true, GetUseColor());
1291
}
1292
1293
StreamSP Debugger::GetAsyncErrorStream() {
1294
return std::make_shared<StreamAsynchronousIO>(*this, false, GetUseColor());
1295
}
1296
1297
void Debugger::RequestInterrupt() {
1298
std::lock_guard<std::mutex> guard(m_interrupt_mutex);
1299
m_interrupt_requested++;
1300
}
1301
1302
void Debugger::CancelInterruptRequest() {
1303
std::lock_guard<std::mutex> guard(m_interrupt_mutex);
1304
if (m_interrupt_requested > 0)
1305
m_interrupt_requested--;
1306
}
1307
1308
bool Debugger::InterruptRequested() {
1309
// This is the one we should call internally. This will return true either
1310
// if there's a debugger interrupt and we aren't on the IOHandler thread,
1311
// or if we are on the IOHandler thread and there's a CommandInterpreter
1312
// interrupt.
1313
if (!IsIOHandlerThreadCurrentThread()) {
1314
std::lock_guard<std::mutex> guard(m_interrupt_mutex);
1315
return m_interrupt_requested != 0;
1316
}
1317
return GetCommandInterpreter().WasInterrupted();
1318
}
1319
1320
Debugger::InterruptionReport::InterruptionReport(
1321
std::string function_name, const llvm::formatv_object_base &payload)
1322
: m_function_name(std::move(function_name)),
1323
m_interrupt_time(std::chrono::system_clock::now()),
1324
m_thread_id(llvm::get_threadid()) {
1325
llvm::raw_string_ostream desc(m_description);
1326
desc << payload << "\n";
1327
}
1328
1329
void Debugger::ReportInterruption(const InterruptionReport &report) {
1330
// For now, just log the description:
1331
Log *log = GetLog(LLDBLog::Host);
1332
LLDB_LOG(log, "Interruption: {0}", report.m_description);
1333
}
1334
1335
Debugger::DebuggerList Debugger::DebuggersRequestingInterruption() {
1336
DebuggerList result;
1337
if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
1338
std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
1339
for (auto debugger_sp : *g_debugger_list_ptr) {
1340
if (debugger_sp->InterruptRequested())
1341
result.push_back(debugger_sp);
1342
}
1343
}
1344
return result;
1345
}
1346
1347
size_t Debugger::GetNumDebuggers() {
1348
if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
1349
std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
1350
return g_debugger_list_ptr->size();
1351
}
1352
return 0;
1353
}
1354
1355
lldb::DebuggerSP Debugger::GetDebuggerAtIndex(size_t index) {
1356
DebuggerSP debugger_sp;
1357
1358
if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
1359
std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
1360
if (index < g_debugger_list_ptr->size())
1361
debugger_sp = g_debugger_list_ptr->at(index);
1362
}
1363
1364
return debugger_sp;
1365
}
1366
1367
DebuggerSP Debugger::FindDebuggerWithID(lldb::user_id_t id) {
1368
DebuggerSP debugger_sp;
1369
1370
if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
1371
std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
1372
DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
1373
for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
1374
if ((*pos)->GetID() == id) {
1375
debugger_sp = *pos;
1376
break;
1377
}
1378
}
1379
}
1380
return debugger_sp;
1381
}
1382
1383
bool Debugger::FormatDisassemblerAddress(const FormatEntity::Entry *format,
1384
const SymbolContext *sc,
1385
const SymbolContext *prev_sc,
1386
const ExecutionContext *exe_ctx,
1387
const Address *addr, Stream &s) {
1388
FormatEntity::Entry format_entry;
1389
1390
if (format == nullptr) {
1391
if (exe_ctx != nullptr && exe_ctx->HasTargetScope())
1392
format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
1393
if (format == nullptr) {
1394
FormatEntity::Parse("${addr}: ", format_entry);
1395
format = &format_entry;
1396
}
1397
}
1398
bool function_changed = false;
1399
bool initial_function = false;
1400
if (prev_sc && (prev_sc->function || prev_sc->symbol)) {
1401
if (sc && (sc->function || sc->symbol)) {
1402
if (prev_sc->symbol && sc->symbol) {
1403
if (!sc->symbol->Compare(prev_sc->symbol->GetName(),
1404
prev_sc->symbol->GetType())) {
1405
function_changed = true;
1406
}
1407
} else if (prev_sc->function && sc->function) {
1408
if (prev_sc->function->GetMangled() != sc->function->GetMangled()) {
1409
function_changed = true;
1410
}
1411
}
1412
}
1413
}
1414
// The first context on a list of instructions will have a prev_sc that has
1415
// no Function or Symbol -- if SymbolContext had an IsValid() method, it
1416
// would return false. But we do get a prev_sc pointer.
1417
if ((sc && (sc->function || sc->symbol)) && prev_sc &&
1418
(prev_sc->function == nullptr && prev_sc->symbol == nullptr)) {
1419
initial_function = true;
1420
}
1421
return FormatEntity::Format(*format, s, sc, exe_ctx, addr, nullptr,
1422
function_changed, initial_function);
1423
}
1424
1425
void Debugger::AssertCallback(llvm::StringRef message,
1426
llvm::StringRef backtrace,
1427
llvm::StringRef prompt) {
1428
Debugger::ReportError(
1429
llvm::formatv("{0}\n{1}{2}", message, backtrace, prompt).str());
1430
}
1431
1432
void Debugger::SetLoggingCallback(lldb::LogOutputCallback log_callback,
1433
void *baton) {
1434
// For simplicity's sake, I am not going to deal with how to close down any
1435
// open logging streams, I just redirect everything from here on out to the
1436
// callback.
1437
m_callback_handler_sp =
1438
std::make_shared<CallbackLogHandler>(log_callback, baton);
1439
}
1440
1441
void Debugger::SetDestroyCallback(
1442
lldb_private::DebuggerDestroyCallback destroy_callback, void *baton) {
1443
std::lock_guard<std::mutex> guard(m_destroy_callback_mutex);
1444
m_destroy_callbacks.clear();
1445
const lldb::callback_token_t token = m_destroy_callback_next_token++;
1446
m_destroy_callbacks.emplace_back(token, destroy_callback, baton);
1447
}
1448
1449
lldb::callback_token_t Debugger::AddDestroyCallback(
1450
lldb_private::DebuggerDestroyCallback destroy_callback, void *baton) {
1451
std::lock_guard<std::mutex> guard(m_destroy_callback_mutex);
1452
const lldb::callback_token_t token = m_destroy_callback_next_token++;
1453
m_destroy_callbacks.emplace_back(token, destroy_callback, baton);
1454
return token;
1455
}
1456
1457
bool Debugger::RemoveDestroyCallback(lldb::callback_token_t token) {
1458
std::lock_guard<std::mutex> guard(m_destroy_callback_mutex);
1459
for (auto it = m_destroy_callbacks.begin(); it != m_destroy_callbacks.end();
1460
++it) {
1461
if (it->token == token) {
1462
m_destroy_callbacks.erase(it);
1463
return true;
1464
}
1465
}
1466
return false;
1467
}
1468
1469
static void PrivateReportProgress(Debugger &debugger, uint64_t progress_id,
1470
std::string title, std::string details,
1471
uint64_t completed, uint64_t total,
1472
bool is_debugger_specific,
1473
uint32_t progress_broadcast_bit) {
1474
// Only deliver progress events if we have any progress listeners.
1475
if (!debugger.GetBroadcaster().EventTypeHasListeners(progress_broadcast_bit))
1476
return;
1477
1478
EventSP event_sp(new Event(
1479
progress_broadcast_bit,
1480
new ProgressEventData(progress_id, std::move(title), std::move(details),
1481
completed, total, is_debugger_specific)));
1482
debugger.GetBroadcaster().BroadcastEvent(event_sp);
1483
}
1484
1485
void Debugger::ReportProgress(uint64_t progress_id, std::string title,
1486
std::string details, uint64_t completed,
1487
uint64_t total,
1488
std::optional<lldb::user_id_t> debugger_id,
1489
uint32_t progress_category_bit) {
1490
// Check if this progress is for a specific debugger.
1491
if (debugger_id) {
1492
// It is debugger specific, grab it and deliver the event if the debugger
1493
// still exists.
1494
DebuggerSP debugger_sp = FindDebuggerWithID(*debugger_id);
1495
if (debugger_sp)
1496
PrivateReportProgress(*debugger_sp, progress_id, std::move(title),
1497
std::move(details), completed, total,
1498
/*is_debugger_specific*/ true,
1499
progress_category_bit);
1500
return;
1501
}
1502
// The progress event is not debugger specific, iterate over all debuggers
1503
// and deliver a progress event to each one.
1504
if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
1505
std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
1506
DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
1507
for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos)
1508
PrivateReportProgress(*(*pos), progress_id, title, details, completed,
1509
total, /*is_debugger_specific*/ false,
1510
progress_category_bit);
1511
}
1512
}
1513
1514
static void PrivateReportDiagnostic(Debugger &debugger, Severity severity,
1515
std::string message,
1516
bool debugger_specific) {
1517
uint32_t event_type = 0;
1518
switch (severity) {
1519
case eSeverityInfo:
1520
assert(false && "eSeverityInfo should not be broadcast");
1521
return;
1522
case eSeverityWarning:
1523
event_type = lldb::eBroadcastBitWarning;
1524
break;
1525
case eSeverityError:
1526
event_type = lldb::eBroadcastBitError;
1527
break;
1528
}
1529
1530
Broadcaster &broadcaster = debugger.GetBroadcaster();
1531
if (!broadcaster.EventTypeHasListeners(event_type)) {
1532
// Diagnostics are too important to drop. If nobody is listening, print the
1533
// diagnostic directly to the debugger's error stream.
1534
DiagnosticEventData event_data(severity, std::move(message),
1535
debugger_specific);
1536
StreamSP stream = debugger.GetAsyncErrorStream();
1537
event_data.Dump(stream.get());
1538
return;
1539
}
1540
EventSP event_sp = std::make_shared<Event>(
1541
event_type,
1542
new DiagnosticEventData(severity, std::move(message), debugger_specific));
1543
broadcaster.BroadcastEvent(event_sp);
1544
}
1545
1546
void Debugger::ReportDiagnosticImpl(Severity severity, std::string message,
1547
std::optional<lldb::user_id_t> debugger_id,
1548
std::once_flag *once) {
1549
auto ReportDiagnosticLambda = [&]() {
1550
// Always log diagnostics to the system log.
1551
Host::SystemLog(severity, message);
1552
1553
// The diagnostic subsystem is optional but we still want to broadcast
1554
// events when it's disabled.
1555
if (Diagnostics::Enabled())
1556
Diagnostics::Instance().Report(message);
1557
1558
// We don't broadcast info events.
1559
if (severity == lldb::eSeverityInfo)
1560
return;
1561
1562
// Check if this diagnostic is for a specific debugger.
1563
if (debugger_id) {
1564
// It is debugger specific, grab it and deliver the event if the debugger
1565
// still exists.
1566
DebuggerSP debugger_sp = FindDebuggerWithID(*debugger_id);
1567
if (debugger_sp)
1568
PrivateReportDiagnostic(*debugger_sp, severity, std::move(message),
1569
true);
1570
return;
1571
}
1572
// The diagnostic event is not debugger specific, iterate over all debuggers
1573
// and deliver a diagnostic event to each one.
1574
if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
1575
std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
1576
for (const auto &debugger : *g_debugger_list_ptr)
1577
PrivateReportDiagnostic(*debugger, severity, message, false);
1578
}
1579
};
1580
1581
if (once)
1582
std::call_once(*once, ReportDiagnosticLambda);
1583
else
1584
ReportDiagnosticLambda();
1585
}
1586
1587
void Debugger::ReportWarning(std::string message,
1588
std::optional<lldb::user_id_t> debugger_id,
1589
std::once_flag *once) {
1590
ReportDiagnosticImpl(eSeverityWarning, std::move(message), debugger_id, once);
1591
}
1592
1593
void Debugger::ReportError(std::string message,
1594
std::optional<lldb::user_id_t> debugger_id,
1595
std::once_flag *once) {
1596
ReportDiagnosticImpl(eSeverityError, std::move(message), debugger_id, once);
1597
}
1598
1599
void Debugger::ReportInfo(std::string message,
1600
std::optional<lldb::user_id_t> debugger_id,
1601
std::once_flag *once) {
1602
ReportDiagnosticImpl(eSeverityInfo, std::move(message), debugger_id, once);
1603
}
1604
1605
void Debugger::ReportSymbolChange(const ModuleSpec &module_spec) {
1606
if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
1607
std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
1608
for (DebuggerSP debugger_sp : *g_debugger_list_ptr) {
1609
EventSP event_sp = std::make_shared<Event>(
1610
lldb::eBroadcastSymbolChange,
1611
new SymbolChangeEventData(debugger_sp, module_spec));
1612
debugger_sp->GetBroadcaster().BroadcastEvent(event_sp);
1613
}
1614
}
1615
}
1616
1617
static std::shared_ptr<LogHandler>
1618
CreateLogHandler(LogHandlerKind log_handler_kind, int fd, bool should_close,
1619
size_t buffer_size) {
1620
switch (log_handler_kind) {
1621
case eLogHandlerStream:
1622
return std::make_shared<StreamLogHandler>(fd, should_close, buffer_size);
1623
case eLogHandlerCircular:
1624
return std::make_shared<RotatingLogHandler>(buffer_size);
1625
case eLogHandlerSystem:
1626
return std::make_shared<SystemLogHandler>();
1627
case eLogHandlerCallback:
1628
return {};
1629
}
1630
return {};
1631
}
1632
1633
bool Debugger::EnableLog(llvm::StringRef channel,
1634
llvm::ArrayRef<const char *> categories,
1635
llvm::StringRef log_file, uint32_t log_options,
1636
size_t buffer_size, LogHandlerKind log_handler_kind,
1637
llvm::raw_ostream &error_stream) {
1638
1639
std::shared_ptr<LogHandler> log_handler_sp;
1640
if (m_callback_handler_sp) {
1641
log_handler_sp = m_callback_handler_sp;
1642
// For now when using the callback mode you always get thread & timestamp.
1643
log_options |=
1644
LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
1645
} else if (log_file.empty()) {
1646
log_handler_sp =
1647
CreateLogHandler(log_handler_kind, GetOutputFile().GetDescriptor(),
1648
/*should_close=*/false, buffer_size);
1649
} else {
1650
auto pos = m_stream_handlers.find(log_file);
1651
if (pos != m_stream_handlers.end())
1652
log_handler_sp = pos->second.lock();
1653
if (!log_handler_sp) {
1654
File::OpenOptions flags =
1655
File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate;
1656
if (log_options & LLDB_LOG_OPTION_APPEND)
1657
flags |= File::eOpenOptionAppend;
1658
else
1659
flags |= File::eOpenOptionTruncate;
1660
llvm::Expected<FileUP> file = FileSystem::Instance().Open(
1661
FileSpec(log_file), flags, lldb::eFilePermissionsFileDefault, false);
1662
if (!file) {
1663
error_stream << "Unable to open log file '" << log_file
1664
<< "': " << llvm::toString(file.takeError()) << "\n";
1665
return false;
1666
}
1667
1668
log_handler_sp =
1669
CreateLogHandler(log_handler_kind, (*file)->GetDescriptor(),
1670
/*should_close=*/true, buffer_size);
1671
m_stream_handlers[log_file] = log_handler_sp;
1672
}
1673
}
1674
assert(log_handler_sp);
1675
1676
if (log_options == 0)
1677
log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
1678
1679
return Log::EnableLogChannel(log_handler_sp, log_options, channel, categories,
1680
error_stream);
1681
}
1682
1683
ScriptInterpreter *
1684
Debugger::GetScriptInterpreter(bool can_create,
1685
std::optional<lldb::ScriptLanguage> language) {
1686
std::lock_guard<std::recursive_mutex> locker(m_script_interpreter_mutex);
1687
lldb::ScriptLanguage script_language =
1688
language ? *language : GetScriptLanguage();
1689
1690
if (!m_script_interpreters[script_language]) {
1691
if (!can_create)
1692
return nullptr;
1693
m_script_interpreters[script_language] =
1694
PluginManager::GetScriptInterpreterForLanguage(script_language, *this);
1695
}
1696
1697
return m_script_interpreters[script_language].get();
1698
}
1699
1700
SourceManager &Debugger::GetSourceManager() {
1701
if (!m_source_manager_up)
1702
m_source_manager_up = std::make_unique<SourceManager>(shared_from_this());
1703
return *m_source_manager_up;
1704
}
1705
1706
// This function handles events that were broadcast by the process.
1707
void Debugger::HandleBreakpointEvent(const EventSP &event_sp) {
1708
using namespace lldb;
1709
const uint32_t event_type =
1710
Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent(
1711
event_sp);
1712
1713
// if (event_type & eBreakpointEventTypeAdded
1714
// || event_type & eBreakpointEventTypeRemoved
1715
// || event_type & eBreakpointEventTypeEnabled
1716
// || event_type & eBreakpointEventTypeDisabled
1717
// || event_type & eBreakpointEventTypeCommandChanged
1718
// || event_type & eBreakpointEventTypeConditionChanged
1719
// || event_type & eBreakpointEventTypeIgnoreChanged
1720
// || event_type & eBreakpointEventTypeLocationsResolved)
1721
// {
1722
// // Don't do anything about these events, since the breakpoint
1723
// commands already echo these actions.
1724
// }
1725
//
1726
if (event_type & eBreakpointEventTypeLocationsAdded) {
1727
uint32_t num_new_locations =
1728
Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(
1729
event_sp);
1730
if (num_new_locations > 0) {
1731
BreakpointSP breakpoint =
1732
Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp);
1733
StreamSP output_sp(GetAsyncOutputStream());
1734
if (output_sp) {
1735
output_sp->Printf("%d location%s added to breakpoint %d\n",
1736
num_new_locations, num_new_locations == 1 ? "" : "s",
1737
breakpoint->GetID());
1738
output_sp->Flush();
1739
}
1740
}
1741
}
1742
// else if (event_type & eBreakpointEventTypeLocationsRemoved)
1743
// {
1744
// // These locations just get disabled, not sure it is worth spamming
1745
// folks about this on the command line.
1746
// }
1747
// else if (event_type & eBreakpointEventTypeLocationsResolved)
1748
// {
1749
// // This might be an interesting thing to note, but I'm going to
1750
// leave it quiet for now, it just looked noisy.
1751
// }
1752
}
1753
1754
void Debugger::FlushProcessOutput(Process &process, bool flush_stdout,
1755
bool flush_stderr) {
1756
const auto &flush = [&](Stream &stream,
1757
size_t (Process::*get)(char *, size_t, Status &)) {
1758
Status error;
1759
size_t len;
1760
char buffer[1024];
1761
while ((len = (process.*get)(buffer, sizeof(buffer), error)) > 0)
1762
stream.Write(buffer, len);
1763
stream.Flush();
1764
};
1765
1766
std::lock_guard<std::mutex> guard(m_output_flush_mutex);
1767
if (flush_stdout)
1768
flush(*GetAsyncOutputStream(), &Process::GetSTDOUT);
1769
if (flush_stderr)
1770
flush(*GetAsyncErrorStream(), &Process::GetSTDERR);
1771
}
1772
1773
// This function handles events that were broadcast by the process.
1774
void Debugger::HandleProcessEvent(const EventSP &event_sp) {
1775
using namespace lldb;
1776
const uint32_t event_type = event_sp->GetType();
1777
ProcessSP process_sp =
1778
(event_type == Process::eBroadcastBitStructuredData)
1779
? EventDataStructuredData::GetProcessFromEvent(event_sp.get())
1780
: Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
1781
1782
StreamSP output_stream_sp = GetAsyncOutputStream();
1783
StreamSP error_stream_sp = GetAsyncErrorStream();
1784
const bool gui_enabled = IsForwardingEvents();
1785
1786
if (!gui_enabled) {
1787
bool pop_process_io_handler = false;
1788
assert(process_sp);
1789
1790
bool state_is_stopped = false;
1791
const bool got_state_changed =
1792
(event_type & Process::eBroadcastBitStateChanged) != 0;
1793
const bool got_stdout = (event_type & Process::eBroadcastBitSTDOUT) != 0;
1794
const bool got_stderr = (event_type & Process::eBroadcastBitSTDERR) != 0;
1795
const bool got_structured_data =
1796
(event_type & Process::eBroadcastBitStructuredData) != 0;
1797
1798
if (got_state_changed) {
1799
StateType event_state =
1800
Process::ProcessEventData::GetStateFromEvent(event_sp.get());
1801
state_is_stopped = StateIsStoppedState(event_state, false);
1802
}
1803
1804
// Display running state changes first before any STDIO
1805
if (got_state_changed && !state_is_stopped) {
1806
// This is a public stop which we are going to announce to the user, so
1807
// we should force the most relevant frame selection here.
1808
Process::HandleProcessStateChangedEvent(event_sp, output_stream_sp.get(),
1809
SelectMostRelevantFrame,
1810
pop_process_io_handler);
1811
}
1812
1813
// Now display STDOUT and STDERR
1814
FlushProcessOutput(*process_sp, got_stdout || got_state_changed,
1815
got_stderr || got_state_changed);
1816
1817
// Give structured data events an opportunity to display.
1818
if (got_structured_data) {
1819
StructuredDataPluginSP plugin_sp =
1820
EventDataStructuredData::GetPluginFromEvent(event_sp.get());
1821
if (plugin_sp) {
1822
auto structured_data_sp =
1823
EventDataStructuredData::GetObjectFromEvent(event_sp.get());
1824
if (output_stream_sp) {
1825
StreamString content_stream;
1826
Status error =
1827
plugin_sp->GetDescription(structured_data_sp, content_stream);
1828
if (error.Success()) {
1829
if (!content_stream.GetString().empty()) {
1830
// Add newline.
1831
content_stream.PutChar('\n');
1832
content_stream.Flush();
1833
1834
// Print it.
1835
output_stream_sp->PutCString(content_stream.GetString());
1836
}
1837
} else {
1838
error_stream_sp->Format("Failed to print structured "
1839
"data with plugin {0}: {1}",
1840
plugin_sp->GetPluginName(), error);
1841
}
1842
}
1843
}
1844
}
1845
1846
// Now display any stopped state changes after any STDIO
1847
if (got_state_changed && state_is_stopped) {
1848
Process::HandleProcessStateChangedEvent(event_sp, output_stream_sp.get(),
1849
SelectMostRelevantFrame,
1850
pop_process_io_handler);
1851
}
1852
1853
output_stream_sp->Flush();
1854
error_stream_sp->Flush();
1855
1856
if (pop_process_io_handler)
1857
process_sp->PopProcessIOHandler();
1858
}
1859
}
1860
1861
void Debugger::HandleThreadEvent(const EventSP &event_sp) {
1862
// At present the only thread event we handle is the Frame Changed event, and
1863
// all we do for that is just reprint the thread status for that thread.
1864
using namespace lldb;
1865
const uint32_t event_type = event_sp->GetType();
1866
const bool stop_format = true;
1867
if (event_type == Thread::eBroadcastBitStackChanged ||
1868
event_type == Thread::eBroadcastBitThreadSelected) {
1869
ThreadSP thread_sp(
1870
Thread::ThreadEventData::GetThreadFromEvent(event_sp.get()));
1871
if (thread_sp) {
1872
thread_sp->GetStatus(*GetAsyncOutputStream(), 0, 1, 1, stop_format);
1873
}
1874
}
1875
}
1876
1877
bool Debugger::IsForwardingEvents() { return (bool)m_forward_listener_sp; }
1878
1879
void Debugger::EnableForwardEvents(const ListenerSP &listener_sp) {
1880
m_forward_listener_sp = listener_sp;
1881
}
1882
1883
void Debugger::CancelForwardEvents(const ListenerSP &listener_sp) {
1884
m_forward_listener_sp.reset();
1885
}
1886
1887
lldb::thread_result_t Debugger::DefaultEventHandler() {
1888
ListenerSP listener_sp(GetListener());
1889
ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
1890
ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
1891
ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
1892
BroadcastEventSpec target_event_spec(broadcaster_class_target,
1893
Target::eBroadcastBitBreakpointChanged);
1894
1895
BroadcastEventSpec process_event_spec(
1896
broadcaster_class_process,
1897
Process::eBroadcastBitStateChanged | Process::eBroadcastBitSTDOUT |
1898
Process::eBroadcastBitSTDERR | Process::eBroadcastBitStructuredData);
1899
1900
BroadcastEventSpec thread_event_spec(broadcaster_class_thread,
1901
Thread::eBroadcastBitStackChanged |
1902
Thread::eBroadcastBitThreadSelected);
1903
1904
listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp,
1905
target_event_spec);
1906
listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp,
1907
process_event_spec);
1908
listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp,
1909
thread_event_spec);
1910
listener_sp->StartListeningForEvents(
1911
m_command_interpreter_up.get(),
1912
CommandInterpreter::eBroadcastBitQuitCommandReceived |
1913
CommandInterpreter::eBroadcastBitAsynchronousOutputData |
1914
CommandInterpreter::eBroadcastBitAsynchronousErrorData);
1915
1916
listener_sp->StartListeningForEvents(
1917
&m_broadcaster, lldb::eBroadcastBitProgress | lldb::eBroadcastBitWarning |
1918
lldb::eBroadcastBitError |
1919
lldb::eBroadcastSymbolChange);
1920
1921
// Let the thread that spawned us know that we have started up and that we
1922
// are now listening to all required events so no events get missed
1923
m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening);
1924
1925
bool done = false;
1926
while (!done) {
1927
EventSP event_sp;
1928
if (listener_sp->GetEvent(event_sp, std::nullopt)) {
1929
if (event_sp) {
1930
Broadcaster *broadcaster = event_sp->GetBroadcaster();
1931
if (broadcaster) {
1932
uint32_t event_type = event_sp->GetType();
1933
ConstString broadcaster_class(broadcaster->GetBroadcasterClass());
1934
if (broadcaster_class == broadcaster_class_process) {
1935
HandleProcessEvent(event_sp);
1936
} else if (broadcaster_class == broadcaster_class_target) {
1937
if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(
1938
event_sp.get())) {
1939
HandleBreakpointEvent(event_sp);
1940
}
1941
} else if (broadcaster_class == broadcaster_class_thread) {
1942
HandleThreadEvent(event_sp);
1943
} else if (broadcaster == m_command_interpreter_up.get()) {
1944
if (event_type &
1945
CommandInterpreter::eBroadcastBitQuitCommandReceived) {
1946
done = true;
1947
} else if (event_type &
1948
CommandInterpreter::eBroadcastBitAsynchronousErrorData) {
1949
const char *data = static_cast<const char *>(
1950
EventDataBytes::GetBytesFromEvent(event_sp.get()));
1951
if (data && data[0]) {
1952
StreamSP error_sp(GetAsyncErrorStream());
1953
if (error_sp) {
1954
error_sp->PutCString(data);
1955
error_sp->Flush();
1956
}
1957
}
1958
} else if (event_type & CommandInterpreter::
1959
eBroadcastBitAsynchronousOutputData) {
1960
const char *data = static_cast<const char *>(
1961
EventDataBytes::GetBytesFromEvent(event_sp.get()));
1962
if (data && data[0]) {
1963
StreamSP output_sp(GetAsyncOutputStream());
1964
if (output_sp) {
1965
output_sp->PutCString(data);
1966
output_sp->Flush();
1967
}
1968
}
1969
}
1970
} else if (broadcaster == &m_broadcaster) {
1971
if (event_type & lldb::eBroadcastBitProgress)
1972
HandleProgressEvent(event_sp);
1973
else if (event_type & lldb::eBroadcastBitWarning)
1974
HandleDiagnosticEvent(event_sp);
1975
else if (event_type & lldb::eBroadcastBitError)
1976
HandleDiagnosticEvent(event_sp);
1977
}
1978
}
1979
1980
if (m_forward_listener_sp)
1981
m_forward_listener_sp->AddEvent(event_sp);
1982
}
1983
}
1984
}
1985
return {};
1986
}
1987
1988
bool Debugger::StartEventHandlerThread() {
1989
if (!m_event_handler_thread.IsJoinable()) {
1990
// We must synchronize with the DefaultEventHandler() thread to ensure it
1991
// is up and running and listening to events before we return from this
1992
// function. We do this by listening to events for the
1993
// eBroadcastBitEventThreadIsListening from the m_sync_broadcaster
1994
ConstString full_name("lldb.debugger.event-handler");
1995
ListenerSP listener_sp(Listener::MakeListener(full_name.AsCString()));
1996
listener_sp->StartListeningForEvents(&m_sync_broadcaster,
1997
eBroadcastBitEventThreadIsListening);
1998
1999
llvm::StringRef thread_name =
2000
full_name.GetLength() < llvm::get_max_thread_name_length()
2001
? full_name.GetStringRef()
2002
: "dbg.evt-handler";
2003
2004
// Use larger 8MB stack for this thread
2005
llvm::Expected<HostThread> event_handler_thread =
2006
ThreadLauncher::LaunchThread(
2007
thread_name, [this] { return DefaultEventHandler(); },
2008
g_debugger_event_thread_stack_bytes);
2009
2010
if (event_handler_thread) {
2011
m_event_handler_thread = *event_handler_thread;
2012
} else {
2013
LLDB_LOG_ERROR(GetLog(LLDBLog::Host), event_handler_thread.takeError(),
2014
"failed to launch host thread: {0}");
2015
}
2016
2017
// Make sure DefaultEventHandler() is running and listening to events
2018
// before we return from this function. We are only listening for events of
2019
// type eBroadcastBitEventThreadIsListening so we don't need to check the
2020
// event, we just need to wait an infinite amount of time for it (nullptr
2021
// timeout as the first parameter)
2022
lldb::EventSP event_sp;
2023
listener_sp->GetEvent(event_sp, std::nullopt);
2024
}
2025
return m_event_handler_thread.IsJoinable();
2026
}
2027
2028
void Debugger::StopEventHandlerThread() {
2029
if (m_event_handler_thread.IsJoinable()) {
2030
GetCommandInterpreter().BroadcastEvent(
2031
CommandInterpreter::eBroadcastBitQuitCommandReceived);
2032
m_event_handler_thread.Join(nullptr);
2033
}
2034
}
2035
2036
lldb::thread_result_t Debugger::IOHandlerThread() {
2037
RunIOHandlers();
2038
StopEventHandlerThread();
2039
return {};
2040
}
2041
2042
void Debugger::HandleProgressEvent(const lldb::EventSP &event_sp) {
2043
auto *data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
2044
if (!data)
2045
return;
2046
2047
// Do some bookkeeping for the current event, regardless of whether we're
2048
// going to show the progress.
2049
const uint64_t id = data->GetID();
2050
if (m_current_event_id) {
2051
Log *log = GetLog(LLDBLog::Events);
2052
if (log && log->GetVerbose()) {
2053
StreamString log_stream;
2054
log_stream.AsRawOstream()
2055
<< static_cast<void *>(this) << " Debugger(" << GetID()
2056
<< ")::HandleProgressEvent( m_current_event_id = "
2057
<< *m_current_event_id << ", data = { ";
2058
data->Dump(&log_stream);
2059
log_stream << " } )";
2060
log->PutString(log_stream.GetString());
2061
}
2062
if (id != *m_current_event_id)
2063
return;
2064
if (data->GetCompleted() == data->GetTotal())
2065
m_current_event_id.reset();
2066
} else {
2067
m_current_event_id = id;
2068
}
2069
2070
// Decide whether we actually are going to show the progress. This decision
2071
// can change between iterations so check it inside the loop.
2072
if (!GetShowProgress())
2073
return;
2074
2075
// Determine whether the current output file is an interactive terminal with
2076
// color support. We assume that if we support ANSI escape codes we support
2077
// vt100 escape codes.
2078
File &file = GetOutputFile();
2079
if (!file.GetIsInteractive() || !file.GetIsTerminalWithColors())
2080
return;
2081
2082
StreamSP output = GetAsyncOutputStream();
2083
2084
// Print over previous line, if any.
2085
output->Printf("\r");
2086
2087
if (data->GetCompleted() == data->GetTotal()) {
2088
// Clear the current line.
2089
output->Printf("\x1B[2K");
2090
output->Flush();
2091
return;
2092
}
2093
2094
// Trim the progress message if it exceeds the window's width and print it.
2095
std::string message = data->GetMessage();
2096
if (data->IsFinite())
2097
message = llvm::formatv("[{0}/{1}] {2}", data->GetCompleted(),
2098
data->GetTotal(), message)
2099
.str();
2100
2101
// Trim the progress message if it exceeds the window's width and print it.
2102
const uint32_t term_width = GetTerminalWidth();
2103
const uint32_t ellipsis = 3;
2104
if (message.size() + ellipsis >= term_width)
2105
message = message.substr(0, term_width - ellipsis);
2106
2107
const bool use_color = GetUseColor();
2108
llvm::StringRef ansi_prefix = GetShowProgressAnsiPrefix();
2109
if (!ansi_prefix.empty())
2110
output->Printf(
2111
"%s", ansi::FormatAnsiTerminalCodes(ansi_prefix, use_color).c_str());
2112
2113
output->Printf("%s...", message.c_str());
2114
2115
llvm::StringRef ansi_suffix = GetShowProgressAnsiSuffix();
2116
if (!ansi_suffix.empty())
2117
output->Printf(
2118
"%s", ansi::FormatAnsiTerminalCodes(ansi_suffix, use_color).c_str());
2119
2120
// Clear until the end of the line.
2121
output->Printf("\x1B[K\r");
2122
2123
// Flush the output.
2124
output->Flush();
2125
}
2126
2127
void Debugger::HandleDiagnosticEvent(const lldb::EventSP &event_sp) {
2128
auto *data = DiagnosticEventData::GetEventDataFromEvent(event_sp.get());
2129
if (!data)
2130
return;
2131
2132
StreamSP stream = GetAsyncErrorStream();
2133
data->Dump(stream.get());
2134
}
2135
2136
bool Debugger::HasIOHandlerThread() const {
2137
return m_io_handler_thread.IsJoinable();
2138
}
2139
2140
HostThread Debugger::SetIOHandlerThread(HostThread &new_thread) {
2141
HostThread old_host = m_io_handler_thread;
2142
m_io_handler_thread = new_thread;
2143
return old_host;
2144
}
2145
2146
bool Debugger::StartIOHandlerThread() {
2147
if (!m_io_handler_thread.IsJoinable()) {
2148
llvm::Expected<HostThread> io_handler_thread = ThreadLauncher::LaunchThread(
2149
"lldb.debugger.io-handler", [this] { return IOHandlerThread(); },
2150
8 * 1024 * 1024); // Use larger 8MB stack for this thread
2151
if (io_handler_thread) {
2152
m_io_handler_thread = *io_handler_thread;
2153
} else {
2154
LLDB_LOG_ERROR(GetLog(LLDBLog::Host), io_handler_thread.takeError(),
2155
"failed to launch host thread: {0}");
2156
}
2157
}
2158
return m_io_handler_thread.IsJoinable();
2159
}
2160
2161
void Debugger::StopIOHandlerThread() {
2162
if (m_io_handler_thread.IsJoinable()) {
2163
GetInputFile().Close();
2164
m_io_handler_thread.Join(nullptr);
2165
}
2166
}
2167
2168
void Debugger::JoinIOHandlerThread() {
2169
if (HasIOHandlerThread()) {
2170
thread_result_t result;
2171
m_io_handler_thread.Join(&result);
2172
m_io_handler_thread = LLDB_INVALID_HOST_THREAD;
2173
}
2174
}
2175
2176
bool Debugger::IsIOHandlerThreadCurrentThread() const {
2177
if (!HasIOHandlerThread())
2178
return false;
2179
return m_io_handler_thread.EqualsThread(Host::GetCurrentThread());
2180
}
2181
2182
Target &Debugger::GetSelectedOrDummyTarget(bool prefer_dummy) {
2183
if (!prefer_dummy) {
2184
if (TargetSP target = m_target_list.GetSelectedTarget())
2185
return *target;
2186
}
2187
return GetDummyTarget();
2188
}
2189
2190
Status Debugger::RunREPL(LanguageType language, const char *repl_options) {
2191
Status err;
2192
FileSpec repl_executable;
2193
2194
if (language == eLanguageTypeUnknown)
2195
language = GetREPLLanguage();
2196
2197
if (language == eLanguageTypeUnknown) {
2198
LanguageSet repl_languages = Language::GetLanguagesSupportingREPLs();
2199
2200
if (auto single_lang = repl_languages.GetSingularLanguage()) {
2201
language = *single_lang;
2202
} else if (repl_languages.Empty()) {
2203
err.SetErrorString(
2204
"LLDB isn't configured with REPL support for any languages.");
2205
return err;
2206
} else {
2207
err.SetErrorString(
2208
"Multiple possible REPL languages. Please specify a language.");
2209
return err;
2210
}
2211
}
2212
2213
Target *const target =
2214
nullptr; // passing in an empty target means the REPL must create one
2215
2216
REPLSP repl_sp(REPL::Create(err, language, this, target, repl_options));
2217
2218
if (!err.Success()) {
2219
return err;
2220
}
2221
2222
if (!repl_sp) {
2223
err.SetErrorStringWithFormat("couldn't find a REPL for %s",
2224
Language::GetNameForLanguageType(language));
2225
return err;
2226
}
2227
2228
repl_sp->SetCompilerOptions(repl_options);
2229
repl_sp->RunLoop();
2230
2231
return err;
2232
}
2233
2234
llvm::ThreadPoolInterface &Debugger::GetThreadPool() {
2235
assert(g_thread_pool &&
2236
"Debugger::GetThreadPool called before Debugger::Initialize");
2237
return *g_thread_pool;
2238
}
2239
2240