Coverage Report

Created: 2023-09-21 18:56

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