1ac7ddfbfSEd Maste //===-- Debugger.cpp --------------------------------------------*- C++ -*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste //                     The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste 
10ac7ddfbfSEd Maste #include "lldb/Core/Debugger.h"
11ac7ddfbfSEd Maste 
12*b5893f02SDimitry Andric #include "lldb/Breakpoint/Breakpoint.h"
131c3bbb01SEd Maste #include "lldb/Core/FormatEntity.h"
14*b5893f02SDimitry Andric #include "lldb/Core/Mangled.h"
15*b5893f02SDimitry Andric #include "lldb/Core/ModuleList.h"
16ac7ddfbfSEd Maste #include "lldb/Core/PluginManager.h"
17ac7ddfbfSEd Maste #include "lldb/Core/StreamAsynchronousIO.h"
1812b93ac6SEd Maste #include "lldb/Core/StreamFile.h"
19ac7ddfbfSEd Maste #include "lldb/DataFormatters/DataVisualization.h"
209f2f44ceSEd Maste #include "lldb/Expression/REPL.h"
21*b5893f02SDimitry Andric #include "lldb/Host/File.h"
22*b5893f02SDimitry Andric #include "lldb/Host/FileSystem.h"
230127ef0fSEd Maste #include "lldb/Host/HostInfo.h"
24ac7ddfbfSEd Maste #include "lldb/Host/Terminal.h"
257aa51b79SEd Maste #include "lldb/Host/ThreadLauncher.h"
26ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandInterpreter.h"
27*b5893f02SDimitry Andric #include "lldb/Interpreter/OptionValue.h"
281c3bbb01SEd Maste #include "lldb/Interpreter/OptionValueProperties.h"
29ac7ddfbfSEd Maste #include "lldb/Interpreter/OptionValueSInt64.h"
30ac7ddfbfSEd Maste #include "lldb/Interpreter/OptionValueString.h"
31*b5893f02SDimitry Andric #include "lldb/Interpreter/Property.h"
32*b5893f02SDimitry Andric #include "lldb/Interpreter/ScriptInterpreter.h"
33ac7ddfbfSEd Maste #include "lldb/Symbol/Function.h"
34ac7ddfbfSEd Maste #include "lldb/Symbol/Symbol.h"
35*b5893f02SDimitry Andric #include "lldb/Symbol/SymbolContext.h"
369f2f44ceSEd Maste #include "lldb/Target/Language.h"
37ac7ddfbfSEd Maste #include "lldb/Target/Process.h"
38435933ddSDimitry Andric #include "lldb/Target/StructuredDataPlugin.h"
39ac7ddfbfSEd Maste #include "lldb/Target/Target.h"
40435933ddSDimitry Andric #include "lldb/Target/TargetList.h"
41ac7ddfbfSEd Maste #include "lldb/Target/Thread.h"
42*b5893f02SDimitry Andric #include "lldb/Target/ThreadList.h"
43ac7ddfbfSEd Maste #include "lldb/Utility/AnsiTerminal.h"
44*b5893f02SDimitry Andric #include "lldb/Utility/Event.h"
45*b5893f02SDimitry Andric #include "lldb/Utility/Listener.h"
46*b5893f02SDimitry Andric #include "lldb/Utility/Log.h"
47*b5893f02SDimitry Andric #include "lldb/Utility/Reproducer.h"
48*b5893f02SDimitry Andric #include "lldb/Utility/State.h"
49*b5893f02SDimitry Andric #include "lldb/Utility/Stream.h"
50f678e45dSDimitry Andric #include "lldb/Utility/StreamCallback.h"
51f678e45dSDimitry Andric #include "lldb/Utility/StreamString.h"
52f678e45dSDimitry Andric 
534ba319b5SDimitry Andric #if defined(_WIN32)
54*b5893f02SDimitry Andric #include "lldb/Host/windows/PosixApi.h"
55*b5893f02SDimitry Andric #include "lldb/Host/windows/windows.h"
56f678e45dSDimitry Andric #endif
57f678e45dSDimitry Andric 
58*b5893f02SDimitry Andric #include "llvm/ADT/None.h"
59*b5893f02SDimitry Andric #include "llvm/ADT/STLExtras.h"
60f678e45dSDimitry Andric #include "llvm/ADT/StringRef.h"
61*b5893f02SDimitry Andric #include "llvm/ADT/iterator.h"
62f678e45dSDimitry Andric #include "llvm/Support/DynamicLibrary.h"
63f678e45dSDimitry Andric #include "llvm/Support/FileSystem.h"
64*b5893f02SDimitry Andric #include "llvm/Support/Process.h"
65f678e45dSDimitry Andric #include "llvm/Support/Threading.h"
66*b5893f02SDimitry Andric #include "llvm/Support/raw_ostream.h"
67f678e45dSDimitry Andric 
68*b5893f02SDimitry Andric #include <list>
69*b5893f02SDimitry Andric #include <memory>
70f678e45dSDimitry Andric #include <mutex>
71*b5893f02SDimitry Andric #include <set>
72*b5893f02SDimitry Andric #include <stdio.h>
73*b5893f02SDimitry Andric #include <stdlib.h>
74*b5893f02SDimitry Andric #include <string.h>
75*b5893f02SDimitry Andric #include <string>
76*b5893f02SDimitry Andric #include <system_error>
77f678e45dSDimitry Andric 
78f678e45dSDimitry Andric namespace lldb_private {
79f678e45dSDimitry Andric class Address;
80f678e45dSDimitry Andric }
81ac7ddfbfSEd Maste 
82ac7ddfbfSEd Maste using namespace lldb;
83ac7ddfbfSEd Maste using namespace lldb_private;
84ac7ddfbfSEd Maste 
85ac7ddfbfSEd Maste static lldb::user_id_t g_unique_id = 1;
867aa51b79SEd Maste static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024;
87ac7ddfbfSEd Maste 
88ac7ddfbfSEd Maste #pragma mark Static Functions
89ac7ddfbfSEd Maste 
90ac7ddfbfSEd Maste typedef std::vector<DebuggerSP> DebuggerList;
91435933ddSDimitry Andric static std::recursive_mutex *g_debugger_list_mutex_ptr =
92435933ddSDimitry Andric     nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
93435933ddSDimitry Andric static DebuggerList *g_debugger_list_ptr =
94435933ddSDimitry Andric     nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
95ac7ddfbfSEd Maste 
96*b5893f02SDimitry Andric static constexpr OptionEnumValueElement g_show_disassembly_enum_values[] = {
97435933ddSDimitry Andric     {Debugger::eStopDisassemblyTypeNever, "never",
98435933ddSDimitry Andric      "Never show disassembly when displaying a stop context."},
99435933ddSDimitry Andric     {Debugger::eStopDisassemblyTypeNoDebugInfo, "no-debuginfo",
100435933ddSDimitry Andric      "Show disassembly when there is no debug information."},
101435933ddSDimitry Andric     {Debugger::eStopDisassemblyTypeNoSource, "no-source",
102435933ddSDimitry Andric      "Show disassembly when there is no source information, or the source file "
103435933ddSDimitry Andric      "is missing when displaying a stop context."},
104435933ddSDimitry Andric     {Debugger::eStopDisassemblyTypeAlways, "always",
105*b5893f02SDimitry Andric      "Always show disassembly when displaying a stop context."} };
106ac7ddfbfSEd Maste 
107*b5893f02SDimitry Andric static constexpr OptionEnumValueElement g_language_enumerators[] = {
108ac7ddfbfSEd Maste     {eScriptLanguageNone, "none", "Disable scripting languages."},
109435933ddSDimitry Andric     {eScriptLanguagePython, "python",
110435933ddSDimitry Andric      "Select python as the default scripting language."},
111435933ddSDimitry Andric     {eScriptLanguageDefault, "default",
112*b5893f02SDimitry Andric      "Select the lldb default as the default scripting language."} };
113ac7ddfbfSEd Maste 
114435933ddSDimitry Andric #define MODULE_WITH_FUNC                                                       \
115435933ddSDimitry Andric   "{ "                                                                         \
116435933ddSDimitry Andric   "${module.file.basename}{`${function.name-with-args}"                        \
117435933ddSDimitry Andric   "{${frame.no-debug}${function.pc-offset}}}}"
11824d58133SDimitry Andric 
11924d58133SDimitry Andric #define MODULE_WITH_FUNC_NO_ARGS                                               \
12024d58133SDimitry Andric   "{ "                                                                         \
12124d58133SDimitry Andric   "${module.file.basename}{`${function.name-without-args}"                     \
12224d58133SDimitry Andric   "{${frame.no-debug}${function.pc-offset}}}}"
12324d58133SDimitry Andric 
124*b5893f02SDimitry Andric #define FILE_AND_LINE                                                          \
125*b5893f02SDimitry Andric   "{ at ${line.file.basename}:${line.number}{:${line.column}}}"
1269f2f44ceSEd Maste #define IS_OPTIMIZED "{${function.is-optimized} [opt]}"
127ac7ddfbfSEd Maste 
128*b5893f02SDimitry Andric #define IS_ARTIFICIAL "{${frame.is-artificial} [artificial]}"
129*b5893f02SDimitry Andric 
130435933ddSDimitry Andric #define DEFAULT_THREAD_FORMAT                                                  \
131435933ddSDimitry Andric   "thread #${thread.index}: tid = ${thread.id%tid}"                            \
132435933ddSDimitry Andric   "{, ${frame.pc}}" MODULE_WITH_FUNC FILE_AND_LINE                             \
133ac7ddfbfSEd Maste   "{, name = '${thread.name}'}"                                                \
134ac7ddfbfSEd Maste   "{, queue = '${thread.queue}'}"                                              \
1350127ef0fSEd Maste   "{, activity = '${thread.info.activity.name}'}"                              \
1360127ef0fSEd Maste   "{, ${thread.info.trace_messages} messages}"                                 \
137ac7ddfbfSEd Maste   "{, stop reason = ${thread.stop-reason}}"                                    \
138ac7ddfbfSEd Maste   "{\\nReturn value: ${thread.return-value}}"                                  \
1390127ef0fSEd Maste   "{\\nCompleted expression: ${thread.completed-expression}}"                  \
140ac7ddfbfSEd Maste   "\\n"
141ac7ddfbfSEd Maste 
142435933ddSDimitry Andric #define DEFAULT_THREAD_STOP_FORMAT                                             \
143435933ddSDimitry Andric   "thread #${thread.index}{, name = '${thread.name}'}"                         \
144435933ddSDimitry Andric   "{, queue = '${thread.queue}'}"                                              \
145435933ddSDimitry Andric   "{, activity = '${thread.info.activity.name}'}"                              \
146435933ddSDimitry Andric   "{, ${thread.info.trace_messages} messages}"                                 \
147435933ddSDimitry Andric   "{, stop reason = ${thread.stop-reason}}"                                    \
148435933ddSDimitry Andric   "{\\nReturn value: ${thread.return-value}}"                                  \
149435933ddSDimitry Andric   "{\\nCompleted expression: ${thread.completed-expression}}"                  \
150ac7ddfbfSEd Maste   "\\n"
151ac7ddfbfSEd Maste 
152435933ddSDimitry Andric #define DEFAULT_FRAME_FORMAT                                                   \
153f678e45dSDimitry Andric   "frame #${frame.index}: ${frame.pc}" MODULE_WITH_FUNC FILE_AND_LINE          \
154*b5893f02SDimitry Andric       IS_OPTIMIZED IS_ARTIFICIAL "\\n"
155435933ddSDimitry Andric 
15624d58133SDimitry Andric #define DEFAULT_FRAME_FORMAT_NO_ARGS                                           \
15724d58133SDimitry Andric   "frame #${frame.index}: ${frame.pc}" MODULE_WITH_FUNC_NO_ARGS FILE_AND_LINE  \
158*b5893f02SDimitry Andric       IS_OPTIMIZED IS_ARTIFICIAL "\\n"
15924d58133SDimitry Andric 
1601c3bbb01SEd Maste // Three parts to this disassembly format specification:
1611c3bbb01SEd Maste //   1. If this is a new function/symbol (no previous symbol/function), print
1621c3bbb01SEd Maste //      dylib`funcname:\n
163435933ddSDimitry Andric //   2. If this is a symbol context change (different from previous
164435933ddSDimitry Andric //   symbol/function), print
1651c3bbb01SEd Maste //      dylib`funcname:\n
1661c3bbb01SEd Maste //   3. print
1671c3bbb01SEd Maste //      address <+offset>:
168435933ddSDimitry Andric #define DEFAULT_DISASSEMBLY_FORMAT                                             \
169435933ddSDimitry Andric   "{${function.initial-function}{${module.file.basename}`}{${function.name-"   \
170*b5893f02SDimitry Andric   "without-args}}:\\n}{${function.changed}\\n{${module.file.basename}`}{${"    \
171*b5893f02SDimitry Andric   "function.name-without-args}}:\\n}{${current-pc-arrow} "                     \
172435933ddSDimitry Andric   "}${addr-file-or-load}{ "                                                    \
173435933ddSDimitry Andric   "<${function.concrete-only-addr-offset-no-padding}>}: "
1741c3bbb01SEd Maste 
1754ba319b5SDimitry Andric // gdb's disassembly format can be emulated with ${current-pc-arrow}${addr-
1764ba319b5SDimitry Andric // file-or-load}{ <${function.name-without-args}${function.concrete-only-addr-
1774ba319b5SDimitry Andric // offset-no-padding}>}:
1781c3bbb01SEd Maste 
1791c3bbb01SEd Maste // lldb's original format for disassembly would look like this format string -
1804ba319b5SDimitry Andric // {${function.initial-function}{${module.file.basename}`}{${function.name-
1814ba319b5SDimitry Andric // without-
1824ba319b5SDimitry Andric // args}}:\n}{${function.changed}\n{${module.file.basename}`}{${function.name-
1834ba319b5SDimitry Andric // without-args}}:\n}{${current-pc-arrow} }{${addr-file-or-load}}:
1841c3bbb01SEd Maste 
185*b5893f02SDimitry Andric static constexpr OptionEnumValueElement s_stop_show_column_values[] = {
186435933ddSDimitry Andric     {eStopShowColumnAnsiOrCaret, "ansi-or-caret",
187435933ddSDimitry Andric      "Highlight the stop column with ANSI terminal codes when color/ANSI mode "
188435933ddSDimitry Andric      "is enabled; otherwise, fall back to using a text-only caret (^) as if "
189435933ddSDimitry Andric      "\"caret-only\" mode was selected."},
190435933ddSDimitry Andric     {eStopShowColumnAnsi, "ansi", "Highlight the stop column with ANSI "
191435933ddSDimitry Andric                                   "terminal codes when running LLDB with "
192435933ddSDimitry Andric                                   "color/ANSI enabled."},
193435933ddSDimitry Andric     {eStopShowColumnCaret, "caret",
194435933ddSDimitry Andric      "Highlight the stop column with a caret character (^) underneath the stop "
195435933ddSDimitry Andric      "column. This method introduces a new line in source listings that "
196435933ddSDimitry Andric      "display thread stop locations."},
197*b5893f02SDimitry Andric     {eStopShowColumnNone, "none", "Do not highlight the stop column."}};
198435933ddSDimitry Andric 
199*b5893f02SDimitry Andric static constexpr PropertyDefinition g_properties[] = {
200*b5893f02SDimitry Andric     {"auto-confirm", OptionValue::eTypeBoolean, true, false, nullptr, {},
201435933ddSDimitry Andric      "If true all confirmation prompts will receive their default reply."},
202435933ddSDimitry Andric     {"disassembly-format", OptionValue::eTypeFormatEntity, true, 0,
203*b5893f02SDimitry Andric      DEFAULT_DISASSEMBLY_FORMAT, {},
20424d58133SDimitry Andric      "The default disassembly format "
205435933ddSDimitry Andric      "string to use when disassembling "
206435933ddSDimitry Andric      "instruction sequences."},
207435933ddSDimitry Andric     {"frame-format", OptionValue::eTypeFormatEntity, true, 0,
208*b5893f02SDimitry Andric      DEFAULT_FRAME_FORMAT, {},
20924d58133SDimitry Andric      "The default frame format string to use "
210435933ddSDimitry Andric      "when displaying stack frame information "
211435933ddSDimitry Andric      "for threads."},
212*b5893f02SDimitry Andric     {"notify-void", OptionValue::eTypeBoolean, true, false, nullptr, {},
213435933ddSDimitry Andric      "Notify the user explicitly if an expression returns void (default: "
214435933ddSDimitry Andric      "false)."},
215435933ddSDimitry Andric     {"prompt", OptionValue::eTypeString, true,
216*b5893f02SDimitry Andric      OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", {},
217*b5893f02SDimitry Andric      "The debugger command line prompt displayed for the user."},
218435933ddSDimitry Andric     {"script-lang", OptionValue::eTypeEnum, true, eScriptLanguagePython,
219*b5893f02SDimitry Andric      nullptr, OptionEnumValues(g_language_enumerators),
220435933ddSDimitry Andric      "The script language to be used for evaluating user-written scripts."},
221*b5893f02SDimitry Andric     {"stop-disassembly-count", OptionValue::eTypeSInt64, true, 4, nullptr, {},
22224d58133SDimitry Andric      "The number of disassembly lines to show when displaying a "
223435933ddSDimitry Andric      "stopped context."},
224435933ddSDimitry Andric     {"stop-disassembly-display", OptionValue::eTypeEnum, true,
225435933ddSDimitry Andric      Debugger::eStopDisassemblyTypeNoDebugInfo, nullptr,
226*b5893f02SDimitry Andric      OptionEnumValues(g_show_disassembly_enum_values),
227435933ddSDimitry Andric      "Control when to display disassembly when displaying a stopped context."},
228*b5893f02SDimitry Andric     {"stop-line-count-after", OptionValue::eTypeSInt64, true, 3, nullptr, {},
22924d58133SDimitry Andric      "The number of sources lines to display that come after the "
230435933ddSDimitry Andric      "current source line when displaying a stopped context."},
231*b5893f02SDimitry Andric     {"stop-line-count-before", OptionValue::eTypeSInt64, true, 3, nullptr, {},
23224d58133SDimitry Andric      "The number of sources lines to display that come before the "
233435933ddSDimitry Andric      "current source line when displaying a stopped context."},
234*b5893f02SDimitry Andric     {"highlight-source", OptionValue::eTypeBoolean, true, true, nullptr, {},
235*b5893f02SDimitry Andric      "If true, LLDB will highlight the displayed source code."},
236435933ddSDimitry Andric     {"stop-show-column", OptionValue::eTypeEnum, false,
237*b5893f02SDimitry Andric      eStopShowColumnAnsiOrCaret, nullptr, OptionEnumValues(s_stop_show_column_values),
238435933ddSDimitry Andric      "If true, LLDB will use the column information from the debug info to "
239435933ddSDimitry Andric      "mark the current position when displaying a stopped context."},
240*b5893f02SDimitry Andric     {"stop-show-column-ansi-prefix", OptionValue::eTypeString, true, 0,
241*b5893f02SDimitry Andric      "${ansi.underline}", {},
242435933ddSDimitry Andric      "When displaying the column marker in a color-enabled (i.e. ANSI) "
243435933ddSDimitry Andric      "terminal, use the ANSI terminal code specified in this format at the "
244435933ddSDimitry Andric      "immediately before the column to be marked."},
245*b5893f02SDimitry Andric     {"stop-show-column-ansi-suffix", OptionValue::eTypeString, true, 0,
246*b5893f02SDimitry Andric      "${ansi.normal}", {},
247435933ddSDimitry Andric      "When displaying the column marker in a color-enabled (i.e. ANSI) "
248435933ddSDimitry Andric      "terminal, use the ANSI terminal code specified in this format "
249435933ddSDimitry Andric      "immediately after the column to be marked."},
250*b5893f02SDimitry Andric     {"term-width", OptionValue::eTypeSInt64, true, 80, nullptr, {},
251435933ddSDimitry Andric      "The maximum number of columns to use for displaying text."},
252435933ddSDimitry Andric     {"thread-format", OptionValue::eTypeFormatEntity, true, 0,
253*b5893f02SDimitry Andric      DEFAULT_THREAD_FORMAT, {},
25424d58133SDimitry Andric      "The default thread format string to use "
255435933ddSDimitry Andric      "when displaying thread information."},
256435933ddSDimitry Andric     {"thread-stop-format", OptionValue::eTypeFormatEntity, true, 0,
257*b5893f02SDimitry Andric      DEFAULT_THREAD_STOP_FORMAT, {},
25824d58133SDimitry Andric      "The default thread format  "
259435933ddSDimitry Andric      "string to use when displaying thread "
260435933ddSDimitry Andric      "information as part of the stop display."},
261*b5893f02SDimitry Andric     {"use-external-editor", OptionValue::eTypeBoolean, true, false, nullptr, {},
262*b5893f02SDimitry Andric      "Whether to use an external editor or not."},
263*b5893f02SDimitry Andric     {"use-color", OptionValue::eTypeBoolean, true, true, nullptr, {},
264435933ddSDimitry Andric      "Whether to use Ansi color codes or not."},
265435933ddSDimitry Andric     {"auto-one-line-summaries", OptionValue::eTypeBoolean, true, true, nullptr,
266*b5893f02SDimitry Andric      {},
26724d58133SDimitry Andric      "If true, LLDB will automatically display small structs in "
268435933ddSDimitry Andric      "one-liner format (default: true)."},
269*b5893f02SDimitry Andric     {"auto-indent", OptionValue::eTypeBoolean, true, true, nullptr, {},
270435933ddSDimitry Andric      "If true, LLDB will auto indent/outdent code. Currently only supported in "
271435933ddSDimitry Andric      "the REPL (default: true)."},
272*b5893f02SDimitry Andric     {"print-decls", OptionValue::eTypeBoolean, true, true, nullptr, {},
273435933ddSDimitry Andric      "If true, LLDB will print the values of variables declared in an "
274435933ddSDimitry Andric      "expression. Currently only supported in the REPL (default: true)."},
275*b5893f02SDimitry Andric     {"tab-size", OptionValue::eTypeUInt64, true, 4, nullptr, {},
276435933ddSDimitry Andric      "The tab size to use when indenting code in multi-line input mode "
277435933ddSDimitry Andric      "(default: 4)."},
278435933ddSDimitry Andric     {"escape-non-printables", OptionValue::eTypeBoolean, true, true, nullptr,
279*b5893f02SDimitry Andric      {},
28024d58133SDimitry Andric      "If true, LLDB will automatically escape non-printable and "
281435933ddSDimitry Andric      "escape characters when formatting strings."},
28224d58133SDimitry Andric     {"frame-format-unique", OptionValue::eTypeFormatEntity, true, 0,
283*b5893f02SDimitry Andric      DEFAULT_FRAME_FORMAT_NO_ARGS, {},
28424d58133SDimitry Andric      "The default frame format string to use when displaying stack frame"
285*b5893f02SDimitry Andric      "information for threads from thread backtrace unique."}};
286435933ddSDimitry Andric 
287435933ddSDimitry Andric enum {
288ac7ddfbfSEd Maste   ePropertyAutoConfirm = 0,
2897aa51b79SEd Maste   ePropertyDisassemblyFormat,
290ac7ddfbfSEd Maste   ePropertyFrameFormat,
291ac7ddfbfSEd Maste   ePropertyNotiftVoid,
292ac7ddfbfSEd Maste   ePropertyPrompt,
293ac7ddfbfSEd Maste   ePropertyScriptLanguage,
294ac7ddfbfSEd Maste   ePropertyStopDisassemblyCount,
295ac7ddfbfSEd Maste   ePropertyStopDisassemblyDisplay,
296ac7ddfbfSEd Maste   ePropertyStopLineCountAfter,
297ac7ddfbfSEd Maste   ePropertyStopLineCountBefore,
298*b5893f02SDimitry Andric   ePropertyHighlightSource,
299435933ddSDimitry Andric   ePropertyStopShowColumn,
300435933ddSDimitry Andric   ePropertyStopShowColumnAnsiPrefix,
301435933ddSDimitry Andric   ePropertyStopShowColumnAnsiSuffix,
302ac7ddfbfSEd Maste   ePropertyTerminalWidth,
303ac7ddfbfSEd Maste   ePropertyThreadFormat,
304435933ddSDimitry Andric   ePropertyThreadStopFormat,
305ac7ddfbfSEd Maste   ePropertyUseExternalEditor,
306ac7ddfbfSEd Maste   ePropertyUseColor,
3077aa51b79SEd Maste   ePropertyAutoOneLineSummaries,
3089f2f44ceSEd Maste   ePropertyAutoIndent,
3099f2f44ceSEd Maste   ePropertyPrintDecls,
3109f2f44ceSEd Maste   ePropertyTabSize,
31124d58133SDimitry Andric   ePropertyEscapeNonPrintables,
31224d58133SDimitry Andric   ePropertyFrameFormatUnique,
313ac7ddfbfSEd Maste };
314ac7ddfbfSEd Maste 
3154bb0738eSEd Maste LoadPluginCallbackType Debugger::g_load_plugin_callback = nullptr;
316ac7ddfbfSEd Maste 
SetPropertyValue(const ExecutionContext * exe_ctx,VarSetOperationType op,llvm::StringRef property_path,llvm::StringRef value)3175517e702SDimitry Andric Status Debugger::SetPropertyValue(const ExecutionContext *exe_ctx,
318ac7ddfbfSEd Maste                                   VarSetOperationType op,
3195517e702SDimitry Andric                                   llvm::StringRef property_path,
3205517e702SDimitry Andric                                   llvm::StringRef value) {
321435933ddSDimitry Andric   bool is_load_script = (property_path == "target.load-script-from-symbol-file");
322435933ddSDimitry Andric   bool is_escape_non_printables = (property_path == "escape-non-printables");
323ac7ddfbfSEd Maste   TargetSP target_sp;
324ac7ddfbfSEd Maste   LoadScriptFromSymFile load_script_old_value;
325435933ddSDimitry Andric   if (is_load_script && exe_ctx->GetTargetSP()) {
326ac7ddfbfSEd Maste     target_sp = exe_ctx->GetTargetSP();
327435933ddSDimitry Andric     load_script_old_value =
328435933ddSDimitry Andric         target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
329ac7ddfbfSEd Maste   }
3305517e702SDimitry Andric   Status error(Properties::SetPropertyValue(exe_ctx, op, property_path, value));
331435933ddSDimitry Andric   if (error.Success()) {
332ac7ddfbfSEd Maste     // FIXME it would be nice to have "on-change" callbacks for properties
333435933ddSDimitry Andric     if (property_path == g_properties[ePropertyPrompt].name) {
334435933ddSDimitry Andric       llvm::StringRef new_prompt = GetPrompt();
335435933ddSDimitry Andric       std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes(
336435933ddSDimitry Andric           new_prompt, GetUseColor());
337ac7ddfbfSEd Maste       if (str.length())
338435933ddSDimitry Andric         new_prompt = str;
33912b93ac6SEd Maste       GetCommandInterpreter().UpdatePrompt(new_prompt);
340f678e45dSDimitry Andric       auto bytes = llvm::make_unique<EventDataBytes>(new_prompt);
341f678e45dSDimitry Andric       auto prompt_change_event_sp = std::make_shared<Event>(
342f678e45dSDimitry Andric           CommandInterpreter::eBroadcastBitResetPrompt, bytes.release());
343ac7ddfbfSEd Maste       GetCommandInterpreter().BroadcastEvent(prompt_change_event_sp);
344435933ddSDimitry Andric     } else if (property_path == g_properties[ePropertyUseColor].name) {
345435933ddSDimitry Andric       // use-color changed. Ping the prompt so it can reset the ansi terminal
346435933ddSDimitry Andric       // codes.
347ac7ddfbfSEd Maste       SetPrompt(GetPrompt());
348435933ddSDimitry Andric     } else if (is_load_script && target_sp &&
349435933ddSDimitry Andric                load_script_old_value == eLoadScriptFromSymFileWarn) {
350435933ddSDimitry Andric       if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() ==
351435933ddSDimitry Andric           eLoadScriptFromSymFileTrue) {
3525517e702SDimitry Andric         std::list<Status> errors;
353ac7ddfbfSEd Maste         StreamString feedback_stream;
354435933ddSDimitry Andric         if (!target_sp->LoadScriptingResources(errors, &feedback_stream)) {
35512b93ac6SEd Maste           StreamFileSP stream_sp(GetErrorFile());
356435933ddSDimitry Andric           if (stream_sp) {
357435933ddSDimitry Andric             for (auto error : errors) {
35812b93ac6SEd Maste               stream_sp->Printf("%s\n", error.AsCString());
359ac7ddfbfSEd Maste             }
360ac7ddfbfSEd Maste             if (feedback_stream.GetSize())
361435933ddSDimitry Andric               stream_sp->PutCString(feedback_stream.GetString());
36212b93ac6SEd Maste           }
363ac7ddfbfSEd Maste         }
364ac7ddfbfSEd Maste       }
365435933ddSDimitry Andric     } else if (is_escape_non_printables) {
3667aa51b79SEd Maste       DataVisualization::ForceUpdate();
3677aa51b79SEd Maste     }
368ac7ddfbfSEd Maste   }
369ac7ddfbfSEd Maste   return error;
370ac7ddfbfSEd Maste }
371ac7ddfbfSEd Maste 
GetAutoConfirm() const372435933ddSDimitry Andric bool Debugger::GetAutoConfirm() const {
373ac7ddfbfSEd Maste   const uint32_t idx = ePropertyAutoConfirm;
374435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
375435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
376ac7ddfbfSEd Maste }
377ac7ddfbfSEd Maste 
GetDisassemblyFormat() const378435933ddSDimitry Andric const FormatEntity::Entry *Debugger::GetDisassemblyFormat() const {
3797aa51b79SEd Maste   const uint32_t idx = ePropertyDisassemblyFormat;
3804bb0738eSEd Maste   return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
3817aa51b79SEd Maste }
3827aa51b79SEd Maste 
GetFrameFormat() const383435933ddSDimitry Andric const FormatEntity::Entry *Debugger::GetFrameFormat() const {
384ac7ddfbfSEd Maste   const uint32_t idx = ePropertyFrameFormat;
3854bb0738eSEd Maste   return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
386ac7ddfbfSEd Maste }
387ac7ddfbfSEd Maste 
GetFrameFormatUnique() const38824d58133SDimitry Andric const FormatEntity::Entry *Debugger::GetFrameFormatUnique() const {
38924d58133SDimitry Andric   const uint32_t idx = ePropertyFrameFormatUnique;
39024d58133SDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
39124d58133SDimitry Andric }
39224d58133SDimitry Andric 
GetNotifyVoid() const393435933ddSDimitry Andric bool Debugger::GetNotifyVoid() const {
394ac7ddfbfSEd Maste   const uint32_t idx = ePropertyNotiftVoid;
395435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
396435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
397ac7ddfbfSEd Maste }
398ac7ddfbfSEd Maste 
GetPrompt() const399435933ddSDimitry Andric llvm::StringRef Debugger::GetPrompt() const {
400ac7ddfbfSEd Maste   const uint32_t idx = ePropertyPrompt;
401435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsString(
402435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_cstr_value);
403ac7ddfbfSEd Maste }
404ac7ddfbfSEd Maste 
SetPrompt(llvm::StringRef p)405435933ddSDimitry Andric void Debugger::SetPrompt(llvm::StringRef p) {
406ac7ddfbfSEd Maste   const uint32_t idx = ePropertyPrompt;
4074bb0738eSEd Maste   m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, p);
408435933ddSDimitry Andric   llvm::StringRef new_prompt = GetPrompt();
409435933ddSDimitry Andric   std::string str =
410435933ddSDimitry Andric       lldb_utility::ansi::FormatAnsiTerminalCodes(new_prompt, GetUseColor());
411ac7ddfbfSEd Maste   if (str.length())
412435933ddSDimitry Andric     new_prompt = str;
41312b93ac6SEd Maste   GetCommandInterpreter().UpdatePrompt(new_prompt);
414ac7ddfbfSEd Maste }
415ac7ddfbfSEd Maste 
GetReproducerPath() const416*b5893f02SDimitry Andric llvm::StringRef Debugger::GetReproducerPath() const {
417*b5893f02SDimitry Andric   auto &r = repro::Reproducer::Instance();
418*b5893f02SDimitry Andric   return r.GetReproducerPath().GetCString();
419*b5893f02SDimitry Andric }
420*b5893f02SDimitry Andric 
GetThreadFormat() const421435933ddSDimitry Andric const FormatEntity::Entry *Debugger::GetThreadFormat() const {
422ac7ddfbfSEd Maste   const uint32_t idx = ePropertyThreadFormat;
4234bb0738eSEd Maste   return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
424ac7ddfbfSEd Maste }
425ac7ddfbfSEd Maste 
GetThreadStopFormat() const426435933ddSDimitry Andric const FormatEntity::Entry *Debugger::GetThreadStopFormat() const {
427435933ddSDimitry Andric   const uint32_t idx = ePropertyThreadStopFormat;
428435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
429ac7ddfbfSEd Maste }
430ac7ddfbfSEd Maste 
GetScriptLanguage() const431435933ddSDimitry Andric lldb::ScriptLanguage Debugger::GetScriptLanguage() const {
432ac7ddfbfSEd Maste   const uint32_t idx = ePropertyScriptLanguage;
433435933ddSDimitry Andric   return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration(
434435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value);
435ac7ddfbfSEd Maste }
436ac7ddfbfSEd Maste 
SetScriptLanguage(lldb::ScriptLanguage script_lang)437435933ddSDimitry Andric bool Debugger::SetScriptLanguage(lldb::ScriptLanguage script_lang) {
438435933ddSDimitry Andric   const uint32_t idx = ePropertyScriptLanguage;
439435933ddSDimitry Andric   return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx,
440435933ddSDimitry Andric                                                           script_lang);
441435933ddSDimitry Andric }
442435933ddSDimitry Andric 
GetTerminalWidth() const443435933ddSDimitry Andric uint32_t Debugger::GetTerminalWidth() const {
444ac7ddfbfSEd Maste   const uint32_t idx = ePropertyTerminalWidth;
445435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsSInt64(
446435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value);
447ac7ddfbfSEd Maste }
448ac7ddfbfSEd Maste 
SetTerminalWidth(uint32_t term_width)449435933ddSDimitry Andric bool Debugger::SetTerminalWidth(uint32_t term_width) {
450ac7ddfbfSEd Maste   const uint32_t idx = ePropertyTerminalWidth;
4514bb0738eSEd Maste   return m_collection_sp->SetPropertyAtIndexAsSInt64(nullptr, idx, term_width);
452ac7ddfbfSEd Maste }
453ac7ddfbfSEd Maste 
GetUseExternalEditor() const454435933ddSDimitry Andric bool Debugger::GetUseExternalEditor() const {
455ac7ddfbfSEd Maste   const uint32_t idx = ePropertyUseExternalEditor;
456435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
457435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
458ac7ddfbfSEd Maste }
459ac7ddfbfSEd Maste 
SetUseExternalEditor(bool b)460435933ddSDimitry Andric bool Debugger::SetUseExternalEditor(bool b) {
461ac7ddfbfSEd Maste   const uint32_t idx = ePropertyUseExternalEditor;
4624bb0738eSEd Maste   return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
463ac7ddfbfSEd Maste }
464ac7ddfbfSEd Maste 
GetUseColor() const465435933ddSDimitry Andric bool Debugger::GetUseColor() const {
466ac7ddfbfSEd Maste   const uint32_t idx = ePropertyUseColor;
467435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
468435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
469ac7ddfbfSEd Maste }
470ac7ddfbfSEd Maste 
SetUseColor(bool b)471435933ddSDimitry Andric bool Debugger::SetUseColor(bool b) {
472ac7ddfbfSEd Maste   const uint32_t idx = ePropertyUseColor;
4734bb0738eSEd Maste   bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
474ac7ddfbfSEd Maste   SetPrompt(GetPrompt());
475ac7ddfbfSEd Maste   return ret;
476ac7ddfbfSEd Maste }
477ac7ddfbfSEd Maste 
GetHighlightSource() const478*b5893f02SDimitry Andric bool Debugger::GetHighlightSource() const {
479*b5893f02SDimitry Andric   const uint32_t idx = ePropertyHighlightSource;
480*b5893f02SDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
481*b5893f02SDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value);
482*b5893f02SDimitry Andric }
483*b5893f02SDimitry Andric 
GetStopShowColumn() const484435933ddSDimitry Andric StopShowColumn Debugger::GetStopShowColumn() const {
485435933ddSDimitry Andric   const uint32_t idx = ePropertyStopShowColumn;
486435933ddSDimitry Andric   return (lldb::StopShowColumn)m_collection_sp->GetPropertyAtIndexAsEnumeration(
487435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value);
488ac7ddfbfSEd Maste }
489ac7ddfbfSEd Maste 
GetStopShowColumnAnsiPrefix() const490*b5893f02SDimitry Andric llvm::StringRef Debugger::GetStopShowColumnAnsiPrefix() const {
491435933ddSDimitry Andric   const uint32_t idx = ePropertyStopShowColumnAnsiPrefix;
492*b5893f02SDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, "");
493435933ddSDimitry Andric }
494435933ddSDimitry Andric 
GetStopShowColumnAnsiSuffix() const495*b5893f02SDimitry Andric llvm::StringRef Debugger::GetStopShowColumnAnsiSuffix() const {
496435933ddSDimitry Andric   const uint32_t idx = ePropertyStopShowColumnAnsiSuffix;
497*b5893f02SDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, "");
498435933ddSDimitry Andric }
499435933ddSDimitry Andric 
GetStopSourceLineCount(bool before) const500435933ddSDimitry Andric uint32_t Debugger::GetStopSourceLineCount(bool before) const {
501435933ddSDimitry Andric   const uint32_t idx =
502435933ddSDimitry Andric       before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
503435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsSInt64(
504435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value);
505435933ddSDimitry Andric }
506435933ddSDimitry Andric 
GetStopDisassemblyDisplay() const507435933ddSDimitry Andric Debugger::StopDisassemblyType Debugger::GetStopDisassemblyDisplay() const {
508ac7ddfbfSEd Maste   const uint32_t idx = ePropertyStopDisassemblyDisplay;
509435933ddSDimitry Andric   return (Debugger::StopDisassemblyType)
510435933ddSDimitry Andric       m_collection_sp->GetPropertyAtIndexAsEnumeration(
511435933ddSDimitry Andric           nullptr, idx, g_properties[idx].default_uint_value);
512ac7ddfbfSEd Maste }
513ac7ddfbfSEd Maste 
GetDisassemblyLineCount() const514435933ddSDimitry Andric uint32_t Debugger::GetDisassemblyLineCount() const {
515ac7ddfbfSEd Maste   const uint32_t idx = ePropertyStopDisassemblyCount;
516435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsSInt64(
517435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value);
518ac7ddfbfSEd Maste }
519ac7ddfbfSEd Maste 
GetAutoOneLineSummaries() const520435933ddSDimitry Andric bool Debugger::GetAutoOneLineSummaries() const {
52135617911SEd Maste   const uint32_t idx = ePropertyAutoOneLineSummaries;
5224bb0738eSEd Maste   return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
5237aa51b79SEd Maste }
52435617911SEd Maste 
GetEscapeNonPrintables() const525435933ddSDimitry Andric bool Debugger::GetEscapeNonPrintables() const {
5267aa51b79SEd Maste   const uint32_t idx = ePropertyEscapeNonPrintables;
5274bb0738eSEd Maste   return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
52835617911SEd Maste }
52935617911SEd Maste 
GetAutoIndent() const530435933ddSDimitry Andric bool Debugger::GetAutoIndent() const {
5319f2f44ceSEd Maste   const uint32_t idx = ePropertyAutoIndent;
5324bb0738eSEd Maste   return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
5339f2f44ceSEd Maste }
5349f2f44ceSEd Maste 
SetAutoIndent(bool b)535435933ddSDimitry Andric bool Debugger::SetAutoIndent(bool b) {
5369f2f44ceSEd Maste   const uint32_t idx = ePropertyAutoIndent;
5374bb0738eSEd Maste   return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
5389f2f44ceSEd Maste }
5399f2f44ceSEd Maste 
GetPrintDecls() const540435933ddSDimitry Andric bool Debugger::GetPrintDecls() const {
5419f2f44ceSEd Maste   const uint32_t idx = ePropertyPrintDecls;
5424bb0738eSEd Maste   return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
5439f2f44ceSEd Maste }
5449f2f44ceSEd Maste 
SetPrintDecls(bool b)545435933ddSDimitry Andric bool Debugger::SetPrintDecls(bool b) {
5469f2f44ceSEd Maste   const uint32_t idx = ePropertyPrintDecls;
5474bb0738eSEd Maste   return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
5489f2f44ceSEd Maste }
5499f2f44ceSEd Maste 
GetTabSize() const550435933ddSDimitry Andric uint32_t Debugger::GetTabSize() const {
5519f2f44ceSEd Maste   const uint32_t idx = ePropertyTabSize;
552435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsUInt64(
553435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value);
5549f2f44ceSEd Maste }
5559f2f44ceSEd Maste 
SetTabSize(uint32_t tab_size)556435933ddSDimitry Andric bool Debugger::SetTabSize(uint32_t tab_size) {
5579f2f44ceSEd Maste   const uint32_t idx = ePropertyTabSize;
5584bb0738eSEd Maste   return m_collection_sp->SetPropertyAtIndexAsUInt64(nullptr, idx, tab_size);
5599f2f44ceSEd Maste }
5609f2f44ceSEd Maste 
561ac7ddfbfSEd Maste #pragma mark Debugger
562ac7ddfbfSEd Maste 
563ac7ddfbfSEd Maste // const DebuggerPropertiesSP &
564ac7ddfbfSEd Maste // Debugger::GetSettings() const
565ac7ddfbfSEd Maste //{
566ac7ddfbfSEd Maste //    return m_properties_sp;
567ac7ddfbfSEd Maste //}
568ac7ddfbfSEd Maste //
569ac7ddfbfSEd Maste 
Initialize(LoadPluginCallbackType load_plugin_callback)570435933ddSDimitry Andric void Debugger::Initialize(LoadPluginCallbackType load_plugin_callback) {
571435933ddSDimitry Andric   assert(g_debugger_list_ptr == nullptr &&
572435933ddSDimitry Andric          "Debugger::Initialize called more than once!");
5734bb0738eSEd Maste   g_debugger_list_mutex_ptr = new std::recursive_mutex();
5744bb0738eSEd Maste   g_debugger_list_ptr = new DebuggerList();
575b952cd58SEd Maste   g_load_plugin_callback = load_plugin_callback;
576ac7ddfbfSEd Maste }
577ac7ddfbfSEd Maste 
Terminate()578435933ddSDimitry Andric void Debugger::Terminate() {
579435933ddSDimitry Andric   assert(g_debugger_list_ptr &&
580435933ddSDimitry Andric          "Debugger::Terminate called without a matching Debugger::Initialize!");
581ac7ddfbfSEd Maste 
582435933ddSDimitry Andric   if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
583ac7ddfbfSEd Maste     // Clear our master list of debugger objects
5844bb0738eSEd Maste     {
5854bb0738eSEd Maste       std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
5864bb0738eSEd Maste       for (const auto &debugger : *g_debugger_list_ptr)
5879f2f44ceSEd Maste         debugger->Clear();
5884bb0738eSEd Maste       g_debugger_list_ptr->clear();
5894bb0738eSEd Maste     }
5904bb0738eSEd Maste   }
591ac7ddfbfSEd Maste }
592ac7ddfbfSEd Maste 
SettingsInitialize()593435933ddSDimitry Andric void Debugger::SettingsInitialize() { Target::SettingsInitialize(); }
594ac7ddfbfSEd Maste 
SettingsTerminate()595435933ddSDimitry Andric void Debugger::SettingsTerminate() { Target::SettingsTerminate(); }
596ac7ddfbfSEd Maste 
LoadPlugin(const FileSpec & spec,Status & error)5975517e702SDimitry Andric bool Debugger::LoadPlugin(const FileSpec &spec, Status &error) {
598435933ddSDimitry Andric   if (g_load_plugin_callback) {
599435933ddSDimitry Andric     llvm::sys::DynamicLibrary dynlib =
600435933ddSDimitry Andric         g_load_plugin_callback(shared_from_this(), spec, error);
601435933ddSDimitry Andric     if (dynlib.isValid()) {
6020127ef0fSEd Maste       m_loaded_plugins.push_back(dynlib);
603ac7ddfbfSEd Maste       return true;
604ac7ddfbfSEd Maste     }
605435933ddSDimitry Andric   } else {
6064ba319b5SDimitry Andric     // The g_load_plugin_callback is registered in SBDebugger::Initialize() and
6074ba319b5SDimitry Andric     // if the public API layer isn't available (code is linking against all of
6084ba319b5SDimitry Andric     // the internal LLDB static libraries), then we can't load plugins
609b952cd58SEd Maste     error.SetErrorString("Public API layer is not available");
610b952cd58SEd Maste   }
611ac7ddfbfSEd Maste   return false;
612ac7ddfbfSEd Maste }
613ac7ddfbfSEd Maste 
614*b5893f02SDimitry Andric static FileSystem::EnumerateDirectoryResult
LoadPluginCallback(void * baton,llvm::sys::fs::file_type ft,llvm::StringRef path)615f678e45dSDimitry Andric LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
616*b5893f02SDimitry Andric                    llvm::StringRef path) {
6175517e702SDimitry Andric   Status error;
618ac7ddfbfSEd Maste 
6194ba319b5SDimitry Andric   static ConstString g_dylibext(".dylib");
6204ba319b5SDimitry Andric   static ConstString g_solibext(".so");
621ac7ddfbfSEd Maste 
622ac7ddfbfSEd Maste   if (!baton)
623*b5893f02SDimitry Andric     return FileSystem::eEnumerateDirectoryResultQuit;
624ac7ddfbfSEd Maste 
625ac7ddfbfSEd Maste   Debugger *debugger = (Debugger *)baton;
626ac7ddfbfSEd Maste 
627f678e45dSDimitry Andric   namespace fs = llvm::sys::fs;
6284ba319b5SDimitry Andric   // If we have a regular file, a symbolic link or unknown file type, try and
6294ba319b5SDimitry Andric   // process the file. We must handle unknown as sometimes the directory
630ac7ddfbfSEd Maste   // enumeration might be enumerating a file system that doesn't have correct
631ac7ddfbfSEd Maste   // file type information.
632f678e45dSDimitry Andric   if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file ||
633f678e45dSDimitry Andric       ft == fs::file_type::type_unknown) {
634*b5893f02SDimitry Andric     FileSpec plugin_file_spec(path);
635*b5893f02SDimitry Andric     FileSystem::Instance().Resolve(plugin_file_spec);
636ac7ddfbfSEd Maste 
637ac7ddfbfSEd Maste     if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
638435933ddSDimitry Andric         plugin_file_spec.GetFileNameExtension() != g_solibext) {
639*b5893f02SDimitry Andric       return FileSystem::eEnumerateDirectoryResultNext;
640ac7ddfbfSEd Maste     }
641ac7ddfbfSEd Maste 
6425517e702SDimitry Andric     Status plugin_load_error;
643ac7ddfbfSEd Maste     debugger->LoadPlugin(plugin_file_spec, plugin_load_error);
644ac7ddfbfSEd Maste 
645*b5893f02SDimitry Andric     return FileSystem::eEnumerateDirectoryResultNext;
646f678e45dSDimitry Andric   } else if (ft == fs::file_type::directory_file ||
647f678e45dSDimitry Andric              ft == fs::file_type::symlink_file ||
648f678e45dSDimitry Andric              ft == fs::file_type::type_unknown) {
6494ba319b5SDimitry Andric     // Try and recurse into anything that a directory or symbolic link. We must
6504ba319b5SDimitry Andric     // also do this for unknown as sometimes the directory enumeration might be
6514ba319b5SDimitry Andric     // enumerating a file system that doesn't have correct file type
652ac7ddfbfSEd Maste     // information.
653*b5893f02SDimitry Andric     return FileSystem::eEnumerateDirectoryResultEnter;
654ac7ddfbfSEd Maste   }
655ac7ddfbfSEd Maste 
656*b5893f02SDimitry Andric   return FileSystem::eEnumerateDirectoryResultNext;
657ac7ddfbfSEd Maste }
658ac7ddfbfSEd Maste 
InstanceInitialize()659435933ddSDimitry Andric void Debugger::InstanceInitialize() {
660ac7ddfbfSEd Maste   const bool find_directories = true;
661ac7ddfbfSEd Maste   const bool find_files = true;
662ac7ddfbfSEd Maste   const bool find_other = true;
663ac7ddfbfSEd Maste   char dir_path[PATH_MAX];
6644ba319b5SDimitry Andric   if (FileSpec dir_spec = HostInfo::GetSystemPluginDir()) {
665*b5893f02SDimitry Andric     if (FileSystem::Instance().Exists(dir_spec) &&
666*b5893f02SDimitry Andric         dir_spec.GetPath(dir_path, sizeof(dir_path))) {
667*b5893f02SDimitry Andric       FileSystem::Instance().EnumerateDirectory(dir_path, find_directories,
668*b5893f02SDimitry Andric                                                 find_files, find_other,
669*b5893f02SDimitry Andric                                                 LoadPluginCallback, this);
670ac7ddfbfSEd Maste     }
671ac7ddfbfSEd Maste   }
672ac7ddfbfSEd Maste 
6734ba319b5SDimitry Andric   if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) {
674*b5893f02SDimitry Andric     if (FileSystem::Instance().Exists(dir_spec) &&
675*b5893f02SDimitry Andric         dir_spec.GetPath(dir_path, sizeof(dir_path))) {
676*b5893f02SDimitry Andric       FileSystem::Instance().EnumerateDirectory(dir_path, find_directories,
677*b5893f02SDimitry Andric                                                 find_files, find_other,
678*b5893f02SDimitry Andric                                                 LoadPluginCallback, this);
679ac7ddfbfSEd Maste     }
680ac7ddfbfSEd Maste   }
681ac7ddfbfSEd Maste 
682ac7ddfbfSEd Maste   PluginManager::DebuggerInitialize(*this);
683ac7ddfbfSEd Maste }
684ac7ddfbfSEd Maste 
CreateInstance(lldb::LogOutputCallback log_callback,void * baton)685435933ddSDimitry Andric DebuggerSP Debugger::CreateInstance(lldb::LogOutputCallback log_callback,
686435933ddSDimitry Andric                                     void *baton) {
687ac7ddfbfSEd Maste   DebuggerSP debugger_sp(new Debugger(log_callback, baton));
688435933ddSDimitry Andric   if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
6894bb0738eSEd Maste     std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
6904bb0738eSEd Maste     g_debugger_list_ptr->push_back(debugger_sp);
691ac7ddfbfSEd Maste   }
692ac7ddfbfSEd Maste   debugger_sp->InstanceInitialize();
693ac7ddfbfSEd Maste   return debugger_sp;
694ac7ddfbfSEd Maste }
695ac7ddfbfSEd Maste 
Destroy(DebuggerSP & debugger_sp)696435933ddSDimitry Andric void Debugger::Destroy(DebuggerSP &debugger_sp) {
6974bb0738eSEd Maste   if (!debugger_sp)
698ac7ddfbfSEd Maste     return;
699ac7ddfbfSEd Maste 
700ac7ddfbfSEd Maste   debugger_sp->Clear();
701ac7ddfbfSEd Maste 
702435933ddSDimitry Andric   if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
7034bb0738eSEd Maste     std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
7044bb0738eSEd Maste     DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
705435933ddSDimitry Andric     for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
706435933ddSDimitry Andric       if ((*pos).get() == debugger_sp.get()) {
7074bb0738eSEd Maste         g_debugger_list_ptr->erase(pos);
708ac7ddfbfSEd Maste         return;
709ac7ddfbfSEd Maste       }
710ac7ddfbfSEd Maste     }
711ac7ddfbfSEd Maste   }
712ac7ddfbfSEd Maste }
713ac7ddfbfSEd Maste 
714ac7ddfbfSEd Maste DebuggerSP
FindDebuggerWithInstanceName(const ConstString & instance_name)715435933ddSDimitry Andric Debugger::FindDebuggerWithInstanceName(const ConstString &instance_name) {
716ac7ddfbfSEd Maste   DebuggerSP debugger_sp;
717435933ddSDimitry Andric   if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
7184bb0738eSEd Maste     std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
7194bb0738eSEd Maste     DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
720435933ddSDimitry Andric     for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
721435933ddSDimitry Andric       if ((*pos)->m_instance_name == instance_name) {
722ac7ddfbfSEd Maste         debugger_sp = *pos;
723ac7ddfbfSEd Maste         break;
724ac7ddfbfSEd Maste       }
725ac7ddfbfSEd Maste     }
726ac7ddfbfSEd Maste   }
727ac7ddfbfSEd Maste   return debugger_sp;
728ac7ddfbfSEd Maste }
729ac7ddfbfSEd Maste 
FindTargetWithProcessID(lldb::pid_t pid)730435933ddSDimitry Andric TargetSP Debugger::FindTargetWithProcessID(lldb::pid_t pid) {
731ac7ddfbfSEd Maste   TargetSP target_sp;
732435933ddSDimitry Andric   if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
7334bb0738eSEd Maste     std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
7344bb0738eSEd Maste     DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
735435933ddSDimitry Andric     for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
736ac7ddfbfSEd Maste       target_sp = (*pos)->GetTargetList().FindTargetWithProcessID(pid);
737ac7ddfbfSEd Maste       if (target_sp)
738ac7ddfbfSEd Maste         break;
739ac7ddfbfSEd Maste     }
740ac7ddfbfSEd Maste   }
741ac7ddfbfSEd Maste   return target_sp;
742ac7ddfbfSEd Maste }
743ac7ddfbfSEd Maste 
FindTargetWithProcess(Process * process)744435933ddSDimitry Andric TargetSP Debugger::FindTargetWithProcess(Process *process) {
745ac7ddfbfSEd Maste   TargetSP target_sp;
746435933ddSDimitry Andric   if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
7474bb0738eSEd Maste     std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
7484bb0738eSEd Maste     DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
749435933ddSDimitry Andric     for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
750ac7ddfbfSEd Maste       target_sp = (*pos)->GetTargetList().FindTargetWithProcess(process);
751ac7ddfbfSEd Maste       if (target_sp)
752ac7ddfbfSEd Maste         break;
753ac7ddfbfSEd Maste     }
754ac7ddfbfSEd Maste   }
755ac7ddfbfSEd Maste   return target_sp;
756ac7ddfbfSEd Maste }
757ac7ddfbfSEd Maste 
Debugger(lldb::LogOutputCallback log_callback,void * baton)758435933ddSDimitry Andric Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton)
759435933ddSDimitry Andric     : UserID(g_unique_id++),
760f678e45dSDimitry Andric       Properties(std::make_shared<OptionValueProperties>()),
761f678e45dSDimitry Andric       m_input_file_sp(std::make_shared<StreamFile>(stdin, false)),
762f678e45dSDimitry Andric       m_output_file_sp(std::make_shared<StreamFile>(stdout, false)),
763f678e45dSDimitry Andric       m_error_file_sp(std::make_shared<StreamFile>(stderr, false)),
7644bb0738eSEd Maste       m_broadcaster_manager_sp(BroadcasterManager::MakeBroadcasterManager()),
765435933ddSDimitry Andric       m_terminal_state(), m_target_list(*this), m_platform_list(),
7664bb0738eSEd Maste       m_listener_sp(Listener::MakeListener("lldb.Debugger")),
767435933ddSDimitry Andric       m_source_manager_ap(), m_source_file_cache(),
768f678e45dSDimitry Andric       m_command_interpreter_ap(llvm::make_unique<CommandInterpreter>(
769f678e45dSDimitry Andric           *this, eScriptLanguageDefault, false)),
770435933ddSDimitry Andric       m_input_reader_stack(), m_instance_name(), m_loaded_plugins(),
771435933ddSDimitry Andric       m_event_handler_thread(), m_io_handler_thread(),
7724bb0738eSEd Maste       m_sync_broadcaster(nullptr, "lldb.debugger.sync"),
773435933ddSDimitry Andric       m_forward_listener_sp(), m_clear_once() {
774ac7ddfbfSEd Maste   char instance_cstr[256];
775ac7ddfbfSEd Maste   snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
776ac7ddfbfSEd Maste   m_instance_name.SetCString(instance_cstr);
777ac7ddfbfSEd Maste   if (log_callback)
778f678e45dSDimitry Andric     m_log_callback_stream_sp =
779f678e45dSDimitry Andric         std::make_shared<StreamCallback>(log_callback, baton);
780ac7ddfbfSEd Maste   m_command_interpreter_ap->Initialize();
781ac7ddfbfSEd Maste   // Always add our default platform to the platform list
7827aa51b79SEd Maste   PlatformSP default_platform_sp(Platform::GetHostPlatform());
7834bb0738eSEd Maste   assert(default_platform_sp);
784ac7ddfbfSEd Maste   m_platform_list.Append(default_platform_sp, true);
785ac7ddfbfSEd Maste 
786ac7ddfbfSEd Maste   m_collection_sp->Initialize(g_properties);
787435933ddSDimitry Andric   m_collection_sp->AppendProperty(
788435933ddSDimitry Andric       ConstString("target"),
789435933ddSDimitry Andric       ConstString("Settings specify to debugging targets."), true,
790ac7ddfbfSEd Maste       Target::GetGlobalProperties()->GetValueProperties());
791435933ddSDimitry Andric   m_collection_sp->AppendProperty(
792435933ddSDimitry Andric       ConstString("platform"), ConstString("Platform settings."), true,
7931c3bbb01SEd Maste       Platform::GetGlobalPlatformProperties()->GetValueProperties());
7944ba319b5SDimitry Andric   m_collection_sp->AppendProperty(
7954ba319b5SDimitry Andric       ConstString("symbols"), ConstString("Symbol lookup and cache settings."),
7964ba319b5SDimitry Andric       true, ModuleList::GetGlobalModuleListProperties().GetValueProperties());
797435933ddSDimitry Andric   if (m_command_interpreter_ap) {
798435933ddSDimitry Andric     m_collection_sp->AppendProperty(
799435933ddSDimitry Andric         ConstString("interpreter"),
800ac7ddfbfSEd Maste         ConstString("Settings specify to the debugger's command interpreter."),
801435933ddSDimitry Andric         true, m_command_interpreter_ap->GetValueProperties());
802ac7ddfbfSEd Maste   }
803435933ddSDimitry Andric   OptionValueSInt64 *term_width =
804435933ddSDimitry Andric       m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64(
805435933ddSDimitry Andric           nullptr, ePropertyTerminalWidth);
806ac7ddfbfSEd Maste   term_width->SetMinimumValue(10);
807ac7ddfbfSEd Maste   term_width->SetMaximumValue(1024);
808ac7ddfbfSEd Maste 
809ac7ddfbfSEd Maste   // Turn off use-color if this is a dumb terminal.
810ac7ddfbfSEd Maste   const char *term = getenv("TERM");
811ac7ddfbfSEd Maste   if (term && !strcmp(term, "dumb"))
812ac7ddfbfSEd Maste     SetUseColor(false);
813*b5893f02SDimitry Andric   // Turn off use-color if we don't write to a terminal with color support.
814*b5893f02SDimitry Andric   if (!m_output_file_sp->GetFile().GetIsTerminalWithColors())
815*b5893f02SDimitry Andric     SetUseColor(false);
816*b5893f02SDimitry Andric 
817*b5893f02SDimitry Andric #if defined(_WIN32) && defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING)
818*b5893f02SDimitry Andric   // Enabling use of ANSI color codes because LLDB is using them to highlight
819*b5893f02SDimitry Andric   // text.
820*b5893f02SDimitry Andric   llvm::sys::Process::UseANSIEscapeCodes(true);
821*b5893f02SDimitry Andric #endif
822ac7ddfbfSEd Maste }
823ac7ddfbfSEd Maste 
~Debugger()824435933ddSDimitry Andric Debugger::~Debugger() { Clear(); }
825ac7ddfbfSEd Maste 
Clear()826435933ddSDimitry Andric void Debugger::Clear() {
8274bb0738eSEd Maste   //----------------------------------------------------------------------
8284ba319b5SDimitry Andric   // Make sure we call this function only once. With the C++ global destructor
8294ba319b5SDimitry Andric   // chain having a list of debuggers and with code that can be running on
8304ba319b5SDimitry Andric   // other threads, we need to ensure this doesn't happen multiple times.
8314bb0738eSEd Maste   //
8324bb0738eSEd Maste   // The following functions call Debugger::Clear():
8334bb0738eSEd Maste   //     Debugger::~Debugger();
8344bb0738eSEd Maste   //     static void Debugger::Destroy(lldb::DebuggerSP &debugger_sp);
8354bb0738eSEd Maste   //     static void Debugger::Terminate();
8364bb0738eSEd Maste   //----------------------------------------------------------------------
837f678e45dSDimitry Andric   llvm::call_once(m_clear_once, [this]() {
83812b93ac6SEd Maste     ClearIOHandlers();
83912b93ac6SEd Maste     StopIOHandlerThread();
84012b93ac6SEd Maste     StopEventHandlerThread();
8414bb0738eSEd Maste     m_listener_sp->Clear();
842ac7ddfbfSEd Maste     int num_targets = m_target_list.GetNumTargets();
843435933ddSDimitry Andric     for (int i = 0; i < num_targets; i++) {
844ac7ddfbfSEd Maste       TargetSP target_sp(m_target_list.GetTargetAtIndex(i));
845435933ddSDimitry Andric       if (target_sp) {
846ac7ddfbfSEd Maste         ProcessSP process_sp(target_sp->GetProcessSP());
847ac7ddfbfSEd Maste         if (process_sp)
848ac7ddfbfSEd Maste           process_sp->Finalize();
849ac7ddfbfSEd Maste         target_sp->Destroy();
850ac7ddfbfSEd Maste       }
851ac7ddfbfSEd Maste     }
8524bb0738eSEd Maste     m_broadcaster_manager_sp->Clear();
853ac7ddfbfSEd Maste 
854435933ddSDimitry Andric     // Close the input file _before_ we close the input read communications
8554ba319b5SDimitry Andric     // class as it does NOT own the input file, our m_input_file does.
856ac7ddfbfSEd Maste     m_terminal_state.Clear();
85712b93ac6SEd Maste     if (m_input_file_sp)
85812b93ac6SEd Maste       m_input_file_sp->GetFile().Close();
8590127ef0fSEd Maste 
8600127ef0fSEd Maste     m_command_interpreter_ap->Clear();
8614bb0738eSEd Maste   });
862ac7ddfbfSEd Maste }
863ac7ddfbfSEd Maste 
GetCloseInputOnEOF() const864435933ddSDimitry Andric bool Debugger::GetCloseInputOnEOF() const {
86512b93ac6SEd Maste   //    return m_input_comm.GetCloseOnEOF();
86612b93ac6SEd Maste   return false;
867ac7ddfbfSEd Maste }
868ac7ddfbfSEd Maste 
SetCloseInputOnEOF(bool b)869435933ddSDimitry Andric void Debugger::SetCloseInputOnEOF(bool b) {
87012b93ac6SEd Maste   //    m_input_comm.SetCloseOnEOF(b);
871ac7ddfbfSEd Maste }
872ac7ddfbfSEd Maste 
GetAsyncExecution()873435933ddSDimitry Andric bool Debugger::GetAsyncExecution() {
874ac7ddfbfSEd Maste   return !m_command_interpreter_ap->GetSynchronous();
875ac7ddfbfSEd Maste }
876ac7ddfbfSEd Maste 
SetAsyncExecution(bool async_execution)877435933ddSDimitry Andric void Debugger::SetAsyncExecution(bool async_execution) {
878ac7ddfbfSEd Maste   m_command_interpreter_ap->SetSynchronous(!async_execution);
879ac7ddfbfSEd Maste }
880ac7ddfbfSEd Maste 
SetInputFileHandle(FILE * fh,bool tranfer_ownership)881435933ddSDimitry Andric void Debugger::SetInputFileHandle(FILE *fh, bool tranfer_ownership) {
88212b93ac6SEd Maste   if (m_input_file_sp)
88312b93ac6SEd Maste     m_input_file_sp->GetFile().SetStream(fh, tranfer_ownership);
88412b93ac6SEd Maste   else
885f678e45dSDimitry Andric     m_input_file_sp = std::make_shared<StreamFile>(fh, tranfer_ownership);
88612b93ac6SEd Maste 
88712b93ac6SEd Maste   File &in_file = m_input_file_sp->GetFile();
8884bb0738eSEd Maste   if (!in_file.IsValid())
889ac7ddfbfSEd Maste     in_file.SetStream(stdin, true);
890ac7ddfbfSEd Maste 
8914ba319b5SDimitry Andric   // Save away the terminal state if that is relevant, so that we can restore
8924ba319b5SDimitry Andric   // it in RestoreInputState.
893ac7ddfbfSEd Maste   SaveInputTerminalState();
894ac7ddfbfSEd Maste }
895ac7ddfbfSEd Maste 
SetOutputFileHandle(FILE * fh,bool tranfer_ownership)896435933ddSDimitry Andric void Debugger::SetOutputFileHandle(FILE *fh, bool tranfer_ownership) {
89712b93ac6SEd Maste   if (m_output_file_sp)
89812b93ac6SEd Maste     m_output_file_sp->GetFile().SetStream(fh, tranfer_ownership);
89912b93ac6SEd Maste   else
900f678e45dSDimitry Andric     m_output_file_sp = std::make_shared<StreamFile>(fh, tranfer_ownership);
90112b93ac6SEd Maste 
90212b93ac6SEd Maste   File &out_file = m_output_file_sp->GetFile();
9034bb0738eSEd Maste   if (!out_file.IsValid())
904ac7ddfbfSEd Maste     out_file.SetStream(stdout, false);
905ac7ddfbfSEd Maste 
9064ba319b5SDimitry Andric   // do not create the ScriptInterpreter just for setting the output file
9074ba319b5SDimitry Andric   // handle as the constructor will know how to do the right thing on its own
908ac7ddfbfSEd Maste   const bool can_create = false;
909435933ddSDimitry Andric   ScriptInterpreter *script_interpreter =
910435933ddSDimitry Andric       GetCommandInterpreter().GetScriptInterpreter(can_create);
911ac7ddfbfSEd Maste   if (script_interpreter)
912ac7ddfbfSEd Maste     script_interpreter->ResetOutputFileHandle(fh);
913ac7ddfbfSEd Maste }
914ac7ddfbfSEd Maste 
SetErrorFileHandle(FILE * fh,bool tranfer_ownership)915435933ddSDimitry Andric void Debugger::SetErrorFileHandle(FILE *fh, bool tranfer_ownership) {
91612b93ac6SEd Maste   if (m_error_file_sp)
91712b93ac6SEd Maste     m_error_file_sp->GetFile().SetStream(fh, tranfer_ownership);
91812b93ac6SEd Maste   else
919f678e45dSDimitry Andric     m_error_file_sp = std::make_shared<StreamFile>(fh, tranfer_ownership);
92012b93ac6SEd Maste 
92112b93ac6SEd Maste   File &err_file = m_error_file_sp->GetFile();
9224bb0738eSEd Maste   if (!err_file.IsValid())
923ac7ddfbfSEd Maste     err_file.SetStream(stderr, false);
924ac7ddfbfSEd Maste }
925ac7ddfbfSEd Maste 
SaveInputTerminalState()926435933ddSDimitry Andric void Debugger::SaveInputTerminalState() {
927435933ddSDimitry Andric   if (m_input_file_sp) {
92812b93ac6SEd Maste     File &in_file = m_input_file_sp->GetFile();
929ac7ddfbfSEd Maste     if (in_file.GetDescriptor() != File::kInvalidDescriptor)
930ac7ddfbfSEd Maste       m_terminal_state.Save(in_file.GetDescriptor(), true);
931ac7ddfbfSEd Maste   }
93212b93ac6SEd Maste }
933ac7ddfbfSEd Maste 
RestoreInputTerminalState()934435933ddSDimitry Andric void Debugger::RestoreInputTerminalState() { m_terminal_state.Restore(); }
935ac7ddfbfSEd Maste 
GetSelectedExecutionContext()936435933ddSDimitry Andric ExecutionContext Debugger::GetSelectedExecutionContext() {
937ac7ddfbfSEd Maste   ExecutionContext exe_ctx;
938ac7ddfbfSEd Maste   TargetSP target_sp(GetSelectedTarget());
939ac7ddfbfSEd Maste   exe_ctx.SetTargetSP(target_sp);
940ac7ddfbfSEd Maste 
941435933ddSDimitry Andric   if (target_sp) {
942ac7ddfbfSEd Maste     ProcessSP process_sp(target_sp->GetProcessSP());
943ac7ddfbfSEd Maste     exe_ctx.SetProcessSP(process_sp);
944435933ddSDimitry Andric     if (process_sp && !process_sp->IsRunning()) {
945ac7ddfbfSEd Maste       ThreadSP thread_sp(process_sp->GetThreadList().GetSelectedThread());
946435933ddSDimitry Andric       if (thread_sp) {
947ac7ddfbfSEd Maste         exe_ctx.SetThreadSP(thread_sp);
948ac7ddfbfSEd Maste         exe_ctx.SetFrameSP(thread_sp->GetSelectedFrame());
9494bb0738eSEd Maste         if (exe_ctx.GetFramePtr() == nullptr)
950ac7ddfbfSEd Maste           exe_ctx.SetFrameSP(thread_sp->GetStackFrameAtIndex(0));
951ac7ddfbfSEd Maste       }
952ac7ddfbfSEd Maste     }
953ac7ddfbfSEd Maste   }
954ac7ddfbfSEd Maste   return exe_ctx;
955ac7ddfbfSEd Maste }
956ac7ddfbfSEd Maste 
DispatchInputInterrupt()957435933ddSDimitry Andric void Debugger::DispatchInputInterrupt() {
9584bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
95912b93ac6SEd Maste   IOHandlerSP reader_sp(m_input_reader_stack.Top());
960ac7ddfbfSEd Maste   if (reader_sp)
96112b93ac6SEd Maste     reader_sp->Interrupt();
962ac7ddfbfSEd Maste }
963ac7ddfbfSEd Maste 
DispatchInputEndOfFile()964435933ddSDimitry Andric void Debugger::DispatchInputEndOfFile() {
9654bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
96612b93ac6SEd Maste   IOHandlerSP reader_sp(m_input_reader_stack.Top());
967ac7ddfbfSEd Maste   if (reader_sp)
96812b93ac6SEd Maste     reader_sp->GotEOF();
969ac7ddfbfSEd Maste }
970ac7ddfbfSEd Maste 
ClearIOHandlers()971435933ddSDimitry Andric void Debugger::ClearIOHandlers() {
972435933ddSDimitry Andric   // The bottom input reader should be the main debugger input reader.  We do
973435933ddSDimitry Andric   // not want to close that one here.
9744bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
975435933ddSDimitry Andric   while (m_input_reader_stack.GetSize() > 1) {
97612b93ac6SEd Maste     IOHandlerSP reader_sp(m_input_reader_stack.Top());
977ac7ddfbfSEd Maste     if (reader_sp)
9781c3bbb01SEd Maste       PopIOHandler(reader_sp);
979ac7ddfbfSEd Maste   }
980ac7ddfbfSEd Maste }
981ac7ddfbfSEd Maste 
ExecuteIOHandlers()982435933ddSDimitry Andric void Debugger::ExecuteIOHandlers() {
983435933ddSDimitry Andric   while (true) {
98412b93ac6SEd Maste     IOHandlerSP reader_sp(m_input_reader_stack.Top());
985ac7ddfbfSEd Maste     if (!reader_sp)
986ac7ddfbfSEd Maste       break;
987ac7ddfbfSEd Maste 
98812b93ac6SEd Maste     reader_sp->Run();
98912b93ac6SEd Maste 
99012b93ac6SEd Maste     // Remove all input readers that are done from the top of the stack
991435933ddSDimitry Andric     while (true) {
99212b93ac6SEd Maste       IOHandlerSP top_reader_sp = m_input_reader_stack.Top();
99312b93ac6SEd Maste       if (top_reader_sp && top_reader_sp->GetIsDone())
9941c3bbb01SEd Maste         PopIOHandler(top_reader_sp);
995ac7ddfbfSEd Maste       else
996ac7ddfbfSEd Maste         break;
997ac7ddfbfSEd Maste     }
998ac7ddfbfSEd Maste   }
99912b93ac6SEd Maste   ClearIOHandlers();
100012b93ac6SEd Maste }
1001ac7ddfbfSEd Maste 
IsTopIOHandler(const lldb::IOHandlerSP & reader_sp)1002435933ddSDimitry Andric bool Debugger::IsTopIOHandler(const lldb::IOHandlerSP &reader_sp) {
100312b93ac6SEd Maste   return m_input_reader_stack.IsTop(reader_sp);
100412b93ac6SEd Maste }
1005ac7ddfbfSEd Maste 
CheckTopIOHandlerTypes(IOHandler::Type top_type,IOHandler::Type second_top_type)1006435933ddSDimitry Andric bool Debugger::CheckTopIOHandlerTypes(IOHandler::Type top_type,
1007435933ddSDimitry Andric                                       IOHandler::Type second_top_type) {
10089f2f44ceSEd Maste   return m_input_reader_stack.CheckTopIOHandlerTypes(top_type, second_top_type);
10099f2f44ceSEd Maste }
10109f2f44ceSEd Maste 
PrintAsync(const char * s,size_t len,bool is_stdout)1011435933ddSDimitry Andric void Debugger::PrintAsync(const char *s, size_t len, bool is_stdout) {
10121c3bbb01SEd Maste   lldb::StreamFileSP stream = is_stdout ? GetOutputFile() : GetErrorFile();
10131c3bbb01SEd Maste   m_input_reader_stack.PrintAsync(stream.get(), s, len);
10141c3bbb01SEd Maste }
101512b93ac6SEd Maste 
GetTopIOHandlerControlSequence(char ch)1016435933ddSDimitry Andric ConstString Debugger::GetTopIOHandlerControlSequence(char ch) {
101712b93ac6SEd Maste   return m_input_reader_stack.GetTopIOHandlerControlSequence(ch);
1018ac7ddfbfSEd Maste }
1019ac7ddfbfSEd Maste 
GetIOHandlerCommandPrefix()1020435933ddSDimitry Andric const char *Debugger::GetIOHandlerCommandPrefix() {
10211c3bbb01SEd Maste   return m_input_reader_stack.GetTopIOHandlerCommandPrefix();
10221c3bbb01SEd Maste }
10231c3bbb01SEd Maste 
GetIOHandlerHelpPrologue()1024435933ddSDimitry Andric const char *Debugger::GetIOHandlerHelpPrologue() {
10251c3bbb01SEd Maste   return m_input_reader_stack.GetTopIOHandlerHelpPrologue();
10261c3bbb01SEd Maste }
10271c3bbb01SEd Maste 
RunIOHandler(const IOHandlerSP & reader_sp)1028435933ddSDimitry Andric void Debugger::RunIOHandler(const IOHandlerSP &reader_sp) {
102912b93ac6SEd Maste   PushIOHandler(reader_sp);
10300127ef0fSEd Maste 
10310127ef0fSEd Maste   IOHandlerSP top_reader_sp = reader_sp;
1032435933ddSDimitry Andric   while (top_reader_sp) {
10330127ef0fSEd Maste     top_reader_sp->Run();
10340127ef0fSEd Maste 
1035435933ddSDimitry Andric     if (top_reader_sp.get() == reader_sp.get()) {
10360127ef0fSEd Maste       if (PopIOHandler(reader_sp))
10370127ef0fSEd Maste         break;
10380127ef0fSEd Maste     }
10390127ef0fSEd Maste 
1040435933ddSDimitry Andric     while (true) {
10410127ef0fSEd Maste       top_reader_sp = m_input_reader_stack.Top();
10420127ef0fSEd Maste       if (top_reader_sp && top_reader_sp->GetIsDone())
10431c3bbb01SEd Maste         PopIOHandler(top_reader_sp);
10440127ef0fSEd Maste       else
10450127ef0fSEd Maste         break;
10460127ef0fSEd Maste     }
10470127ef0fSEd Maste   }
104812b93ac6SEd Maste }
104912b93ac6SEd Maste 
AdoptTopIOHandlerFilesIfInvalid(StreamFileSP & in,StreamFileSP & out,StreamFileSP & err)1050435933ddSDimitry Andric void Debugger::AdoptTopIOHandlerFilesIfInvalid(StreamFileSP &in,
1051435933ddSDimitry Andric                                                StreamFileSP &out,
1052435933ddSDimitry Andric                                                StreamFileSP &err) {
10534ba319b5SDimitry Andric   // Before an IOHandler runs, it must have in/out/err streams. This function
10544ba319b5SDimitry Andric   // is called when one ore more of the streams are nullptr. We use the top
10554ba319b5SDimitry Andric   // input reader's in/out/err streams, or fall back to the debugger file
10564ba319b5SDimitry Andric   // handles, or we fall back onto stdin/stdout/stderr as a last resort.
105712b93ac6SEd Maste 
10584bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
105912b93ac6SEd Maste   IOHandlerSP top_reader_sp(m_input_reader_stack.Top());
106012b93ac6SEd Maste   // If no STDIN has been set, then set it appropriately
1061435933ddSDimitry Andric   if (!in) {
106212b93ac6SEd Maste     if (top_reader_sp)
106312b93ac6SEd Maste       in = top_reader_sp->GetInputStreamFile();
106412b93ac6SEd Maste     else
106512b93ac6SEd Maste       in = GetInputFile();
106612b93ac6SEd Maste 
106712b93ac6SEd Maste     // If there is nothing, use stdin
106812b93ac6SEd Maste     if (!in)
1069f678e45dSDimitry Andric       in = std::make_shared<StreamFile>(stdin, false);
107012b93ac6SEd Maste   }
107112b93ac6SEd Maste   // If no STDOUT has been set, then set it appropriately
1072435933ddSDimitry Andric   if (!out) {
107312b93ac6SEd Maste     if (top_reader_sp)
107412b93ac6SEd Maste       out = top_reader_sp->GetOutputStreamFile();
107512b93ac6SEd Maste     else
107612b93ac6SEd Maste       out = GetOutputFile();
107712b93ac6SEd Maste 
107812b93ac6SEd Maste     // If there is nothing, use stdout
107912b93ac6SEd Maste     if (!out)
1080f678e45dSDimitry Andric       out = std::make_shared<StreamFile>(stdout, false);
108112b93ac6SEd Maste   }
108212b93ac6SEd Maste   // If no STDERR has been set, then set it appropriately
1083435933ddSDimitry Andric   if (!err) {
108412b93ac6SEd Maste     if (top_reader_sp)
108512b93ac6SEd Maste       err = top_reader_sp->GetErrorStreamFile();
108612b93ac6SEd Maste     else
108712b93ac6SEd Maste       err = GetErrorFile();
108812b93ac6SEd Maste 
108912b93ac6SEd Maste     // If there is nothing, use stderr
109012b93ac6SEd Maste     if (!err)
1091f678e45dSDimitry Andric       err = std::make_shared<StreamFile>(stdout, false);
109212b93ac6SEd Maste   }
109312b93ac6SEd Maste }
109412b93ac6SEd Maste 
PushIOHandler(const IOHandlerSP & reader_sp,bool cancel_top_handler)1095*b5893f02SDimitry Andric void Debugger::PushIOHandler(const IOHandlerSP &reader_sp,
1096*b5893f02SDimitry Andric                              bool cancel_top_handler) {
1097ac7ddfbfSEd Maste   if (!reader_sp)
1098ac7ddfbfSEd Maste     return;
1099ac7ddfbfSEd Maste 
11004bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
11011c3bbb01SEd Maste 
11021c3bbb01SEd Maste   // Get the current top input reader...
110312b93ac6SEd Maste   IOHandlerSP top_reader_sp(m_input_reader_stack.Top());
1104ac7ddfbfSEd Maste 
11050127ef0fSEd Maste   // Don't push the same IO handler twice...
11061c3bbb01SEd Maste   if (reader_sp == top_reader_sp)
11071c3bbb01SEd Maste     return;
11081c3bbb01SEd Maste 
110912b93ac6SEd Maste   // Push our new input reader
1110ac7ddfbfSEd Maste   m_input_reader_stack.Push(reader_sp);
11111c3bbb01SEd Maste   reader_sp->Activate();
111212b93ac6SEd Maste 
11134ba319b5SDimitry Andric   // Interrupt the top input reader to it will exit its Run() function and let
11144ba319b5SDimitry Andric   // this new input reader take over
1115435933ddSDimitry Andric   if (top_reader_sp) {
111612b93ac6SEd Maste     top_reader_sp->Deactivate();
1117*b5893f02SDimitry Andric     if (cancel_top_handler)
11181c3bbb01SEd Maste       top_reader_sp->Cancel();
1119ac7ddfbfSEd Maste   }
11200127ef0fSEd Maste }
1121ac7ddfbfSEd Maste 
PopIOHandler(const IOHandlerSP & pop_reader_sp)1122435933ddSDimitry Andric bool Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp) {
11231c3bbb01SEd Maste   if (!pop_reader_sp)
11241c3bbb01SEd Maste     return false;
1125ac7ddfbfSEd Maste 
11264bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
112712b93ac6SEd Maste 
11284ba319b5SDimitry Andric   // The reader on the stop of the stack is done, so let the next read on the
11294ba319b5SDimitry Andric   // stack refresh its prompt and if there is one...
11301c3bbb01SEd Maste   if (m_input_reader_stack.IsEmpty())
11311c3bbb01SEd Maste     return false;
11321c3bbb01SEd Maste 
113312b93ac6SEd Maste   IOHandlerSP reader_sp(m_input_reader_stack.Top());
1134ac7ddfbfSEd Maste 
11351c3bbb01SEd Maste   if (pop_reader_sp != reader_sp)
11361c3bbb01SEd Maste     return false;
11371c3bbb01SEd Maste 
113812b93ac6SEd Maste   reader_sp->Deactivate();
11390127ef0fSEd Maste   reader_sp->Cancel();
1140ac7ddfbfSEd Maste   m_input_reader_stack.Pop();
1141ac7ddfbfSEd Maste 
1142ac7ddfbfSEd Maste   reader_sp = m_input_reader_stack.Top();
1143ac7ddfbfSEd Maste   if (reader_sp)
114412b93ac6SEd Maste     reader_sp->Activate();
114512b93ac6SEd Maste 
114612b93ac6SEd Maste   return true;
1147ac7ddfbfSEd Maste }
1148ac7ddfbfSEd Maste 
GetAsyncOutputStream()1149435933ddSDimitry Andric StreamSP Debugger::GetAsyncOutputStream() {
1150f678e45dSDimitry Andric   return std::make_shared<StreamAsynchronousIO>(*this, true);
1151ac7ddfbfSEd Maste }
1152ac7ddfbfSEd Maste 
GetAsyncErrorStream()1153435933ddSDimitry Andric StreamSP Debugger::GetAsyncErrorStream() {
1154f678e45dSDimitry Andric   return std::make_shared<StreamAsynchronousIO>(*this, false);
1155ac7ddfbfSEd Maste }
1156ac7ddfbfSEd Maste 
GetNumDebuggers()1157435933ddSDimitry Andric size_t Debugger::GetNumDebuggers() {
1158435933ddSDimitry Andric   if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
11594bb0738eSEd Maste     std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
11604bb0738eSEd Maste     return g_debugger_list_ptr->size();
1161ac7ddfbfSEd Maste   }
1162ac7ddfbfSEd Maste   return 0;
1163ac7ddfbfSEd Maste }
1164ac7ddfbfSEd Maste 
GetDebuggerAtIndex(size_t index)1165435933ddSDimitry Andric lldb::DebuggerSP Debugger::GetDebuggerAtIndex(size_t index) {
1166ac7ddfbfSEd Maste   DebuggerSP debugger_sp;
1167ac7ddfbfSEd Maste 
1168435933ddSDimitry Andric   if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
11694bb0738eSEd Maste     std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
11704bb0738eSEd Maste     if (index < g_debugger_list_ptr->size())
11714bb0738eSEd Maste       debugger_sp = g_debugger_list_ptr->at(index);
1172ac7ddfbfSEd Maste   }
1173ac7ddfbfSEd Maste 
1174ac7ddfbfSEd Maste   return debugger_sp;
1175ac7ddfbfSEd Maste }
1176ac7ddfbfSEd Maste 
FindDebuggerWithID(lldb::user_id_t id)1177435933ddSDimitry Andric DebuggerSP Debugger::FindDebuggerWithID(lldb::user_id_t id) {
1178ac7ddfbfSEd Maste   DebuggerSP debugger_sp;
1179ac7ddfbfSEd Maste 
1180435933ddSDimitry Andric   if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
11814bb0738eSEd Maste     std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
11824bb0738eSEd Maste     DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
1183435933ddSDimitry Andric     for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
1184435933ddSDimitry Andric       if ((*pos)->GetID() == id) {
1185ac7ddfbfSEd Maste         debugger_sp = *pos;
1186ac7ddfbfSEd Maste         break;
1187ac7ddfbfSEd Maste       }
1188ac7ddfbfSEd Maste     }
1189ac7ddfbfSEd Maste   }
1190ac7ddfbfSEd Maste   return debugger_sp;
1191ac7ddfbfSEd Maste }
1192ac7ddfbfSEd Maste 
FormatDisassemblerAddress(const FormatEntity::Entry * format,const SymbolContext * sc,const SymbolContext * prev_sc,const ExecutionContext * exe_ctx,const Address * addr,Stream & s)1193435933ddSDimitry Andric bool Debugger::FormatDisassemblerAddress(const FormatEntity::Entry *format,
11947aa51b79SEd Maste                                          const SymbolContext *sc,
11957aa51b79SEd Maste                                          const SymbolContext *prev_sc,
11967aa51b79SEd Maste                                          const ExecutionContext *exe_ctx,
1197435933ddSDimitry Andric                                          const Address *addr, Stream &s) {
11981c3bbb01SEd Maste   FormatEntity::Entry format_entry;
11991c3bbb01SEd Maste 
1200435933ddSDimitry Andric   if (format == nullptr) {
12014bb0738eSEd Maste     if (exe_ctx != nullptr && exe_ctx->HasTargetScope())
12027aa51b79SEd Maste       format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
1203435933ddSDimitry Andric     if (format == nullptr) {
12041c3bbb01SEd Maste       FormatEntity::Parse("${addr}: ", format_entry);
12051c3bbb01SEd Maste       format = &format_entry;
12061c3bbb01SEd Maste     }
12077aa51b79SEd Maste   }
12087aa51b79SEd Maste   bool function_changed = false;
12097aa51b79SEd Maste   bool initial_function = false;
1210435933ddSDimitry Andric   if (prev_sc && (prev_sc->function || prev_sc->symbol)) {
1211435933ddSDimitry Andric     if (sc && (sc->function || sc->symbol)) {
1212435933ddSDimitry Andric       if (prev_sc->symbol && sc->symbol) {
1213435933ddSDimitry Andric         if (!sc->symbol->Compare(prev_sc->symbol->GetName(),
1214435933ddSDimitry Andric                                  prev_sc->symbol->GetType())) {
12157aa51b79SEd Maste           function_changed = true;
12167aa51b79SEd Maste         }
1217435933ddSDimitry Andric       } else if (prev_sc->function && sc->function) {
1218435933ddSDimitry Andric         if (prev_sc->function->GetMangled() != sc->function->GetMangled()) {
12197aa51b79SEd Maste           function_changed = true;
12207aa51b79SEd Maste         }
12217aa51b79SEd Maste       }
12227aa51b79SEd Maste     }
12237aa51b79SEd Maste   }
12244ba319b5SDimitry Andric   // The first context on a list of instructions will have a prev_sc that has
12254ba319b5SDimitry Andric   // no Function or Symbol -- if SymbolContext had an IsValid() method, it
12267aa51b79SEd Maste   // would return false.  But we do get a prev_sc pointer.
1227435933ddSDimitry Andric   if ((sc && (sc->function || sc->symbol)) && prev_sc &&
1228435933ddSDimitry Andric       (prev_sc->function == nullptr && prev_sc->symbol == nullptr)) {
12297aa51b79SEd Maste     initial_function = true;
12307aa51b79SEd Maste   }
1231435933ddSDimitry Andric   return FormatEntity::Format(*format, s, sc, exe_ctx, addr, nullptr,
1232435933ddSDimitry Andric                               function_changed, initial_function);
12337aa51b79SEd Maste }
12347aa51b79SEd Maste 
SetLoggingCallback(lldb::LogOutputCallback log_callback,void * baton)1235435933ddSDimitry Andric void Debugger::SetLoggingCallback(lldb::LogOutputCallback log_callback,
1236435933ddSDimitry Andric                                   void *baton) {
1237ac7ddfbfSEd Maste   // For simplicity's sake, I am not going to deal with how to close down any
1238ac7ddfbfSEd Maste   // open logging streams, I just redirect everything from here on out to the
1239ac7ddfbfSEd Maste   // callback.
1240f678e45dSDimitry Andric   m_log_callback_stream_sp =
1241f678e45dSDimitry Andric       std::make_shared<StreamCallback>(log_callback, baton);
1242ac7ddfbfSEd Maste }
1243ac7ddfbfSEd Maste 
EnableLog(llvm::StringRef channel,llvm::ArrayRef<const char * > categories,llvm::StringRef log_file,uint32_t log_options,llvm::raw_ostream & error_stream)1244f678e45dSDimitry Andric bool Debugger::EnableLog(llvm::StringRef channel,
1245f678e45dSDimitry Andric                          llvm::ArrayRef<const char *> categories,
1246f678e45dSDimitry Andric                          llvm::StringRef log_file, uint32_t log_options,
1247f678e45dSDimitry Andric                          llvm::raw_ostream &error_stream) {
1248f678e45dSDimitry Andric   const bool should_close = true;
1249f678e45dSDimitry Andric   const bool unbuffered = true;
1250f678e45dSDimitry Andric 
1251f678e45dSDimitry Andric   std::shared_ptr<llvm::raw_ostream> log_stream_sp;
1252435933ddSDimitry Andric   if (m_log_callback_stream_sp) {
1253ac7ddfbfSEd Maste     log_stream_sp = m_log_callback_stream_sp;
1254ac7ddfbfSEd Maste     // For now when using the callback mode you always get thread & timestamp.
1255435933ddSDimitry Andric     log_options |=
1256435933ddSDimitry Andric         LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
1257f678e45dSDimitry Andric   } else if (log_file.empty()) {
1258f678e45dSDimitry Andric     log_stream_sp = std::make_shared<llvm::raw_fd_ostream>(
1259f678e45dSDimitry Andric         GetOutputFile()->GetFile().GetDescriptor(), !should_close, unbuffered);
1260435933ddSDimitry Andric   } else {
1261f678e45dSDimitry Andric     auto pos = m_log_streams.find(log_file);
1262ac7ddfbfSEd Maste     if (pos != m_log_streams.end())
1263ac7ddfbfSEd Maste       log_stream_sp = pos->second.lock();
1264435933ddSDimitry Andric     if (!log_stream_sp) {
1265f678e45dSDimitry Andric       llvm::sys::fs::OpenFlags flags = llvm::sys::fs::F_Text;
1266f678e45dSDimitry Andric       if (log_options & LLDB_LOG_OPTION_APPEND)
1267f678e45dSDimitry Andric         flags |= llvm::sys::fs::F_Append;
1268f678e45dSDimitry Andric       int FD;
12694ba319b5SDimitry Andric       if (std::error_code ec = llvm::sys::fs::openFileForWrite(
12704ba319b5SDimitry Andric               log_file, FD, llvm::sys::fs::CD_CreateAlways, flags)) {
1271f678e45dSDimitry Andric         error_stream << "Unable to open log file: " << ec.message();
1272f678e45dSDimitry Andric         return false;
1273f678e45dSDimitry Andric       }
1274f678e45dSDimitry Andric       log_stream_sp =
1275f678e45dSDimitry Andric           std::make_shared<llvm::raw_fd_ostream>(FD, should_close, unbuffered);
1276ac7ddfbfSEd Maste       m_log_streams[log_file] = log_stream_sp;
1277ac7ddfbfSEd Maste     }
1278ac7ddfbfSEd Maste   }
12794bb0738eSEd Maste   assert(log_stream_sp);
1280ac7ddfbfSEd Maste 
1281ac7ddfbfSEd Maste   if (log_options == 0)
1282435933ddSDimitry Andric     log_options =
1283435933ddSDimitry Andric         LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
1284ac7ddfbfSEd Maste 
1285435933ddSDimitry Andric   return Log::EnableLogChannel(log_stream_sp, log_options, channel, categories,
1286435933ddSDimitry Andric                                error_stream);
1287ac7ddfbfSEd Maste }
1288ac7ddfbfSEd Maste 
GetSourceManager()1289435933ddSDimitry Andric SourceManager &Debugger::GetSourceManager() {
12904bb0738eSEd Maste   if (!m_source_manager_ap)
1291f678e45dSDimitry Andric     m_source_manager_ap = llvm::make_unique<SourceManager>(shared_from_this());
1292ac7ddfbfSEd Maste   return *m_source_manager_ap;
1293ac7ddfbfSEd Maste }
1294ac7ddfbfSEd Maste 
129512b93ac6SEd Maste // This function handles events that were broadcast by the process.
HandleBreakpointEvent(const EventSP & event_sp)1296435933ddSDimitry Andric void Debugger::HandleBreakpointEvent(const EventSP &event_sp) {
129712b93ac6SEd Maste   using namespace lldb;
1298435933ddSDimitry Andric   const uint32_t event_type =
1299435933ddSDimitry Andric       Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent(
1300435933ddSDimitry Andric           event_sp);
130112b93ac6SEd Maste 
130212b93ac6SEd Maste   //    if (event_type & eBreakpointEventTypeAdded
130312b93ac6SEd Maste   //        || event_type & eBreakpointEventTypeRemoved
130412b93ac6SEd Maste   //        || event_type & eBreakpointEventTypeEnabled
130512b93ac6SEd Maste   //        || event_type & eBreakpointEventTypeDisabled
130612b93ac6SEd Maste   //        || event_type & eBreakpointEventTypeCommandChanged
130712b93ac6SEd Maste   //        || event_type & eBreakpointEventTypeConditionChanged
130812b93ac6SEd Maste   //        || event_type & eBreakpointEventTypeIgnoreChanged
130912b93ac6SEd Maste   //        || event_type & eBreakpointEventTypeLocationsResolved)
131012b93ac6SEd Maste   //    {
1311435933ddSDimitry Andric   //        // Don't do anything about these events, since the breakpoint
1312435933ddSDimitry Andric   //        commands already echo these actions.
131312b93ac6SEd Maste   //    }
131412b93ac6SEd Maste   //
1315435933ddSDimitry Andric   if (event_type & eBreakpointEventTypeLocationsAdded) {
1316435933ddSDimitry Andric     uint32_t num_new_locations =
1317435933ddSDimitry Andric         Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(
1318435933ddSDimitry Andric             event_sp);
1319435933ddSDimitry Andric     if (num_new_locations > 0) {
1320435933ddSDimitry Andric       BreakpointSP breakpoint =
1321435933ddSDimitry Andric           Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp);
13221c3bbb01SEd Maste       StreamSP output_sp(GetAsyncOutputStream());
1323435933ddSDimitry Andric       if (output_sp) {
132412b93ac6SEd Maste         output_sp->Printf("%d location%s added to breakpoint %d\n",
1325435933ddSDimitry Andric                           num_new_locations, num_new_locations == 1 ? "" : "s",
132612b93ac6SEd Maste                           breakpoint->GetID());
13271c3bbb01SEd Maste         output_sp->Flush();
132812b93ac6SEd Maste       }
132912b93ac6SEd Maste     }
133012b93ac6SEd Maste   }
133112b93ac6SEd Maste   //    else if (event_type & eBreakpointEventTypeLocationsRemoved)
133212b93ac6SEd Maste   //    {
1333435933ddSDimitry Andric   //        // These locations just get disabled, not sure it is worth spamming
1334435933ddSDimitry Andric   //        folks about this on the command line.
133512b93ac6SEd Maste   //    }
133612b93ac6SEd Maste   //    else if (event_type & eBreakpointEventTypeLocationsResolved)
133712b93ac6SEd Maste   //    {
1338435933ddSDimitry Andric   //        // This might be an interesting thing to note, but I'm going to
1339435933ddSDimitry Andric   //        leave it quiet for now, it just looked noisy.
134012b93ac6SEd Maste   //    }
134112b93ac6SEd Maste }
134212b93ac6SEd Maste 
GetProcessSTDOUT(Process * process,Stream * stream)1343435933ddSDimitry Andric size_t Debugger::GetProcessSTDOUT(Process *process, Stream *stream) {
134412b93ac6SEd Maste   size_t total_bytes = 0;
13454bb0738eSEd Maste   if (stream == nullptr)
134612b93ac6SEd Maste     stream = GetOutputFile().get();
134712b93ac6SEd Maste 
1348435933ddSDimitry Andric   if (stream) {
1349435933ddSDimitry Andric     //  The process has stuff waiting for stdout; get it and write it out to the
1350435933ddSDimitry Andric     //  appropriate place.
1351435933ddSDimitry Andric     if (process == nullptr) {
135212b93ac6SEd Maste       TargetSP target_sp = GetTargetList().GetSelectedTarget();
135312b93ac6SEd Maste       if (target_sp)
135412b93ac6SEd Maste         process = target_sp->GetProcessSP().get();
135512b93ac6SEd Maste     }
1356435933ddSDimitry Andric     if (process) {
13575517e702SDimitry Andric       Status error;
135812b93ac6SEd Maste       size_t len;
135912b93ac6SEd Maste       char stdio_buffer[1024];
1360435933ddSDimitry Andric       while ((len = process->GetSTDOUT(stdio_buffer, sizeof(stdio_buffer),
1361435933ddSDimitry Andric                                        error)) > 0) {
136212b93ac6SEd Maste         stream->Write(stdio_buffer, len);
136312b93ac6SEd Maste         total_bytes += len;
136412b93ac6SEd Maste       }
136512b93ac6SEd Maste     }
136612b93ac6SEd Maste     stream->Flush();
136712b93ac6SEd Maste   }
136812b93ac6SEd Maste   return total_bytes;
136912b93ac6SEd Maste }
137012b93ac6SEd Maste 
GetProcessSTDERR(Process * process,Stream * stream)1371435933ddSDimitry Andric size_t Debugger::GetProcessSTDERR(Process *process, Stream *stream) {
137212b93ac6SEd Maste   size_t total_bytes = 0;
13734bb0738eSEd Maste   if (stream == nullptr)
137412b93ac6SEd Maste     stream = GetOutputFile().get();
137512b93ac6SEd Maste 
1376435933ddSDimitry Andric   if (stream) {
1377435933ddSDimitry Andric     //  The process has stuff waiting for stderr; get it and write it out to the
1378435933ddSDimitry Andric     //  appropriate place.
1379435933ddSDimitry Andric     if (process == nullptr) {
138012b93ac6SEd Maste       TargetSP target_sp = GetTargetList().GetSelectedTarget();
138112b93ac6SEd Maste       if (target_sp)
138212b93ac6SEd Maste         process = target_sp->GetProcessSP().get();
138312b93ac6SEd Maste     }
1384435933ddSDimitry Andric     if (process) {
13855517e702SDimitry Andric       Status error;
138612b93ac6SEd Maste       size_t len;
138712b93ac6SEd Maste       char stdio_buffer[1024];
1388435933ddSDimitry Andric       while ((len = process->GetSTDERR(stdio_buffer, sizeof(stdio_buffer),
1389435933ddSDimitry Andric                                        error)) > 0) {
139012b93ac6SEd Maste         stream->Write(stdio_buffer, len);
139112b93ac6SEd Maste         total_bytes += len;
139212b93ac6SEd Maste       }
139312b93ac6SEd Maste     }
139412b93ac6SEd Maste     stream->Flush();
139512b93ac6SEd Maste   }
139612b93ac6SEd Maste   return total_bytes;
139712b93ac6SEd Maste }
139812b93ac6SEd Maste 
139912b93ac6SEd Maste // This function handles events that were broadcast by the process.
HandleProcessEvent(const EventSP & event_sp)1400435933ddSDimitry Andric void Debugger::HandleProcessEvent(const EventSP &event_sp) {
140112b93ac6SEd Maste   using namespace lldb;
140212b93ac6SEd Maste   const uint32_t event_type = event_sp->GetType();
1403435933ddSDimitry Andric   ProcessSP process_sp =
1404435933ddSDimitry Andric       (event_type == Process::eBroadcastBitStructuredData)
1405435933ddSDimitry Andric           ? EventDataStructuredData::GetProcessFromEvent(event_sp.get())
1406435933ddSDimitry Andric           : Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
140712b93ac6SEd Maste 
14081c3bbb01SEd Maste   StreamSP output_stream_sp = GetAsyncOutputStream();
14091c3bbb01SEd Maste   StreamSP error_stream_sp = GetAsyncErrorStream();
141012b93ac6SEd Maste   const bool gui_enabled = IsForwardingEvents();
141112b93ac6SEd Maste 
1412435933ddSDimitry Andric   if (!gui_enabled) {
14130127ef0fSEd Maste     bool pop_process_io_handler = false;
141412b93ac6SEd Maste     assert(process_sp);
141512b93ac6SEd Maste 
14161c3bbb01SEd Maste     bool state_is_stopped = false;
1417435933ddSDimitry Andric     const bool got_state_changed =
1418435933ddSDimitry Andric         (event_type & Process::eBroadcastBitStateChanged) != 0;
14191c3bbb01SEd Maste     const bool got_stdout = (event_type & Process::eBroadcastBitSTDOUT) != 0;
14201c3bbb01SEd Maste     const bool got_stderr = (event_type & Process::eBroadcastBitSTDERR) != 0;
1421435933ddSDimitry Andric     const bool got_structured_data =
1422435933ddSDimitry Andric         (event_type & Process::eBroadcastBitStructuredData) != 0;
1423435933ddSDimitry Andric 
1424435933ddSDimitry Andric     if (got_state_changed) {
1425435933ddSDimitry Andric       StateType event_state =
1426435933ddSDimitry Andric           Process::ProcessEventData::GetStateFromEvent(event_sp.get());
14271c3bbb01SEd Maste       state_is_stopped = StateIsStoppedState(event_state, false);
142812b93ac6SEd Maste     }
14290127ef0fSEd Maste 
14301c3bbb01SEd Maste     // Display running state changes first before any STDIO
1431435933ddSDimitry Andric     if (got_state_changed && !state_is_stopped) {
1432435933ddSDimitry Andric       Process::HandleProcessStateChangedEvent(event_sp, output_stream_sp.get(),
1433435933ddSDimitry Andric                                               pop_process_io_handler);
143412b93ac6SEd Maste     }
14350127ef0fSEd Maste 
14361c3bbb01SEd Maste     // Now display and STDOUT
1437435933ddSDimitry Andric     if (got_stdout || got_state_changed) {
14381c3bbb01SEd Maste       GetProcessSTDOUT(process_sp.get(), output_stream_sp.get());
143912b93ac6SEd Maste     }
14400127ef0fSEd Maste 
14411c3bbb01SEd Maste     // Now display and STDERR
1442435933ddSDimitry Andric     if (got_stderr || got_state_changed) {
14431c3bbb01SEd Maste       GetProcessSTDERR(process_sp.get(), error_stream_sp.get());
14440127ef0fSEd Maste     }
14450127ef0fSEd Maste 
1446435933ddSDimitry Andric     // Give structured data events an opportunity to display.
1447435933ddSDimitry Andric     if (got_structured_data) {
1448435933ddSDimitry Andric       StructuredDataPluginSP plugin_sp =
1449435933ddSDimitry Andric           EventDataStructuredData::GetPluginFromEvent(event_sp.get());
1450435933ddSDimitry Andric       if (plugin_sp) {
1451435933ddSDimitry Andric         auto structured_data_sp =
1452435933ddSDimitry Andric             EventDataStructuredData::GetObjectFromEvent(event_sp.get());
1453435933ddSDimitry Andric         if (output_stream_sp) {
1454435933ddSDimitry Andric           StreamString content_stream;
14555517e702SDimitry Andric           Status error =
1456435933ddSDimitry Andric               plugin_sp->GetDescription(structured_data_sp, content_stream);
1457435933ddSDimitry Andric           if (error.Success()) {
1458435933ddSDimitry Andric             if (!content_stream.GetString().empty()) {
1459435933ddSDimitry Andric               // Add newline.
1460435933ddSDimitry Andric               content_stream.PutChar('\n');
1461435933ddSDimitry Andric               content_stream.Flush();
1462435933ddSDimitry Andric 
1463435933ddSDimitry Andric               // Print it.
1464435933ddSDimitry Andric               output_stream_sp->PutCString(content_stream.GetString());
1465435933ddSDimitry Andric             }
1466435933ddSDimitry Andric           } else {
1467435933ddSDimitry Andric             error_stream_sp->Printf("Failed to print structured "
1468435933ddSDimitry Andric                                     "data with plugin %s: %s",
1469435933ddSDimitry Andric                                     plugin_sp->GetPluginName().AsCString(),
1470435933ddSDimitry Andric                                     error.AsCString());
1471435933ddSDimitry Andric           }
1472435933ddSDimitry Andric         }
1473435933ddSDimitry Andric       }
1474435933ddSDimitry Andric     }
1475435933ddSDimitry Andric 
14761c3bbb01SEd Maste     // Now display any stopped state changes after any STDIO
1477435933ddSDimitry Andric     if (got_state_changed && state_is_stopped) {
1478435933ddSDimitry Andric       Process::HandleProcessStateChangedEvent(event_sp, output_stream_sp.get(),
1479435933ddSDimitry Andric                                               pop_process_io_handler);
148012b93ac6SEd Maste     }
148112b93ac6SEd Maste 
14821c3bbb01SEd Maste     output_stream_sp->Flush();
14831c3bbb01SEd Maste     error_stream_sp->Flush();
148412b93ac6SEd Maste 
14850127ef0fSEd Maste     if (pop_process_io_handler)
14860127ef0fSEd Maste       process_sp->PopProcessIOHandler();
14870127ef0fSEd Maste   }
14880127ef0fSEd Maste }
14890127ef0fSEd Maste 
HandleThreadEvent(const EventSP & event_sp)1490435933ddSDimitry Andric void Debugger::HandleThreadEvent(const EventSP &event_sp) {
14914ba319b5SDimitry Andric   // At present the only thread event we handle is the Frame Changed event, and
14924ba319b5SDimitry Andric   // all we do for that is just reprint the thread status for that thread.
149312b93ac6SEd Maste   using namespace lldb;
149412b93ac6SEd Maste   const uint32_t event_type = event_sp->GetType();
1495435933ddSDimitry Andric   const bool stop_format = true;
149612b93ac6SEd Maste   if (event_type == Thread::eBroadcastBitStackChanged ||
1497435933ddSDimitry Andric       event_type == Thread::eBroadcastBitThreadSelected) {
1498435933ddSDimitry Andric     ThreadSP thread_sp(
1499435933ddSDimitry Andric         Thread::ThreadEventData::GetThreadFromEvent(event_sp.get()));
1500435933ddSDimitry Andric     if (thread_sp) {
1501435933ddSDimitry Andric       thread_sp->GetStatus(*GetAsyncOutputStream(), 0, 1, 1, stop_format);
150212b93ac6SEd Maste     }
150312b93ac6SEd Maste   }
150412b93ac6SEd Maste }
150512b93ac6SEd Maste 
IsForwardingEvents()1506435933ddSDimitry Andric bool Debugger::IsForwardingEvents() { return (bool)m_forward_listener_sp; }
150712b93ac6SEd Maste 
EnableForwardEvents(const ListenerSP & listener_sp)1508435933ddSDimitry Andric void Debugger::EnableForwardEvents(const ListenerSP &listener_sp) {
150912b93ac6SEd Maste   m_forward_listener_sp = listener_sp;
151012b93ac6SEd Maste }
151112b93ac6SEd Maste 
CancelForwardEvents(const ListenerSP & listener_sp)1512435933ddSDimitry Andric void Debugger::CancelForwardEvents(const ListenerSP &listener_sp) {
151312b93ac6SEd Maste   m_forward_listener_sp.reset();
151412b93ac6SEd Maste }
151512b93ac6SEd Maste 
DefaultEventHandler()1516435933ddSDimitry Andric void Debugger::DefaultEventHandler() {
15174bb0738eSEd Maste   ListenerSP listener_sp(GetListener());
151812b93ac6SEd Maste   ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
151912b93ac6SEd Maste   ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
152012b93ac6SEd Maste   ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
152112b93ac6SEd Maste   BroadcastEventSpec target_event_spec(broadcaster_class_target,
152212b93ac6SEd Maste                                        Target::eBroadcastBitBreakpointChanged);
152312b93ac6SEd Maste 
1524435933ddSDimitry Andric   BroadcastEventSpec process_event_spec(
1525435933ddSDimitry Andric       broadcaster_class_process,
1526435933ddSDimitry Andric       Process::eBroadcastBitStateChanged | Process::eBroadcastBitSTDOUT |
1527435933ddSDimitry Andric           Process::eBroadcastBitSTDERR | Process::eBroadcastBitStructuredData);
152812b93ac6SEd Maste 
152912b93ac6SEd Maste   BroadcastEventSpec thread_event_spec(broadcaster_class_thread,
153012b93ac6SEd Maste                                        Thread::eBroadcastBitStackChanged |
153112b93ac6SEd Maste                                            Thread::eBroadcastBitThreadSelected);
153212b93ac6SEd Maste 
1533435933ddSDimitry Andric   listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp,
1534435933ddSDimitry Andric                                           target_event_spec);
1535435933ddSDimitry Andric   listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp,
1536435933ddSDimitry Andric                                           process_event_spec);
1537435933ddSDimitry Andric   listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp,
1538435933ddSDimitry Andric                                           thread_event_spec);
1539435933ddSDimitry Andric   listener_sp->StartListeningForEvents(
1540435933ddSDimitry Andric       m_command_interpreter_ap.get(),
154112b93ac6SEd Maste       CommandInterpreter::eBroadcastBitQuitCommandReceived |
154212b93ac6SEd Maste           CommandInterpreter::eBroadcastBitAsynchronousOutputData |
154312b93ac6SEd Maste           CommandInterpreter::eBroadcastBitAsynchronousErrorData);
154412b93ac6SEd Maste 
15454ba319b5SDimitry Andric   // Let the thread that spawned us know that we have started up and that we
15464ba319b5SDimitry Andric   // are now listening to all required events so no events get missed
15477aa51b79SEd Maste   m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening);
15487aa51b79SEd Maste 
154912b93ac6SEd Maste   bool done = false;
1550435933ddSDimitry Andric   while (!done) {
155112b93ac6SEd Maste     EventSP event_sp;
1552435933ddSDimitry Andric     if (listener_sp->GetEvent(event_sp, llvm::None)) {
1553435933ddSDimitry Andric       if (event_sp) {
155412b93ac6SEd Maste         Broadcaster *broadcaster = event_sp->GetBroadcaster();
1555435933ddSDimitry Andric         if (broadcaster) {
155612b93ac6SEd Maste           uint32_t event_type = event_sp->GetType();
155712b93ac6SEd Maste           ConstString broadcaster_class(broadcaster->GetBroadcasterClass());
1558435933ddSDimitry Andric           if (broadcaster_class == broadcaster_class_process) {
155912b93ac6SEd Maste             HandleProcessEvent(event_sp);
1560435933ddSDimitry Andric           } else if (broadcaster_class == broadcaster_class_target) {
1561435933ddSDimitry Andric             if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(
1562435933ddSDimitry Andric                     event_sp.get())) {
156312b93ac6SEd Maste               HandleBreakpointEvent(event_sp);
156412b93ac6SEd Maste             }
1565435933ddSDimitry Andric           } else if (broadcaster_class == broadcaster_class_thread) {
156612b93ac6SEd Maste             HandleThreadEvent(event_sp);
1567435933ddSDimitry Andric           } else if (broadcaster == m_command_interpreter_ap.get()) {
1568435933ddSDimitry Andric             if (event_type &
1569435933ddSDimitry Andric                 CommandInterpreter::eBroadcastBitQuitCommandReceived) {
157012b93ac6SEd Maste               done = true;
1571435933ddSDimitry Andric             } else if (event_type &
1572435933ddSDimitry Andric                        CommandInterpreter::eBroadcastBitAsynchronousErrorData) {
1573435933ddSDimitry Andric               const char *data = reinterpret_cast<const char *>(
1574435933ddSDimitry Andric                   EventDataBytes::GetBytesFromEvent(event_sp.get()));
1575435933ddSDimitry Andric               if (data && data[0]) {
15761c3bbb01SEd Maste                 StreamSP error_sp(GetAsyncErrorStream());
1577435933ddSDimitry Andric                 if (error_sp) {
157812b93ac6SEd Maste                   error_sp->PutCString(data);
157912b93ac6SEd Maste                   error_sp->Flush();
158012b93ac6SEd Maste                 }
158112b93ac6SEd Maste               }
1582435933ddSDimitry Andric             } else if (event_type & CommandInterpreter::
1583435933ddSDimitry Andric                                         eBroadcastBitAsynchronousOutputData) {
1584435933ddSDimitry Andric               const char *data = reinterpret_cast<const char *>(
1585435933ddSDimitry Andric                   EventDataBytes::GetBytesFromEvent(event_sp.get()));
1586435933ddSDimitry Andric               if (data && data[0]) {
15871c3bbb01SEd Maste                 StreamSP output_sp(GetAsyncOutputStream());
1588435933ddSDimitry Andric                 if (output_sp) {
158912b93ac6SEd Maste                   output_sp->PutCString(data);
159012b93ac6SEd Maste                   output_sp->Flush();
159112b93ac6SEd Maste                 }
159212b93ac6SEd Maste               }
159312b93ac6SEd Maste             }
159412b93ac6SEd Maste           }
159512b93ac6SEd Maste         }
159612b93ac6SEd Maste 
159712b93ac6SEd Maste         if (m_forward_listener_sp)
159812b93ac6SEd Maste           m_forward_listener_sp->AddEvent(event_sp);
159912b93ac6SEd Maste       }
160012b93ac6SEd Maste     }
160112b93ac6SEd Maste   }
160212b93ac6SEd Maste }
160312b93ac6SEd Maste 
EventHandlerThread(lldb::thread_arg_t arg)1604435933ddSDimitry Andric lldb::thread_result_t Debugger::EventHandlerThread(lldb::thread_arg_t arg) {
160512b93ac6SEd Maste   ((Debugger *)arg)->DefaultEventHandler();
160612b93ac6SEd Maste   return NULL;
160712b93ac6SEd Maste }
160812b93ac6SEd Maste 
StartEventHandlerThread()1609435933ddSDimitry Andric bool Debugger::StartEventHandlerThread() {
1610435933ddSDimitry Andric   if (!m_event_handler_thread.IsJoinable()) {
16114ba319b5SDimitry Andric     // We must synchronize with the DefaultEventHandler() thread to ensure it
16124ba319b5SDimitry Andric     // is up and running and listening to events before we return from this
16134ba319b5SDimitry Andric     // function. We do this by listening to events for the
16147aa51b79SEd Maste     // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster
16154ba319b5SDimitry Andric     ConstString full_name("lldb.debugger.event-handler");
16164ba319b5SDimitry Andric     ListenerSP listener_sp(Listener::MakeListener(full_name.AsCString()));
1617435933ddSDimitry Andric     listener_sp->StartListeningForEvents(&m_sync_broadcaster,
1618435933ddSDimitry Andric                                          eBroadcastBitEventThreadIsListening);
16197aa51b79SEd Maste 
16204ba319b5SDimitry Andric     auto thread_name =
16214ba319b5SDimitry Andric         full_name.GetLength() < llvm::get_max_thread_name_length() ?
16224ba319b5SDimitry Andric         full_name.AsCString() : "dbg.evt-handler";
16237aa51b79SEd Maste 
16244ba319b5SDimitry Andric     // Use larger 8MB stack for this thread
16254ba319b5SDimitry Andric     m_event_handler_thread = ThreadLauncher::LaunchThread(thread_name,
16264ba319b5SDimitry Andric         EventHandlerThread, this, nullptr, g_debugger_event_thread_stack_bytes);
16274ba319b5SDimitry Andric 
16284ba319b5SDimitry Andric     // Make sure DefaultEventHandler() is running and listening to events
16294ba319b5SDimitry Andric     // before we return from this function. We are only listening for events of
16304ba319b5SDimitry Andric     // type eBroadcastBitEventThreadIsListening so we don't need to check the
16314ba319b5SDimitry Andric     // event, we just need to wait an infinite amount of time for it (nullptr
16324ba319b5SDimitry Andric     // timeout as the first parameter)
16337aa51b79SEd Maste     lldb::EventSP event_sp;
1634435933ddSDimitry Andric     listener_sp->GetEvent(event_sp, llvm::None);
16357aa51b79SEd Maste   }
16367aa51b79SEd Maste   return m_event_handler_thread.IsJoinable();
163712b93ac6SEd Maste }
163812b93ac6SEd Maste 
StopEventHandlerThread()1639435933ddSDimitry Andric void Debugger::StopEventHandlerThread() {
1640435933ddSDimitry Andric   if (m_event_handler_thread.IsJoinable()) {
1641435933ddSDimitry Andric     GetCommandInterpreter().BroadcastEvent(
1642435933ddSDimitry Andric         CommandInterpreter::eBroadcastBitQuitCommandReceived);
16437aa51b79SEd Maste     m_event_handler_thread.Join(nullptr);
164412b93ac6SEd Maste   }
164512b93ac6SEd Maste }
164612b93ac6SEd Maste 
IOHandlerThread(lldb::thread_arg_t arg)1647435933ddSDimitry Andric lldb::thread_result_t Debugger::IOHandlerThread(lldb::thread_arg_t arg) {
164812b93ac6SEd Maste   Debugger *debugger = (Debugger *)arg;
16491c3bbb01SEd Maste   debugger->ExecuteIOHandlers();
165012b93ac6SEd Maste   debugger->StopEventHandlerThread();
165112b93ac6SEd Maste   return NULL;
165212b93ac6SEd Maste }
165312b93ac6SEd Maste 
HasIOHandlerThread()1654435933ddSDimitry Andric bool Debugger::HasIOHandlerThread() { return m_io_handler_thread.IsJoinable(); }
16559f2f44ceSEd Maste 
StartIOHandlerThread()1656435933ddSDimitry Andric bool Debugger::StartIOHandlerThread() {
16577aa51b79SEd Maste   if (!m_io_handler_thread.IsJoinable())
1658435933ddSDimitry Andric     m_io_handler_thread = ThreadLauncher::LaunchThread(
1659435933ddSDimitry Andric         "lldb.debugger.io-handler", IOHandlerThread, this, nullptr,
16607aa51b79SEd Maste         8 * 1024 * 1024); // Use larger 8MB stack for this thread
16617aa51b79SEd Maste   return m_io_handler_thread.IsJoinable();
166212b93ac6SEd Maste }
166312b93ac6SEd Maste 
StopIOHandlerThread()1664435933ddSDimitry Andric void Debugger::StopIOHandlerThread() {
1665435933ddSDimitry Andric   if (m_io_handler_thread.IsJoinable()) {
166612b93ac6SEd Maste     if (m_input_file_sp)
166712b93ac6SEd Maste       m_input_file_sp->GetFile().Close();
16687aa51b79SEd Maste     m_io_handler_thread.Join(nullptr);
166912b93ac6SEd Maste   }
167012b93ac6SEd Maste }
167112b93ac6SEd Maste 
JoinIOHandlerThread()1672435933ddSDimitry Andric void Debugger::JoinIOHandlerThread() {
1673435933ddSDimitry Andric   if (HasIOHandlerThread()) {
16749f2f44ceSEd Maste     thread_result_t result;
16759f2f44ceSEd Maste     m_io_handler_thread.Join(&result);
16769f2f44ceSEd Maste     m_io_handler_thread = LLDB_INVALID_HOST_THREAD;
16779f2f44ceSEd Maste   }
16789f2f44ceSEd Maste }
16799f2f44ceSEd Maste 
GetDummyTarget()1680435933ddSDimitry Andric Target *Debugger::GetDummyTarget() {
16817aa51b79SEd Maste   return m_target_list.GetDummyTarget(*this).get();
16827aa51b79SEd Maste }
16837aa51b79SEd Maste 
GetSelectedOrDummyTarget(bool prefer_dummy)1684435933ddSDimitry Andric Target *Debugger::GetSelectedOrDummyTarget(bool prefer_dummy) {
16857aa51b79SEd Maste   Target *target = nullptr;
1686435933ddSDimitry Andric   if (!prefer_dummy) {
16877aa51b79SEd Maste     target = m_target_list.GetSelectedTarget().get();
16887aa51b79SEd Maste     if (target)
16897aa51b79SEd Maste       return target;
16907aa51b79SEd Maste   }
16917aa51b79SEd Maste 
16927aa51b79SEd Maste   return GetDummyTarget();
16937aa51b79SEd Maste }
169412b93ac6SEd Maste 
RunREPL(LanguageType language,const char * repl_options)16955517e702SDimitry Andric Status Debugger::RunREPL(LanguageType language, const char *repl_options) {
16965517e702SDimitry Andric   Status err;
16979f2f44ceSEd Maste   FileSpec repl_executable;
16989f2f44ceSEd Maste 
1699435933ddSDimitry Andric   if (language == eLanguageTypeUnknown) {
17009f2f44ceSEd Maste     std::set<LanguageType> repl_languages;
17019f2f44ceSEd Maste 
17029f2f44ceSEd Maste     Language::GetLanguagesSupportingREPLs(repl_languages);
17039f2f44ceSEd Maste 
1704435933ddSDimitry Andric     if (repl_languages.size() == 1) {
17059f2f44ceSEd Maste       language = *repl_languages.begin();
1706435933ddSDimitry Andric     } else if (repl_languages.empty()) {
1707435933ddSDimitry Andric       err.SetErrorStringWithFormat(
1708435933ddSDimitry Andric           "LLDB isn't configured with REPL support for any languages.");
17099f2f44ceSEd Maste       return err;
1710435933ddSDimitry Andric     } else {
1711435933ddSDimitry Andric       err.SetErrorStringWithFormat(
1712435933ddSDimitry Andric           "Multiple possible REPL languages.  Please specify a language.");
17139f2f44ceSEd Maste       return err;
17149f2f44ceSEd Maste     }
17159f2f44ceSEd Maste   }
17169f2f44ceSEd Maste 
1717435933ddSDimitry Andric   Target *const target =
1718435933ddSDimitry Andric       nullptr; // passing in an empty target means the REPL must create one
17199f2f44ceSEd Maste 
17209f2f44ceSEd Maste   REPLSP repl_sp(REPL::Create(err, language, this, target, repl_options));
17219f2f44ceSEd Maste 
1722435933ddSDimitry Andric   if (!err.Success()) {
17239f2f44ceSEd Maste     return err;
17249f2f44ceSEd Maste   }
17259f2f44ceSEd Maste 
1726435933ddSDimitry Andric   if (!repl_sp) {
1727435933ddSDimitry Andric     err.SetErrorStringWithFormat("couldn't find a REPL for %s",
1728435933ddSDimitry Andric                                  Language::GetNameForLanguageType(language));
17299f2f44ceSEd Maste     return err;
17309f2f44ceSEd Maste   }
17319f2f44ceSEd Maste 
17329f2f44ceSEd Maste   repl_sp->SetCompilerOptions(repl_options);
17339f2f44ceSEd Maste   repl_sp->RunLoop();
17349f2f44ceSEd Maste 
17359f2f44ceSEd Maste   return err;
17369f2f44ceSEd Maste }
1737