180814287SRaphael Isemann //===-- Debugger.cpp ------------------------------------------------------===// 230fdc8d8SChris Lattner // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 630fdc8d8SChris Lattner // 730fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 830fdc8d8SChris Lattner 94a33d318SGreg Clayton #include "lldb/Core/Debugger.h" 104a33d318SGreg Clayton 11672d2c12SJonas Devlieghere #include "lldb/Breakpoint/Breakpoint.h" 12554f68d3SGreg Clayton #include "lldb/Core/FormatEntity.h" 13672d2c12SJonas Devlieghere #include "lldb/Core/Mangled.h" 14672d2c12SJonas Devlieghere #include "lldb/Core/ModuleList.h" 15e8cd0c98SGreg Clayton #include "lldb/Core/PluginManager.h" 165b52f0c7SJim Ingham #include "lldb/Core/StreamAsynchronousIO.h" 1744d93782SGreg Clayton #include "lldb/Core/StreamFile.h" 185548cb50SEnrico Granata #include "lldb/DataFormatters/DataVisualization.h" 193e7e915dSSean Callanan #include "lldb/Expression/REPL.h" 20672d2c12SJonas Devlieghere #include "lldb/Host/File.h" 2135e4c84cSJonas Devlieghere #include "lldb/Host/FileSystem.h" 2242ff0ad8SZachary Turner #include "lldb/Host/HostInfo.h" 23a3406614SGreg Clayton #include "lldb/Host/Terminal.h" 2439de3110SZachary Turner #include "lldb/Host/ThreadLauncher.h" 256611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 26672d2c12SJonas Devlieghere #include "lldb/Interpreter/OptionValue.h" 27633a29cfSZachary Turner #include "lldb/Interpreter/OptionValueProperties.h" 2867cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueSInt64.h" 2967cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueString.h" 30672d2c12SJonas Devlieghere #include "lldb/Interpreter/Property.h" 31672d2c12SJonas Devlieghere #include "lldb/Interpreter/ScriptInterpreter.h" 321f746071SGreg Clayton #include "lldb/Symbol/Function.h" 331f746071SGreg Clayton #include "lldb/Symbol/Symbol.h" 34672d2c12SJonas Devlieghere #include "lldb/Symbol/SymbolContext.h" 353e7e915dSSean Callanan #include "lldb/Target/Language.h" 3630fdc8d8SChris Lattner #include "lldb/Target/Process.h" 3775930019STodd Fiala #include "lldb/Target/StructuredDataPlugin.h" 3884a53dfbSEnrico Granata #include "lldb/Target/Target.h" 39b9c1b51eSKate Stone #include "lldb/Target/TargetList.h" 4030fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 41672d2c12SJonas Devlieghere #include "lldb/Target/ThreadList.h" 425a31471eSGreg Clayton #include "lldb/Utility/AnsiTerminal.h" 43181b823bSPavel Labath #include "lldb/Utility/Event.h" 44181b823bSPavel Labath #include "lldb/Utility/Listener.h" 45672d2c12SJonas Devlieghere #include "lldb/Utility/Log.h" 469e046f02SJonas Devlieghere #include "lldb/Utility/Reproducer.h" 47d821c997SPavel Labath #include "lldb/Utility/State.h" 48672d2c12SJonas Devlieghere #include "lldb/Utility/Stream.h" 49fb1a0a0dSZachary Turner #include "lldb/Utility/StreamCallback.h" 50bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h" 512f3df613SZachary Turner 52b1cb0b79SNico Weber #if defined(_WIN32) 53672d2c12SJonas Devlieghere #include "lldb/Host/windows/PosixApi.h" 548aa23614SDavid Bolvansky #include "lldb/Host/windows/windows.h" 552f3df613SZachary Turner #endif 562f3df613SZachary Turner 57672d2c12SJonas Devlieghere #include "llvm/ADT/None.h" 58672d2c12SJonas Devlieghere #include "llvm/ADT/STLExtras.h" 592f3df613SZachary Turner #include "llvm/ADT/StringRef.h" 60672d2c12SJonas Devlieghere #include "llvm/ADT/iterator.h" 612f3df613SZachary Turner #include "llvm/Support/DynamicLibrary.h" 622f3df613SZachary Turner #include "llvm/Support/FileSystem.h" 638aa23614SDavid Bolvansky #include "llvm/Support/Process.h" 642f3df613SZachary Turner #include "llvm/Support/Threading.h" 65672d2c12SJonas Devlieghere #include "llvm/Support/raw_ostream.h" 662f3df613SZachary Turner 67672d2c12SJonas Devlieghere #include <list> 68672d2c12SJonas Devlieghere #include <memory> 692f3df613SZachary Turner #include <mutex> 70672d2c12SJonas Devlieghere #include <set> 71672d2c12SJonas Devlieghere #include <stdio.h> 72672d2c12SJonas Devlieghere #include <stdlib.h> 73672d2c12SJonas Devlieghere #include <string.h> 74672d2c12SJonas Devlieghere #include <string> 75672d2c12SJonas Devlieghere #include <system_error> 762f3df613SZachary Turner 772f3df613SZachary Turner namespace lldb_private { 782f3df613SZachary Turner class Address; 792f3df613SZachary Turner } 8030fdc8d8SChris Lattner 8130fdc8d8SChris Lattner using namespace lldb; 8230fdc8d8SChris Lattner using namespace lldb_private; 8330fdc8d8SChris Lattner 84ebc1bb27SCaroline Tice static lldb::user_id_t g_unique_id = 1; 857c2896a2SZachary Turner static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024; 86ebc1bb27SCaroline Tice 871b654882SGreg Clayton #pragma mark Static Functions 881b654882SGreg Clayton 891b654882SGreg Clayton typedef std::vector<DebuggerSP> DebuggerList; 90b9c1b51eSKate Stone static std::recursive_mutex *g_debugger_list_mutex_ptr = 91b9c1b51eSKate Stone nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain 92b9c1b51eSKate Stone static DebuggerList *g_debugger_list_ptr = 93b9c1b51eSKate Stone nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain 94e372b98dSGreg Clayton 958fe53c49STatyana Krasnukha static constexpr OptionEnumValueElement g_show_disassembly_enum_values[] = { 96e063ecccSJonas Devlieghere { 97e063ecccSJonas Devlieghere Debugger::eStopDisassemblyTypeNever, 98e063ecccSJonas Devlieghere "never", 99e063ecccSJonas Devlieghere "Never show disassembly when displaying a stop context.", 100e063ecccSJonas Devlieghere }, 101e063ecccSJonas Devlieghere { 102e063ecccSJonas Devlieghere Debugger::eStopDisassemblyTypeNoDebugInfo, 103e063ecccSJonas Devlieghere "no-debuginfo", 104e063ecccSJonas Devlieghere "Show disassembly when there is no debug information.", 105e063ecccSJonas Devlieghere }, 106e063ecccSJonas Devlieghere { 107e063ecccSJonas Devlieghere Debugger::eStopDisassemblyTypeNoSource, 108e063ecccSJonas Devlieghere "no-source", 109e063ecccSJonas Devlieghere "Show disassembly when there is no source information, or the source " 110e063ecccSJonas Devlieghere "file " 111e063ecccSJonas Devlieghere "is missing when displaying a stop context.", 112e063ecccSJonas Devlieghere }, 113e063ecccSJonas Devlieghere { 114e063ecccSJonas Devlieghere Debugger::eStopDisassemblyTypeAlways, 115e063ecccSJonas Devlieghere "always", 116e063ecccSJonas Devlieghere "Always show disassembly when displaying a stop context.", 117e063ecccSJonas Devlieghere }, 118e063ecccSJonas Devlieghere }; 119e372b98dSGreg Clayton 1208fe53c49STatyana Krasnukha static constexpr OptionEnumValueElement g_language_enumerators[] = { 121e063ecccSJonas Devlieghere { 122e063ecccSJonas Devlieghere eScriptLanguageNone, 123e063ecccSJonas Devlieghere "none", 124e063ecccSJonas Devlieghere "Disable scripting languages.", 125e063ecccSJonas Devlieghere }, 126e063ecccSJonas Devlieghere { 127e063ecccSJonas Devlieghere eScriptLanguagePython, 128e063ecccSJonas Devlieghere "python", 129e063ecccSJonas Devlieghere "Select python as the default scripting language.", 130e063ecccSJonas Devlieghere }, 131e063ecccSJonas Devlieghere { 132e063ecccSJonas Devlieghere eScriptLanguageDefault, 133e063ecccSJonas Devlieghere "default", 134e063ecccSJonas Devlieghere "Select the lldb default as the default scripting language.", 135e063ecccSJonas Devlieghere }, 136e063ecccSJonas Devlieghere }; 137e372b98dSGreg Clayton 1388fe53c49STatyana Krasnukha static constexpr OptionEnumValueElement s_stop_show_column_values[] = { 139e063ecccSJonas Devlieghere { 140e063ecccSJonas Devlieghere eStopShowColumnAnsiOrCaret, 141e063ecccSJonas Devlieghere "ansi-or-caret", 142e063ecccSJonas Devlieghere "Highlight the stop column with ANSI terminal codes when color/ANSI " 143e063ecccSJonas Devlieghere "mode is enabled; otherwise, fall back to using a text-only caret (^) " 144e063ecccSJonas Devlieghere "as if \"caret-only\" mode was selected.", 145e063ecccSJonas Devlieghere }, 146e063ecccSJonas Devlieghere { 147e063ecccSJonas Devlieghere eStopShowColumnAnsi, 148e063ecccSJonas Devlieghere "ansi", 149e063ecccSJonas Devlieghere "Highlight the stop column with ANSI terminal codes when running LLDB " 150e063ecccSJonas Devlieghere "with color/ANSI enabled.", 151e063ecccSJonas Devlieghere }, 152e063ecccSJonas Devlieghere { 153e063ecccSJonas Devlieghere eStopShowColumnCaret, 154e063ecccSJonas Devlieghere "caret", 155e063ecccSJonas Devlieghere "Highlight the stop column with a caret character (^) underneath the " 156e063ecccSJonas Devlieghere "stop column. This method introduces a new line in source listings " 157e063ecccSJonas Devlieghere "that display thread stop locations.", 158e063ecccSJonas Devlieghere }, 159e063ecccSJonas Devlieghere { 160e063ecccSJonas Devlieghere eStopShowColumnNone, 161e063ecccSJonas Devlieghere "none", 162e063ecccSJonas Devlieghere "Do not highlight the stop column.", 163e063ecccSJonas Devlieghere }, 164e063ecccSJonas Devlieghere }; 1659666ba75STodd Fiala 166971f9ca6SJonas Devlieghere #define LLDB_PROPERTIES_debugger 1676a253d37SJordan Rupprecht #include "CoreProperties.inc" 16867cc0636SGreg Clayton 169b9c1b51eSKate Stone enum { 170971f9ca6SJonas Devlieghere #define LLDB_PROPERTIES_debugger 1716a253d37SJordan Rupprecht #include "CorePropertiesEnum.inc" 17267cc0636SGreg Clayton }; 17367cc0636SGreg Clayton 174df370550SEugene Zelenko LoadPluginCallbackType Debugger::g_load_plugin_callback = nullptr; 1754c05410fSGreg Clayton 17697206d57SZachary Turner Status Debugger::SetPropertyValue(const ExecutionContext *exe_ctx, 1774c05410fSGreg Clayton VarSetOperationType op, 17897206d57SZachary Turner llvm::StringRef property_path, 17997206d57SZachary Turner llvm::StringRef value) { 180e063ecccSJonas Devlieghere bool is_load_script = 181e063ecccSJonas Devlieghere (property_path == "target.load-script-from-symbol-file"); 182e5814d78SRaphael Isemann // These properties might change how we visualize data. 183e5814d78SRaphael Isemann bool invalidate_data_vis = (property_path == "escape-non-printables"); 184e5814d78SRaphael Isemann invalidate_data_vis |= 185e5814d78SRaphael Isemann (property_path == "target.max-zero-padding-in-float-format"); 186e5814d78SRaphael Isemann if (invalidate_data_vis) { 187e5814d78SRaphael Isemann DataVisualization::ForceUpdate(); 188e5814d78SRaphael Isemann } 189e5814d78SRaphael Isemann 19084a53dfbSEnrico Granata TargetSP target_sp; 191397ddd5fSEnrico Granata LoadScriptFromSymFile load_script_old_value; 192b9c1b51eSKate Stone if (is_load_script && exe_ctx->GetTargetSP()) { 19384a53dfbSEnrico Granata target_sp = exe_ctx->GetTargetSP(); 194b9c1b51eSKate Stone load_script_old_value = 195b9c1b51eSKate Stone target_sp->TargetProperties::GetLoadScriptFromSymbolFile(); 19684a53dfbSEnrico Granata } 19797206d57SZachary Turner Status error(Properties::SetPropertyValue(exe_ctx, op, property_path, value)); 198b9c1b51eSKate Stone if (error.Success()) { 19984a53dfbSEnrico Granata // FIXME it would be nice to have "on-change" callbacks for properties 200a8ea5955SJonas Devlieghere if (property_path == g_debugger_properties[ePropertyPrompt].name) { 201514d8cd8SZachary Turner llvm::StringRef new_prompt = GetPrompt(); 2024b3c0fd5SJonas Devlieghere std::string str = lldb_private::ansi::FormatAnsiTerminalCodes( 203b9c1b51eSKate Stone new_prompt, GetUseColor()); 204c3ce7f27SMichael Sartain if (str.length()) 205771ef6d4SMalcolm Parsons new_prompt = str; 20644d93782SGreg Clayton GetCommandInterpreter().UpdatePrompt(new_prompt); 207a8f3ae7cSJonas Devlieghere auto bytes = std::make_unique<EventDataBytes>(new_prompt); 2082f3df613SZachary Turner auto prompt_change_event_sp = std::make_shared<Event>( 2092f3df613SZachary Turner CommandInterpreter::eBroadcastBitResetPrompt, bytes.release()); 2104c05410fSGreg Clayton GetCommandInterpreter().BroadcastEvent(prompt_change_event_sp); 211a8ea5955SJonas Devlieghere } else if (property_path == g_debugger_properties[ePropertyUseColor].name) { 212b9c1b51eSKate Stone // use-color changed. Ping the prompt so it can reset the ansi terminal 213b9c1b51eSKate Stone // codes. 214c3ce7f27SMichael Sartain SetPrompt(GetPrompt()); 215acae69d0SEmre Kultursay } else if (property_path == g_debugger_properties[ePropertyUseSourceCache].name) { 216acae69d0SEmre Kultursay // use-source-cache changed. Wipe out the cache contents if it was disabled. 217acae69d0SEmre Kultursay if (!GetUseSourceCache()) { 218acae69d0SEmre Kultursay m_source_file_cache.Clear(); 219acae69d0SEmre Kultursay } 220b9c1b51eSKate Stone } else if (is_load_script && target_sp && 221b9c1b51eSKate Stone load_script_old_value == eLoadScriptFromSymFileWarn) { 222b9c1b51eSKate Stone if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == 223b9c1b51eSKate Stone eLoadScriptFromSymFileTrue) { 22497206d57SZachary Turner std::list<Status> errors; 2259730339bSEnrico Granata StreamString feedback_stream; 226b9c1b51eSKate Stone if (!target_sp->LoadScriptingResources(errors, &feedback_stream)) { 2277ca15ba7SLawrence D'Anna Stream &s = GetErrorStream(); 228b9c1b51eSKate Stone for (auto error : errors) { 2297ca15ba7SLawrence D'Anna s.Printf("%s\n", error.AsCString()); 23084a53dfbSEnrico Granata } 2319730339bSEnrico Granata if (feedback_stream.GetSize()) 2327ca15ba7SLawrence D'Anna s.PutCString(feedback_stream.GetString()); 23384a53dfbSEnrico Granata } 23484a53dfbSEnrico Granata } 235ebdc1ac0SEnrico Granata } 2364c05410fSGreg Clayton } 2374c05410fSGreg Clayton return error; 2384c05410fSGreg Clayton } 2394c05410fSGreg Clayton 240b9c1b51eSKate Stone bool Debugger::GetAutoConfirm() const { 24167cc0636SGreg Clayton const uint32_t idx = ePropertyAutoConfirm; 242b9c1b51eSKate Stone return m_collection_sp->GetPropertyAtIndexAsBoolean( 243a8ea5955SJonas Devlieghere nullptr, idx, g_debugger_properties[idx].default_uint_value != 0); 24467cc0636SGreg Clayton } 24567cc0636SGreg Clayton 246b9c1b51eSKate Stone const FormatEntity::Entry *Debugger::GetDisassemblyFormat() const { 247aff1b357SJason Molenda const uint32_t idx = ePropertyDisassemblyFormat; 248df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); 249aff1b357SJason Molenda } 250aff1b357SJason Molenda 251b9c1b51eSKate Stone const FormatEntity::Entry *Debugger::GetFrameFormat() const { 25267cc0636SGreg Clayton const uint32_t idx = ePropertyFrameFormat; 253df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); 25467cc0636SGreg Clayton } 25567cc0636SGreg Clayton 2567f1c1211SPavel Labath const FormatEntity::Entry *Debugger::GetFrameFormatUnique() const { 2577f1c1211SPavel Labath const uint32_t idx = ePropertyFrameFormatUnique; 2587f1c1211SPavel Labath return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); 2597f1c1211SPavel Labath } 2607f1c1211SPavel Labath 261b9c1b51eSKate Stone bool Debugger::GetNotifyVoid() const { 26267cc0636SGreg Clayton const uint32_t idx = ePropertyNotiftVoid; 263b9c1b51eSKate Stone return m_collection_sp->GetPropertyAtIndexAsBoolean( 264a8ea5955SJonas Devlieghere nullptr, idx, g_debugger_properties[idx].default_uint_value != 0); 26567cc0636SGreg Clayton } 26667cc0636SGreg Clayton 267514d8cd8SZachary Turner llvm::StringRef Debugger::GetPrompt() const { 26867cc0636SGreg Clayton const uint32_t idx = ePropertyPrompt; 269b9c1b51eSKate Stone return m_collection_sp->GetPropertyAtIndexAsString( 270a8ea5955SJonas Devlieghere nullptr, idx, g_debugger_properties[idx].default_cstr_value); 27167cc0636SGreg Clayton } 27267cc0636SGreg Clayton 273514d8cd8SZachary Turner void Debugger::SetPrompt(llvm::StringRef p) { 27467cc0636SGreg Clayton const uint32_t idx = ePropertyPrompt; 275df370550SEugene Zelenko m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, p); 276514d8cd8SZachary Turner llvm::StringRef new_prompt = GetPrompt(); 277b9c1b51eSKate Stone std::string str = 2784b3c0fd5SJonas Devlieghere lldb_private::ansi::FormatAnsiTerminalCodes(new_prompt, GetUseColor()); 279c3ce7f27SMichael Sartain if (str.length()) 280771ef6d4SMalcolm Parsons new_prompt = str; 28144d93782SGreg Clayton GetCommandInterpreter().UpdatePrompt(new_prompt); 28267cc0636SGreg Clayton } 28367cc0636SGreg Clayton 2849e046f02SJonas Devlieghere llvm::StringRef Debugger::GetReproducerPath() const { 2859e046f02SJonas Devlieghere auto &r = repro::Reproducer::Instance(); 2869e046f02SJonas Devlieghere return r.GetReproducerPath().GetCString(); 2879e046f02SJonas Devlieghere } 2889e046f02SJonas Devlieghere 289b9c1b51eSKate Stone const FormatEntity::Entry *Debugger::GetThreadFormat() const { 29067cc0636SGreg Clayton const uint32_t idx = ePropertyThreadFormat; 291df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); 29267cc0636SGreg Clayton } 29367cc0636SGreg Clayton 2946a9767c7SJim Ingham const FormatEntity::Entry *Debugger::GetThreadStopFormat() const { 2956a9767c7SJim Ingham const uint32_t idx = ePropertyThreadStopFormat; 2966a9767c7SJim Ingham return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); 2976a9767c7SJim Ingham } 2986a9767c7SJim Ingham 299b9c1b51eSKate Stone lldb::ScriptLanguage Debugger::GetScriptLanguage() const { 30067cc0636SGreg Clayton const uint32_t idx = ePropertyScriptLanguage; 301b9c1b51eSKate Stone return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration( 302a8ea5955SJonas Devlieghere nullptr, idx, g_debugger_properties[idx].default_uint_value); 30367cc0636SGreg Clayton } 30467cc0636SGreg Clayton 305b9c1b51eSKate Stone bool Debugger::SetScriptLanguage(lldb::ScriptLanguage script_lang) { 30667cc0636SGreg Clayton const uint32_t idx = ePropertyScriptLanguage; 307b9c1b51eSKate Stone return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx, 308b9c1b51eSKate Stone script_lang); 30967cc0636SGreg Clayton } 31067cc0636SGreg Clayton 311b9c1b51eSKate Stone uint32_t Debugger::GetTerminalWidth() const { 31267cc0636SGreg Clayton const uint32_t idx = ePropertyTerminalWidth; 313b9c1b51eSKate Stone return m_collection_sp->GetPropertyAtIndexAsSInt64( 314a8ea5955SJonas Devlieghere nullptr, idx, g_debugger_properties[idx].default_uint_value); 31567cc0636SGreg Clayton } 31667cc0636SGreg Clayton 317b9c1b51eSKate Stone bool Debugger::SetTerminalWidth(uint32_t term_width) { 318d9166ad2SFred Riss if (auto handler_sp = m_io_handler_stack.Top()) 319d9166ad2SFred Riss handler_sp->TerminalSizeChanged(); 320d9166ad2SFred Riss 32167cc0636SGreg Clayton const uint32_t idx = ePropertyTerminalWidth; 322df370550SEugene Zelenko return m_collection_sp->SetPropertyAtIndexAsSInt64(nullptr, idx, term_width); 32367cc0636SGreg Clayton } 32467cc0636SGreg Clayton 325b9c1b51eSKate Stone bool Debugger::GetUseExternalEditor() const { 32667cc0636SGreg Clayton const uint32_t idx = ePropertyUseExternalEditor; 327b9c1b51eSKate Stone return m_collection_sp->GetPropertyAtIndexAsBoolean( 328a8ea5955SJonas Devlieghere nullptr, idx, g_debugger_properties[idx].default_uint_value != 0); 32967cc0636SGreg Clayton } 33067cc0636SGreg Clayton 331b9c1b51eSKate Stone bool Debugger::SetUseExternalEditor(bool b) { 33267cc0636SGreg Clayton const uint32_t idx = ePropertyUseExternalEditor; 333df370550SEugene Zelenko return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 33467cc0636SGreg Clayton } 33567cc0636SGreg Clayton 336b9c1b51eSKate Stone bool Debugger::GetUseColor() const { 337c3ce7f27SMichael Sartain const uint32_t idx = ePropertyUseColor; 338b9c1b51eSKate Stone return m_collection_sp->GetPropertyAtIndexAsBoolean( 339a8ea5955SJonas Devlieghere nullptr, idx, g_debugger_properties[idx].default_uint_value != 0); 340c3ce7f27SMichael Sartain } 341c3ce7f27SMichael Sartain 342b9c1b51eSKate Stone bool Debugger::SetUseColor(bool b) { 343c3ce7f27SMichael Sartain const uint32_t idx = ePropertyUseColor; 344df370550SEugene Zelenko bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 345c3ce7f27SMichael Sartain SetPrompt(GetPrompt()); 346c3ce7f27SMichael Sartain return ret; 347c3ce7f27SMichael Sartain } 348c3ce7f27SMichael Sartain 349de9e8502SShu Anzai bool Debugger::GetUseAutosuggestion() const { 350de9e8502SShu Anzai const uint32_t idx = ePropertyShowAutosuggestion; 351de9e8502SShu Anzai return m_collection_sp->GetPropertyAtIndexAsBoolean( 352de9e8502SShu Anzai nullptr, idx, g_debugger_properties[idx].default_uint_value != 0); 353de9e8502SShu Anzai } 354de9e8502SShu Anzai 355acae69d0SEmre Kultursay bool Debugger::GetUseSourceCache() const { 356acae69d0SEmre Kultursay const uint32_t idx = ePropertyUseSourceCache; 357acae69d0SEmre Kultursay return m_collection_sp->GetPropertyAtIndexAsBoolean( 358acae69d0SEmre Kultursay nullptr, idx, g_debugger_properties[idx].default_uint_value != 0); 359acae69d0SEmre Kultursay } 360acae69d0SEmre Kultursay 361acae69d0SEmre Kultursay bool Debugger::SetUseSourceCache(bool b) { 362acae69d0SEmre Kultursay const uint32_t idx = ePropertyUseSourceCache; 363acae69d0SEmre Kultursay bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 364acae69d0SEmre Kultursay if (!ret) { 365acae69d0SEmre Kultursay m_source_file_cache.Clear(); 366acae69d0SEmre Kultursay } 367acae69d0SEmre Kultursay return ret; 368acae69d0SEmre Kultursay } 369566afa0aSRaphael Isemann bool Debugger::GetHighlightSource() const { 370566afa0aSRaphael Isemann const uint32_t idx = ePropertyHighlightSource; 371566afa0aSRaphael Isemann return m_collection_sp->GetPropertyAtIndexAsBoolean( 372a8ea5955SJonas Devlieghere nullptr, idx, g_debugger_properties[idx].default_uint_value); 373566afa0aSRaphael Isemann } 374566afa0aSRaphael Isemann 3759666ba75STodd Fiala StopShowColumn Debugger::GetStopShowColumn() const { 3769666ba75STodd Fiala const uint32_t idx = ePropertyStopShowColumn; 3779666ba75STodd Fiala return (lldb::StopShowColumn)m_collection_sp->GetPropertyAtIndexAsEnumeration( 378a8ea5955SJonas Devlieghere nullptr, idx, g_debugger_properties[idx].default_uint_value); 3799666ba75STodd Fiala } 3809666ba75STodd Fiala 38120786326SRaphael Isemann llvm::StringRef Debugger::GetStopShowColumnAnsiPrefix() const { 3829666ba75STodd Fiala const uint32_t idx = ePropertyStopShowColumnAnsiPrefix; 38320786326SRaphael Isemann return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); 3849666ba75STodd Fiala } 3859666ba75STodd Fiala 38620786326SRaphael Isemann llvm::StringRef Debugger::GetStopShowColumnAnsiSuffix() const { 3879666ba75STodd Fiala const uint32_t idx = ePropertyStopShowColumnAnsiSuffix; 38820786326SRaphael Isemann return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); 3899666ba75STodd Fiala } 3909666ba75STodd Fiala 391841be985SJonas Devlieghere llvm::StringRef Debugger::GetStopShowLineMarkerAnsiPrefix() const { 392841be985SJonas Devlieghere const uint32_t idx = ePropertyStopShowLineMarkerAnsiPrefix; 393841be985SJonas Devlieghere return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); 394841be985SJonas Devlieghere } 395841be985SJonas Devlieghere 396841be985SJonas Devlieghere llvm::StringRef Debugger::GetStopShowLineMarkerAnsiSuffix() const { 397841be985SJonas Devlieghere const uint32_t idx = ePropertyStopShowLineMarkerAnsiSuffix; 398841be985SJonas Devlieghere return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); 399841be985SJonas Devlieghere } 400841be985SJonas Devlieghere 401b9c1b51eSKate Stone uint32_t Debugger::GetStopSourceLineCount(bool before) const { 402b9c1b51eSKate Stone const uint32_t idx = 403b9c1b51eSKate Stone before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter; 404b9c1b51eSKate Stone return m_collection_sp->GetPropertyAtIndexAsSInt64( 405a8ea5955SJonas Devlieghere nullptr, idx, g_debugger_properties[idx].default_uint_value); 40667cc0636SGreg Clayton } 40767cc0636SGreg Clayton 408b9c1b51eSKate Stone Debugger::StopDisassemblyType Debugger::GetStopDisassemblyDisplay() const { 40967cc0636SGreg Clayton const uint32_t idx = ePropertyStopDisassemblyDisplay; 410b9c1b51eSKate Stone return (Debugger::StopDisassemblyType) 411b9c1b51eSKate Stone m_collection_sp->GetPropertyAtIndexAsEnumeration( 412a8ea5955SJonas Devlieghere nullptr, idx, g_debugger_properties[idx].default_uint_value); 41367cc0636SGreg Clayton } 41467cc0636SGreg Clayton 415b9c1b51eSKate Stone uint32_t Debugger::GetDisassemblyLineCount() const { 41667cc0636SGreg Clayton const uint32_t idx = ePropertyStopDisassemblyCount; 417b9c1b51eSKate Stone return m_collection_sp->GetPropertyAtIndexAsSInt64( 418a8ea5955SJonas Devlieghere nullptr, idx, g_debugger_properties[idx].default_uint_value); 41967cc0636SGreg Clayton } 420e372b98dSGreg Clayton 421b9c1b51eSKate Stone bool Debugger::GetAutoOneLineSummaries() const { 42290a8db30SEnrico Granata const uint32_t idx = ePropertyAutoOneLineSummaries; 423df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true); 424ebdc1ac0SEnrico Granata } 425553fad5cSEnrico Granata 426b9c1b51eSKate Stone bool Debugger::GetEscapeNonPrintables() const { 427ebdc1ac0SEnrico Granata const uint32_t idx = ePropertyEscapeNonPrintables; 428df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true); 429553fad5cSEnrico Granata } 430553fad5cSEnrico Granata 431b9c1b51eSKate Stone bool Debugger::GetAutoIndent() const { 4326681041dSSean Callanan const uint32_t idx = ePropertyAutoIndent; 433df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true); 4346681041dSSean Callanan } 4356681041dSSean Callanan 436b9c1b51eSKate Stone bool Debugger::SetAutoIndent(bool b) { 4376681041dSSean Callanan const uint32_t idx = ePropertyAutoIndent; 438df370550SEugene Zelenko return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 4396681041dSSean Callanan } 4406681041dSSean Callanan 441b9c1b51eSKate Stone bool Debugger::GetPrintDecls() const { 4426681041dSSean Callanan const uint32_t idx = ePropertyPrintDecls; 443df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true); 4446681041dSSean Callanan } 4456681041dSSean Callanan 446b9c1b51eSKate Stone bool Debugger::SetPrintDecls(bool b) { 4476681041dSSean Callanan const uint32_t idx = ePropertyPrintDecls; 448df370550SEugene Zelenko return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 4496681041dSSean Callanan } 4506681041dSSean Callanan 451b9c1b51eSKate Stone uint32_t Debugger::GetTabSize() const { 4526681041dSSean Callanan const uint32_t idx = ePropertyTabSize; 453b9c1b51eSKate Stone return m_collection_sp->GetPropertyAtIndexAsUInt64( 454a8ea5955SJonas Devlieghere nullptr, idx, g_debugger_properties[idx].default_uint_value); 4556681041dSSean Callanan } 4566681041dSSean Callanan 457b9c1b51eSKate Stone bool Debugger::SetTabSize(uint32_t tab_size) { 4586681041dSSean Callanan const uint32_t idx = ePropertyTabSize; 459df370550SEugene Zelenko return m_collection_sp->SetPropertyAtIndexAsUInt64(nullptr, idx, tab_size); 4606681041dSSean Callanan } 4616681041dSSean Callanan 4621b654882SGreg Clayton #pragma mark Debugger 4631b654882SGreg Clayton 46467cc0636SGreg Clayton // const DebuggerPropertiesSP & 46567cc0636SGreg Clayton // Debugger::GetSettings() const 46667cc0636SGreg Clayton //{ 46767cc0636SGreg Clayton // return m_properties_sp; 46867cc0636SGreg Clayton //} 46967cc0636SGreg Clayton // 47099d0faf2SGreg Clayton 471b9c1b51eSKate Stone void Debugger::Initialize(LoadPluginCallbackType load_plugin_callback) { 472b9c1b51eSKate Stone assert(g_debugger_list_ptr == nullptr && 473b9c1b51eSKate Stone "Debugger::Initialize called more than once!"); 4746c42e063SGreg Clayton g_debugger_list_mutex_ptr = new std::recursive_mutex(); 4756c42e063SGreg Clayton g_debugger_list_ptr = new DebuggerList(); 4765fb8f797SGreg Clayton g_load_plugin_callback = load_plugin_callback; 47799d0faf2SGreg Clayton } 47830fdc8d8SChris Lattner 479b9c1b51eSKate Stone void Debugger::Terminate() { 480b9c1b51eSKate Stone assert(g_debugger_list_ptr && 481b9c1b51eSKate Stone "Debugger::Terminate called without a matching Debugger::Initialize!"); 482e6e2bb38SZachary Turner 483b9c1b51eSKate Stone if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 48499d0faf2SGreg Clayton // Clear our master list of debugger objects 4856c42e063SGreg Clayton { 4866c42e063SGreg Clayton std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 4876c42e063SGreg Clayton for (const auto &debugger : *g_debugger_list_ptr) 488f3cd1819SOleksiy Vyalov debugger->Clear(); 4896c42e063SGreg Clayton g_debugger_list_ptr->clear(); 4906c42e063SGreg Clayton } 4916c42e063SGreg Clayton } 49230fdc8d8SChris Lattner } 49330fdc8d8SChris Lattner 494b9c1b51eSKate Stone void Debugger::SettingsInitialize() { Target::SettingsInitialize(); } 49520bd37f7SCaroline Tice 496b9c1b51eSKate Stone void Debugger::SettingsTerminate() { Target::SettingsTerminate(); } 49720bd37f7SCaroline Tice 49897206d57SZachary Turner bool Debugger::LoadPlugin(const FileSpec &spec, Status &error) { 499b9c1b51eSKate Stone if (g_load_plugin_callback) { 500b9c1b51eSKate Stone llvm::sys::DynamicLibrary dynlib = 501b9c1b51eSKate Stone g_load_plugin_callback(shared_from_this(), spec, error); 502b9c1b51eSKate Stone if (dynlib.isValid()) { 50358a559c0SZachary Turner m_loaded_plugins.push_back(dynlib); 50421dfcd9dSEnrico Granata return true; 50521dfcd9dSEnrico Granata } 506b9c1b51eSKate Stone } else { 50705097246SAdrian Prantl // The g_load_plugin_callback is registered in SBDebugger::Initialize() and 50805097246SAdrian Prantl // if the public API layer isn't available (code is linking against all of 50905097246SAdrian Prantl // the internal LLDB static libraries), then we can't load plugins 5105fb8f797SGreg Clayton error.SetErrorString("Public API layer is not available"); 5115fb8f797SGreg Clayton } 51221dfcd9dSEnrico Granata return false; 51321dfcd9dSEnrico Granata } 51421dfcd9dSEnrico Granata 51535e4c84cSJonas Devlieghere static FileSystem::EnumerateDirectoryResult 5167d86ee5aSZachary Turner LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft, 51735e4c84cSJonas Devlieghere llvm::StringRef path) { 51897206d57SZachary Turner Status error; 51921dfcd9dSEnrico Granata 520ad8d48f9SJonas Devlieghere static ConstString g_dylibext(".dylib"); 521ad8d48f9SJonas Devlieghere static ConstString g_solibext(".so"); 52221dfcd9dSEnrico Granata 52321dfcd9dSEnrico Granata if (!baton) 52435e4c84cSJonas Devlieghere return FileSystem::eEnumerateDirectoryResultQuit; 52521dfcd9dSEnrico Granata 52621dfcd9dSEnrico Granata Debugger *debugger = (Debugger *)baton; 52721dfcd9dSEnrico Granata 5287d86ee5aSZachary Turner namespace fs = llvm::sys::fs; 52905097246SAdrian Prantl // If we have a regular file, a symbolic link or unknown file type, try and 53005097246SAdrian Prantl // process the file. We must handle unknown as sometimes the directory 53121dfcd9dSEnrico Granata // enumeration might be enumerating a file system that doesn't have correct 53221dfcd9dSEnrico Granata // file type information. 5337d86ee5aSZachary Turner if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file || 5347d86ee5aSZachary Turner ft == fs::file_type::type_unknown) { 5358f3be7a3SJonas Devlieghere FileSpec plugin_file_spec(path); 5368f3be7a3SJonas Devlieghere FileSystem::Instance().Resolve(plugin_file_spec); 53721dfcd9dSEnrico Granata 5383cf443ddSMichael Sartain if (plugin_file_spec.GetFileNameExtension() != g_dylibext && 539b9c1b51eSKate Stone plugin_file_spec.GetFileNameExtension() != g_solibext) { 54035e4c84cSJonas Devlieghere return FileSystem::eEnumerateDirectoryResultNext; 5413cf443ddSMichael Sartain } 54221dfcd9dSEnrico Granata 54397206d57SZachary Turner Status plugin_load_error; 544e743c782SEnrico Granata debugger->LoadPlugin(plugin_file_spec, plugin_load_error); 54521dfcd9dSEnrico Granata 54635e4c84cSJonas Devlieghere return FileSystem::eEnumerateDirectoryResultNext; 5477d86ee5aSZachary Turner } else if (ft == fs::file_type::directory_file || 5487d86ee5aSZachary Turner ft == fs::file_type::symlink_file || 5497d86ee5aSZachary Turner ft == fs::file_type::type_unknown) { 55005097246SAdrian Prantl // Try and recurse into anything that a directory or symbolic link. We must 55105097246SAdrian Prantl // also do this for unknown as sometimes the directory enumeration might be 55205097246SAdrian Prantl // enumerating a file system that doesn't have correct file type 55321dfcd9dSEnrico Granata // information. 55435e4c84cSJonas Devlieghere return FileSystem::eEnumerateDirectoryResultEnter; 55521dfcd9dSEnrico Granata } 55621dfcd9dSEnrico Granata 55735e4c84cSJonas Devlieghere return FileSystem::eEnumerateDirectoryResultNext; 55821dfcd9dSEnrico Granata } 55921dfcd9dSEnrico Granata 560b9c1b51eSKate Stone void Debugger::InstanceInitialize() { 56121dfcd9dSEnrico Granata const bool find_directories = true; 56221dfcd9dSEnrico Granata const bool find_files = true; 56321dfcd9dSEnrico Granata const bool find_other = true; 56421dfcd9dSEnrico Granata char dir_path[PATH_MAX]; 56560f028ffSPavel Labath if (FileSpec dir_spec = HostInfo::GetSystemPluginDir()) { 566dbd7fabaSJonas Devlieghere if (FileSystem::Instance().Exists(dir_spec) && 567dbd7fabaSJonas Devlieghere dir_spec.GetPath(dir_path, sizeof(dir_path))) { 56835e4c84cSJonas Devlieghere FileSystem::Instance().EnumerateDirectory(dir_path, find_directories, 56935e4c84cSJonas Devlieghere find_files, find_other, 57035e4c84cSJonas Devlieghere LoadPluginCallback, this); 57121dfcd9dSEnrico Granata } 57221dfcd9dSEnrico Granata } 57321dfcd9dSEnrico Granata 57460f028ffSPavel Labath if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) { 575dbd7fabaSJonas Devlieghere if (FileSystem::Instance().Exists(dir_spec) && 576dbd7fabaSJonas Devlieghere dir_spec.GetPath(dir_path, sizeof(dir_path))) { 57735e4c84cSJonas Devlieghere FileSystem::Instance().EnumerateDirectory(dir_path, find_directories, 57835e4c84cSJonas Devlieghere find_files, find_other, 57935e4c84cSJonas Devlieghere LoadPluginCallback, this); 58021dfcd9dSEnrico Granata } 58121dfcd9dSEnrico Granata } 582e8cd0c98SGreg Clayton 583e8cd0c98SGreg Clayton PluginManager::DebuggerInitialize(*this); 58421dfcd9dSEnrico Granata } 58521dfcd9dSEnrico Granata 586b9c1b51eSKate Stone DebuggerSP Debugger::CreateInstance(lldb::LogOutputCallback log_callback, 587b9c1b51eSKate Stone void *baton) { 588228063cdSJim Ingham DebuggerSP debugger_sp(new Debugger(log_callback, baton)); 589b9c1b51eSKate Stone if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 5906c42e063SGreg Clayton std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 5916c42e063SGreg Clayton g_debugger_list_ptr->push_back(debugger_sp); 5926611103cSGreg Clayton } 59321dfcd9dSEnrico Granata debugger_sp->InstanceInitialize(); 5946611103cSGreg Clayton return debugger_sp; 5956611103cSGreg Clayton } 5966611103cSGreg Clayton 597b9c1b51eSKate Stone void Debugger::Destroy(DebuggerSP &debugger_sp) { 598df370550SEugene Zelenko if (!debugger_sp) 599e02657b1SCaroline Tice return; 600e02657b1SCaroline Tice 6018314c525SJim Ingham debugger_sp->Clear(); 6028314c525SJim Ingham 603b9c1b51eSKate Stone if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 6046c42e063SGreg Clayton std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 6056c42e063SGreg Clayton DebuggerList::iterator pos, end = g_debugger_list_ptr->end(); 606b9c1b51eSKate Stone for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) { 607b9c1b51eSKate Stone if ((*pos).get() == debugger_sp.get()) { 6086c42e063SGreg Clayton g_debugger_list_ptr->erase(pos); 609e02657b1SCaroline Tice return; 610e02657b1SCaroline Tice } 611e02657b1SCaroline Tice } 612e02657b1SCaroline Tice } 613c15f55e2SGreg Clayton } 614e02657b1SCaroline Tice 615e063ecccSJonas Devlieghere DebuggerSP Debugger::FindDebuggerWithInstanceName(ConstString instance_name) { 6164d122c40SGreg Clayton DebuggerSP debugger_sp; 617b9c1b51eSKate Stone if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 6186c42e063SGreg Clayton std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 6196c42e063SGreg Clayton DebuggerList::iterator pos, end = g_debugger_list_ptr->end(); 620b9c1b51eSKate Stone for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) { 621b9c1b51eSKate Stone if ((*pos)->m_instance_name == instance_name) { 6226920b52bSGreg Clayton debugger_sp = *pos; 6236920b52bSGreg Clayton break; 6246920b52bSGreg Clayton } 6256920b52bSGreg Clayton } 6266920b52bSGreg Clayton } 6273df9a8dfSCaroline Tice return debugger_sp; 6283df9a8dfSCaroline Tice } 6296611103cSGreg Clayton 630b9c1b51eSKate Stone TargetSP Debugger::FindTargetWithProcessID(lldb::pid_t pid) { 6314d122c40SGreg Clayton TargetSP target_sp; 632b9c1b51eSKate Stone if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 6336c42e063SGreg Clayton std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 6346c42e063SGreg Clayton DebuggerList::iterator pos, end = g_debugger_list_ptr->end(); 635b9c1b51eSKate Stone for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) { 6366611103cSGreg Clayton target_sp = (*pos)->GetTargetList().FindTargetWithProcessID(pid); 6376611103cSGreg Clayton if (target_sp) 6386611103cSGreg Clayton break; 6396611103cSGreg Clayton } 640c15f55e2SGreg Clayton } 6416611103cSGreg Clayton return target_sp; 6426611103cSGreg Clayton } 6436611103cSGreg Clayton 644b9c1b51eSKate Stone TargetSP Debugger::FindTargetWithProcess(Process *process) { 645e4e45924SGreg Clayton TargetSP target_sp; 646b9c1b51eSKate Stone if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 6476c42e063SGreg Clayton std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 6486c42e063SGreg Clayton DebuggerList::iterator pos, end = g_debugger_list_ptr->end(); 649b9c1b51eSKate Stone for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) { 650e4e45924SGreg Clayton target_sp = (*pos)->GetTargetList().FindTargetWithProcess(process); 651e4e45924SGreg Clayton if (target_sp) 652e4e45924SGreg Clayton break; 653e4e45924SGreg Clayton } 654c15f55e2SGreg Clayton } 655e4e45924SGreg Clayton return target_sp; 656e4e45924SGreg Clayton } 657e4e45924SGreg Clayton 658b9c1b51eSKate Stone Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) 659b9c1b51eSKate Stone : UserID(g_unique_id++), 6602f3df613SZachary Turner Properties(std::make_shared<OptionValueProperties>()), 661f913fd6eSLawrence D'Anna m_input_file_sp(std::make_shared<NativeFile>(stdin, false)), 6627ca15ba7SLawrence D'Anna m_output_stream_sp(std::make_shared<StreamFile>(stdout, false)), 6637ca15ba7SLawrence D'Anna m_error_stream_sp(std::make_shared<StreamFile>(stderr, false)), 664d77c2e09SJonas Devlieghere m_input_recorder(nullptr), 665583bbb1dSJim Ingham m_broadcaster_manager_sp(BroadcasterManager::MakeBroadcasterManager()), 666b9c1b51eSKate Stone m_terminal_state(), m_target_list(*this), m_platform_list(), 667583bbb1dSJim Ingham m_listener_sp(Listener::MakeListener("lldb.Debugger")), 668d5b44036SJonas Devlieghere m_source_manager_up(), m_source_file_cache(), 669f20dd1d5SJonas Devlieghere m_command_interpreter_up( 670a8f3ae7cSJonas Devlieghere std::make_unique<CommandInterpreter>(*this, false)), 6717ce2de2cSJonas Devlieghere m_io_handler_stack(), m_instance_name(), m_loaded_plugins(), 672bbf70c04SJonas Devlieghere m_event_handler_thread(), m_io_handler_thread(), 6734329fe42SGreg Clayton m_sync_broadcaster(nullptr, "lldb.debugger.sync"), 674b9c1b51eSKate Stone m_forward_listener_sp(), m_clear_once() { 675db203e02SRaphael Isemann m_instance_name.SetString(llvm::formatv("debugger_{0}", GetID()).str()); 676228063cdSJim Ingham if (log_callback) 6772f3df613SZachary Turner m_log_callback_stream_sp = 6782f3df613SZachary Turner std::make_shared<StreamCallback>(log_callback, baton); 679d5b44036SJonas Devlieghere m_command_interpreter_up->Initialize(); 680ded470d3SGreg Clayton // Always add our default platform to the platform list 681615eb7e6SGreg Clayton PlatformSP default_platform_sp(Platform::GetHostPlatform()); 682df370550SEugene Zelenko assert(default_platform_sp); 683ded470d3SGreg Clayton m_platform_list.Append(default_platform_sp, true); 68467cc0636SGreg Clayton 68516e5a347SVedant Kumar // Create the dummy target. 68616e5a347SVedant Kumar { 68716e5a347SVedant Kumar ArchSpec arch(Target::GetDefaultArchitecture()); 68816e5a347SVedant Kumar if (!arch.IsValid()) 68916e5a347SVedant Kumar arch = HostInfo::GetArchitecture(); 69016e5a347SVedant Kumar assert(arch.IsValid() && "No valid default or host archspec"); 69116e5a347SVedant Kumar const bool is_dummy_target = true; 69216e5a347SVedant Kumar m_dummy_target_sp.reset( 69316e5a347SVedant Kumar new Target(*this, arch, default_platform_sp, is_dummy_target)); 69416e5a347SVedant Kumar } 695d43d912bSRaphael Isemann assert(m_dummy_target_sp.get() && "Couldn't construct dummy target?"); 696d43d912bSRaphael Isemann 697a8ea5955SJonas Devlieghere m_collection_sp->Initialize(g_debugger_properties); 698b9c1b51eSKate Stone m_collection_sp->AppendProperty( 699b9c1b51eSKate Stone ConstString("target"), 700b9c1b51eSKate Stone ConstString("Settings specify to debugging targets."), true, 70167cc0636SGreg Clayton Target::GetGlobalProperties()->GetValueProperties()); 702b9c1b51eSKate Stone m_collection_sp->AppendProperty( 703b9c1b51eSKate Stone ConstString("platform"), ConstString("Platform settings."), true, 70463acdfdeSOleksiy Vyalov Platform::GetGlobalPlatformProperties()->GetValueProperties()); 705235354beSAdrian Prantl m_collection_sp->AppendProperty( 7063cd29bcfSAdrian Prantl ConstString("symbols"), ConstString("Symbol lookup and cache settings."), 7073cd29bcfSAdrian Prantl true, ModuleList::GetGlobalModuleListProperties().GetValueProperties()); 708d5b44036SJonas Devlieghere if (m_command_interpreter_up) { 709b9c1b51eSKate Stone m_collection_sp->AppendProperty( 710b9c1b51eSKate Stone ConstString("interpreter"), 711754a9369SGreg Clayton ConstString("Settings specify to the debugger's command interpreter."), 712d5b44036SJonas Devlieghere true, m_command_interpreter_up->GetValueProperties()); 713754a9369SGreg Clayton } 714b9c1b51eSKate Stone OptionValueSInt64 *term_width = 715b9c1b51eSKate Stone m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64( 716b9c1b51eSKate Stone nullptr, ePropertyTerminalWidth); 71767cc0636SGreg Clayton term_width->SetMinimumValue(10); 71867cc0636SGreg Clayton term_width->SetMaximumValue(1024); 719c3ce7f27SMichael Sartain 720c3ce7f27SMichael Sartain // Turn off use-color if this is a dumb terminal. 721c3ce7f27SMichael Sartain const char *term = getenv("TERM"); 722c3ce7f27SMichael Sartain if (term && !strcmp(term, "dumb")) 723c3ce7f27SMichael Sartain SetUseColor(false); 724eca9ce14SRaphael Isemann // Turn off use-color if we don't write to a terminal with color support. 7257ca15ba7SLawrence D'Anna if (!GetOutputFile().GetIsTerminalWithColors()) 726eca9ce14SRaphael Isemann SetUseColor(false); 7278aa23614SDavid Bolvansky 7288aa23614SDavid Bolvansky #if defined(_WIN32) && defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING) 7298aa23614SDavid Bolvansky // Enabling use of ANSI color codes because LLDB is using them to highlight 7308aa23614SDavid Bolvansky // text. 7318aa23614SDavid Bolvansky llvm::sys::Process::UseANSIEscapeCodes(true); 7328aa23614SDavid Bolvansky #endif 73330fdc8d8SChris Lattner } 73430fdc8d8SChris Lattner 735b9c1b51eSKate Stone Debugger::~Debugger() { Clear(); } 7368314c525SJim Ingham 737b9c1b51eSKate Stone void Debugger::Clear() { 73805097246SAdrian Prantl // Make sure we call this function only once. With the C++ global destructor 73905097246SAdrian Prantl // chain having a list of debuggers and with code that can be running on 74005097246SAdrian Prantl // other threads, we need to ensure this doesn't happen multiple times. 7414329fe42SGreg Clayton // 7424329fe42SGreg Clayton // The following functions call Debugger::Clear(): 7434329fe42SGreg Clayton // Debugger::~Debugger(); 7444329fe42SGreg Clayton // static void Debugger::Destroy(lldb::DebuggerSP &debugger_sp); 7454329fe42SGreg Clayton // static void Debugger::Terminate(); 746c5f28e2aSKamil Rytarowski llvm::call_once(m_clear_once, [this]() { 74744d93782SGreg Clayton ClearIOHandlers(); 74844d93782SGreg Clayton StopIOHandlerThread(); 74944d93782SGreg Clayton StopEventHandlerThread(); 750583bbb1dSJim Ingham m_listener_sp->Clear(); 7516611103cSGreg Clayton int num_targets = m_target_list.GetNumTargets(); 752b9c1b51eSKate Stone for (int i = 0; i < num_targets; i++) { 753ccbc08e6SGreg Clayton TargetSP target_sp(m_target_list.GetTargetAtIndex(i)); 754b9c1b51eSKate Stone if (target_sp) { 755ccbc08e6SGreg Clayton ProcessSP process_sp(target_sp->GetProcessSP()); 7566611103cSGreg Clayton if (process_sp) 7571fd07059SJim Ingham process_sp->Finalize(); 758ccbc08e6SGreg Clayton target_sp->Destroy(); 7596611103cSGreg Clayton } 76030fdc8d8SChris Lattner } 761583bbb1dSJim Ingham m_broadcaster_manager_sp->Clear(); 76230fdc8d8SChris Lattner 763b9c1b51eSKate Stone // Close the input file _before_ we close the input read communications 76405097246SAdrian Prantl // class as it does NOT own the input file, our m_input_file does. 765c5917d9aSJim Ingham m_terminal_state.Clear(); 7667ca15ba7SLawrence D'Anna GetInputFile().Close(); 7670c4129f2SGreg Clayton 768d5b44036SJonas Devlieghere m_command_interpreter_up->Clear(); 7694329fe42SGreg Clayton }); 7708314c525SJim Ingham } 77130fdc8d8SChris Lattner 772b9c1b51eSKate Stone bool Debugger::GetCloseInputOnEOF() const { 77344d93782SGreg Clayton // return m_input_comm.GetCloseOnEOF(); 77444d93782SGreg Clayton return false; 775fc3f027dSGreg Clayton } 776fc3f027dSGreg Clayton 777b9c1b51eSKate Stone void Debugger::SetCloseInputOnEOF(bool b) { 77844d93782SGreg Clayton // m_input_comm.SetCloseOnEOF(b); 779fc3f027dSGreg Clayton } 780fc3f027dSGreg Clayton 781b9c1b51eSKate Stone bool Debugger::GetAsyncExecution() { 782d5b44036SJonas Devlieghere return !m_command_interpreter_up->GetSynchronous(); 78330fdc8d8SChris Lattner } 78430fdc8d8SChris Lattner 785b9c1b51eSKate Stone void Debugger::SetAsyncExecution(bool async_execution) { 786d5b44036SJonas Devlieghere m_command_interpreter_up->SetSynchronous(!async_execution); 78730fdc8d8SChris Lattner } 78830fdc8d8SChris Lattner 789d77c2e09SJonas Devlieghere repro::DataRecorder *Debugger::GetInputRecorder() { return m_input_recorder; } 790d77c2e09SJonas Devlieghere 79196898eb6SLawrence D'Anna void Debugger::SetInputFile(FileSP file_sp, repro::DataRecorder *recorder) { 79296898eb6SLawrence D'Anna assert(file_sp && file_sp->IsValid()); 793d77c2e09SJonas Devlieghere m_input_recorder = recorder; 794c4701c9cSJonas Devlieghere m_input_file_sp = std::move(file_sp); 79505097246SAdrian Prantl // Save away the terminal state if that is relevant, so that we can restore 79605097246SAdrian Prantl // it in RestoreInputState. 797c5917d9aSJim Ingham SaveInputTerminalState(); 79830fdc8d8SChris Lattner } 79930fdc8d8SChris Lattner 80096898eb6SLawrence D'Anna void Debugger::SetOutputFile(FileSP file_sp) { 80196898eb6SLawrence D'Anna assert(file_sp && file_sp->IsValid()); 8027ca15ba7SLawrence D'Anna m_output_stream_sp = std::make_shared<StreamFile>(file_sp); 80330fdc8d8SChris Lattner } 80430fdc8d8SChris Lattner 80596898eb6SLawrence D'Anna void Debugger::SetErrorFile(FileSP file_sp) { 80696898eb6SLawrence D'Anna assert(file_sp && file_sp->IsValid()); 8077ca15ba7SLawrence D'Anna m_error_stream_sp = std::make_shared<StreamFile>(file_sp); 80830fdc8d8SChris Lattner } 80930fdc8d8SChris Lattner 810b9c1b51eSKate Stone void Debugger::SaveInputTerminalState() { 8117ca15ba7SLawrence D'Anna int fd = GetInputFile().GetDescriptor(); 8127ca15ba7SLawrence D'Anna if (fd != File::kInvalidDescriptor) 8137ca15ba7SLawrence D'Anna m_terminal_state.Save(fd, true); 81444d93782SGreg Clayton } 815c5917d9aSJim Ingham 816b9c1b51eSKate Stone void Debugger::RestoreInputTerminalState() { m_terminal_state.Restore(); } 817c5917d9aSJim Ingham 818b9c1b51eSKate Stone ExecutionContext Debugger::GetSelectedExecutionContext() { 819*a39bcbcaSTatyana Krasnukha bool adopt_selected = true; 820*a39bcbcaSTatyana Krasnukha ExecutionContextRef exe_ctx_ref(GetSelectedTarget().get(), adopt_selected); 821*a39bcbcaSTatyana Krasnukha return ExecutionContext(exe_ctx_ref); 82230fdc8d8SChris Lattner } 82330fdc8d8SChris Lattner 824b9c1b51eSKate Stone void Debugger::DispatchInputInterrupt() { 8257ce2de2cSJonas Devlieghere std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex()); 8267ce2de2cSJonas Devlieghere IOHandlerSP reader_sp(m_io_handler_stack.Top()); 827efed6131SCaroline Tice if (reader_sp) 82844d93782SGreg Clayton reader_sp->Interrupt(); 829efed6131SCaroline Tice } 830efed6131SCaroline Tice 831b9c1b51eSKate Stone void Debugger::DispatchInputEndOfFile() { 8327ce2de2cSJonas Devlieghere std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex()); 8337ce2de2cSJonas Devlieghere IOHandlerSP reader_sp(m_io_handler_stack.Top()); 834efed6131SCaroline Tice if (reader_sp) 83544d93782SGreg Clayton reader_sp->GotEOF(); 836efed6131SCaroline Tice } 837efed6131SCaroline Tice 838b9c1b51eSKate Stone void Debugger::ClearIOHandlers() { 839b9c1b51eSKate Stone // The bottom input reader should be the main debugger input reader. We do 840b9c1b51eSKate Stone // not want to close that one here. 8417ce2de2cSJonas Devlieghere std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex()); 8427ce2de2cSJonas Devlieghere while (m_io_handler_stack.GetSize() > 1) { 8437ce2de2cSJonas Devlieghere IOHandlerSP reader_sp(m_io_handler_stack.Top()); 8443d6086f6SCaroline Tice if (reader_sp) 8454446487dSPavel Labath PopIOHandler(reader_sp); 8463d6086f6SCaroline Tice } 8473d6086f6SCaroline Tice } 8483d6086f6SCaroline Tice 8492671df9bSJonas Devlieghere void Debugger::RunIOHandlers() { 85004de24e6SJonas Devlieghere IOHandlerSP reader_sp = m_io_handler_stack.Top(); 851b9c1b51eSKate Stone while (true) { 85230fdc8d8SChris Lattner if (!reader_sp) 85330fdc8d8SChris Lattner break; 85430fdc8d8SChris Lattner 85544d93782SGreg Clayton reader_sp->Run(); 85604de24e6SJonas Devlieghere { 85704de24e6SJonas Devlieghere std::lock_guard<std::recursive_mutex> guard( 85804de24e6SJonas Devlieghere m_io_handler_synchronous_mutex); 85944d93782SGreg Clayton 86044d93782SGreg Clayton // Remove all input readers that are done from the top of the stack 861b9c1b51eSKate Stone while (true) { 8627ce2de2cSJonas Devlieghere IOHandlerSP top_reader_sp = m_io_handler_stack.Top(); 86344d93782SGreg Clayton if (top_reader_sp && top_reader_sp->GetIsDone()) 8644446487dSPavel Labath PopIOHandler(top_reader_sp); 86530fdc8d8SChris Lattner else 86630fdc8d8SChris Lattner break; 86730fdc8d8SChris Lattner } 86804de24e6SJonas Devlieghere reader_sp = m_io_handler_stack.Top(); 86904de24e6SJonas Devlieghere } 87030fdc8d8SChris Lattner } 87144d93782SGreg Clayton ClearIOHandlers(); 87244d93782SGreg Clayton } 87330fdc8d8SChris Lattner 87404de24e6SJonas Devlieghere void Debugger::RunIOHandlerSync(const IOHandlerSP &reader_sp) { 87504de24e6SJonas Devlieghere std::lock_guard<std::recursive_mutex> guard(m_io_handler_synchronous_mutex); 87604de24e6SJonas Devlieghere 87704de24e6SJonas Devlieghere PushIOHandler(reader_sp); 87804de24e6SJonas Devlieghere IOHandlerSP top_reader_sp = reader_sp; 87904de24e6SJonas Devlieghere 88004de24e6SJonas Devlieghere while (top_reader_sp) { 88104de24e6SJonas Devlieghere if (!top_reader_sp) 88204de24e6SJonas Devlieghere break; 88304de24e6SJonas Devlieghere 88404de24e6SJonas Devlieghere top_reader_sp->Run(); 88504de24e6SJonas Devlieghere 88604de24e6SJonas Devlieghere // Don't unwind past the starting point. 88704de24e6SJonas Devlieghere if (top_reader_sp.get() == reader_sp.get()) { 88804de24e6SJonas Devlieghere if (PopIOHandler(reader_sp)) 88904de24e6SJonas Devlieghere break; 89004de24e6SJonas Devlieghere } 89104de24e6SJonas Devlieghere 89204de24e6SJonas Devlieghere // If we pushed new IO handlers, pop them if they're done or restart the 89304de24e6SJonas Devlieghere // loop to run them if they're not. 89404de24e6SJonas Devlieghere while (true) { 89504de24e6SJonas Devlieghere top_reader_sp = m_io_handler_stack.Top(); 89604de24e6SJonas Devlieghere if (top_reader_sp && top_reader_sp->GetIsDone()) { 89704de24e6SJonas Devlieghere PopIOHandler(top_reader_sp); 89804de24e6SJonas Devlieghere // Don't unwind past the starting point. 89904de24e6SJonas Devlieghere if (top_reader_sp.get() == reader_sp.get()) 90004de24e6SJonas Devlieghere return; 90104de24e6SJonas Devlieghere } else { 90204de24e6SJonas Devlieghere break; 90304de24e6SJonas Devlieghere } 90404de24e6SJonas Devlieghere } 90504de24e6SJonas Devlieghere } 90604de24e6SJonas Devlieghere } 90704de24e6SJonas Devlieghere 908b9c1b51eSKate Stone bool Debugger::IsTopIOHandler(const lldb::IOHandlerSP &reader_sp) { 9097ce2de2cSJonas Devlieghere return m_io_handler_stack.IsTop(reader_sp); 91044d93782SGreg Clayton } 91130fdc8d8SChris Lattner 912b9c1b51eSKate Stone bool Debugger::CheckTopIOHandlerTypes(IOHandler::Type top_type, 913b9c1b51eSKate Stone IOHandler::Type second_top_type) { 9147ce2de2cSJonas Devlieghere return m_io_handler_stack.CheckTopIOHandlerTypes(top_type, second_top_type); 9156681041dSSean Callanan } 9166681041dSSean Callanan 917b9c1b51eSKate Stone void Debugger::PrintAsync(const char *s, size_t len, bool is_stdout) { 9187ca15ba7SLawrence D'Anna lldb_private::StreamFile &stream = 9197ca15ba7SLawrence D'Anna is_stdout ? GetOutputStream() : GetErrorStream(); 9207ce2de2cSJonas Devlieghere m_io_handler_stack.PrintAsync(&stream, s, len); 9214446487dSPavel Labath } 92244d93782SGreg Clayton 923b9c1b51eSKate Stone ConstString Debugger::GetTopIOHandlerControlSequence(char ch) { 9247ce2de2cSJonas Devlieghere return m_io_handler_stack.GetTopIOHandlerControlSequence(ch); 92530fdc8d8SChris Lattner } 92630fdc8d8SChris Lattner 927b9c1b51eSKate Stone const char *Debugger::GetIOHandlerCommandPrefix() { 9287ce2de2cSJonas Devlieghere return m_io_handler_stack.GetTopIOHandlerCommandPrefix(); 929a487aa4cSKate Stone } 930a487aa4cSKate Stone 931b9c1b51eSKate Stone const char *Debugger::GetIOHandlerHelpPrologue() { 9327ce2de2cSJonas Devlieghere return m_io_handler_stack.GetTopIOHandlerHelpPrologue(); 933a487aa4cSKate Stone } 934a487aa4cSKate Stone 9357ce2de2cSJonas Devlieghere bool Debugger::RemoveIOHandler(const IOHandlerSP &reader_sp) { 9367ce2de2cSJonas Devlieghere return PopIOHandler(reader_sp); 9377ce2de2cSJonas Devlieghere } 9387ce2de2cSJonas Devlieghere 9397ce2de2cSJonas Devlieghere void Debugger::RunIOHandlerAsync(const IOHandlerSP &reader_sp, 9407ce2de2cSJonas Devlieghere bool cancel_top_handler) { 9417ce2de2cSJonas Devlieghere PushIOHandler(reader_sp, cancel_top_handler); 9427ce2de2cSJonas Devlieghere } 9437ce2de2cSJonas Devlieghere 9447ca15ba7SLawrence D'Anna void Debugger::AdoptTopIOHandlerFilesIfInvalid(FileSP &in, StreamFileSP &out, 945b9c1b51eSKate Stone StreamFileSP &err) { 94605097246SAdrian Prantl // Before an IOHandler runs, it must have in/out/err streams. This function 94705097246SAdrian Prantl // is called when one ore more of the streams are nullptr. We use the top 94805097246SAdrian Prantl // input reader's in/out/err streams, or fall back to the debugger file 94905097246SAdrian Prantl // handles, or we fall back onto stdin/stdout/stderr as a last resort. 95044d93782SGreg Clayton 9517ce2de2cSJonas Devlieghere std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex()); 9527ce2de2cSJonas Devlieghere IOHandlerSP top_reader_sp(m_io_handler_stack.Top()); 95344d93782SGreg Clayton // If no STDIN has been set, then set it appropriately 954b07823f3SLawrence D'Anna if (!in || !in->IsValid()) { 95544d93782SGreg Clayton if (top_reader_sp) 9567ca15ba7SLawrence D'Anna in = top_reader_sp->GetInputFileSP(); 95744d93782SGreg Clayton else 9587ca15ba7SLawrence D'Anna in = GetInputFileSP(); 95944d93782SGreg Clayton // If there is nothing, use stdin 96044d93782SGreg Clayton if (!in) 961f913fd6eSLawrence D'Anna in = std::make_shared<NativeFile>(stdin, false); 96244d93782SGreg Clayton } 96344d93782SGreg Clayton // If no STDOUT has been set, then set it appropriately 964b07823f3SLawrence D'Anna if (!out || !out->GetFile().IsValid()) { 96544d93782SGreg Clayton if (top_reader_sp) 9667ca15ba7SLawrence D'Anna out = top_reader_sp->GetOutputStreamFileSP(); 96744d93782SGreg Clayton else 9687ca15ba7SLawrence D'Anna out = GetOutputStreamSP(); 96944d93782SGreg Clayton // If there is nothing, use stdout 97044d93782SGreg Clayton if (!out) 9712f3df613SZachary Turner out = std::make_shared<StreamFile>(stdout, false); 97244d93782SGreg Clayton } 97344d93782SGreg Clayton // If no STDERR has been set, then set it appropriately 974b07823f3SLawrence D'Anna if (!err || !err->GetFile().IsValid()) { 97544d93782SGreg Clayton if (top_reader_sp) 9767ca15ba7SLawrence D'Anna err = top_reader_sp->GetErrorStreamFileSP(); 97744d93782SGreg Clayton else 9787ca15ba7SLawrence D'Anna err = GetErrorStreamSP(); 97944d93782SGreg Clayton // If there is nothing, use stderr 98044d93782SGreg Clayton if (!err) 9817ca15ba7SLawrence D'Anna err = std::make_shared<StreamFile>(stderr, false); 98244d93782SGreg Clayton } 98344d93782SGreg Clayton } 98444d93782SGreg Clayton 985c01783a8SRaphael Isemann void Debugger::PushIOHandler(const IOHandlerSP &reader_sp, 986c01783a8SRaphael Isemann bool cancel_top_handler) { 98730fdc8d8SChris Lattner if (!reader_sp) 98830fdc8d8SChris Lattner return; 989b44880caSCaroline Tice 9907ce2de2cSJonas Devlieghere std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex()); 9914446487dSPavel Labath 9924446487dSPavel Labath // Get the current top input reader... 9937ce2de2cSJonas Devlieghere IOHandlerSP top_reader_sp(m_io_handler_stack.Top()); 994b44880caSCaroline Tice 995b4874f1aSGreg Clayton // Don't push the same IO handler twice... 9964446487dSPavel Labath if (reader_sp == top_reader_sp) 9974446487dSPavel Labath return; 9984446487dSPavel Labath 99944d93782SGreg Clayton // Push our new input reader 10007ce2de2cSJonas Devlieghere m_io_handler_stack.Push(reader_sp); 10014446487dSPavel Labath reader_sp->Activate(); 100244d93782SGreg Clayton 100305097246SAdrian Prantl // Interrupt the top input reader to it will exit its Run() function and let 100405097246SAdrian Prantl // this new input reader take over 1005b9c1b51eSKate Stone if (top_reader_sp) { 100644d93782SGreg Clayton top_reader_sp->Deactivate(); 1007c01783a8SRaphael Isemann if (cancel_top_handler) 10084446487dSPavel Labath top_reader_sp->Cancel(); 100930fdc8d8SChris Lattner } 1010b4874f1aSGreg Clayton } 101130fdc8d8SChris Lattner 1012b9c1b51eSKate Stone bool Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp) { 10134446487dSPavel Labath if (!pop_reader_sp) 10144446487dSPavel Labath return false; 101530fdc8d8SChris Lattner 10167ce2de2cSJonas Devlieghere std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex()); 101744d93782SGreg Clayton 101805097246SAdrian Prantl // The reader on the stop of the stack is done, so let the next read on the 101905097246SAdrian Prantl // stack refresh its prompt and if there is one... 10207ce2de2cSJonas Devlieghere if (m_io_handler_stack.IsEmpty()) 10214446487dSPavel Labath return false; 10224446487dSPavel Labath 10237ce2de2cSJonas Devlieghere IOHandlerSP reader_sp(m_io_handler_stack.Top()); 102430fdc8d8SChris Lattner 10254446487dSPavel Labath if (pop_reader_sp != reader_sp) 10264446487dSPavel Labath return false; 10274446487dSPavel Labath 102844d93782SGreg Clayton reader_sp->Deactivate(); 1029b4874f1aSGreg Clayton reader_sp->Cancel(); 10307ce2de2cSJonas Devlieghere m_io_handler_stack.Pop(); 103130fdc8d8SChris Lattner 10327ce2de2cSJonas Devlieghere reader_sp = m_io_handler_stack.Top(); 103330fdc8d8SChris Lattner if (reader_sp) 103444d93782SGreg Clayton reader_sp->Activate(); 103544d93782SGreg Clayton 103644d93782SGreg Clayton return true; 103730fdc8d8SChris Lattner } 10386611103cSGreg Clayton 1039b9c1b51eSKate Stone StreamSP Debugger::GetAsyncOutputStream() { 10402f3df613SZachary Turner return std::make_shared<StreamAsynchronousIO>(*this, true); 10415b52f0c7SJim Ingham } 10425b52f0c7SJim Ingham 1043b9c1b51eSKate Stone StreamSP Debugger::GetAsyncErrorStream() { 10442f3df613SZachary Turner return std::make_shared<StreamAsynchronousIO>(*this, false); 10455b52f0c7SJim Ingham } 10465b52f0c7SJim Ingham 1047b9c1b51eSKate Stone size_t Debugger::GetNumDebuggers() { 1048b9c1b51eSKate Stone if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 10496c42e063SGreg Clayton std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 10506c42e063SGreg Clayton return g_debugger_list_ptr->size(); 1051061858ceSEnrico Granata } 1052c15f55e2SGreg Clayton return 0; 1053c15f55e2SGreg Clayton } 1054061858ceSEnrico Granata 1055b9c1b51eSKate Stone lldb::DebuggerSP Debugger::GetDebuggerAtIndex(size_t index) { 1056061858ceSEnrico Granata DebuggerSP debugger_sp; 1057061858ceSEnrico Granata 1058b9c1b51eSKate Stone if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 10596c42e063SGreg Clayton std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 10606c42e063SGreg Clayton if (index < g_debugger_list_ptr->size()) 10616c42e063SGreg Clayton debugger_sp = g_debugger_list_ptr->at(index); 1062c15f55e2SGreg Clayton } 1063061858ceSEnrico Granata 1064061858ceSEnrico Granata return debugger_sp; 1065061858ceSEnrico Granata } 1066061858ceSEnrico Granata 1067b9c1b51eSKate Stone DebuggerSP Debugger::FindDebuggerWithID(lldb::user_id_t id) { 10684d122c40SGreg Clayton DebuggerSP debugger_sp; 1069ebc1bb27SCaroline Tice 1070b9c1b51eSKate Stone if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { 10716c42e063SGreg Clayton std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); 10726c42e063SGreg Clayton DebuggerList::iterator pos, end = g_debugger_list_ptr->end(); 1073b9c1b51eSKate Stone for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) { 1074b9c1b51eSKate Stone if ((*pos)->GetID() == id) { 1075ebc1bb27SCaroline Tice debugger_sp = *pos; 1076ebc1bb27SCaroline Tice break; 1077ebc1bb27SCaroline Tice } 1078ebc1bb27SCaroline Tice } 1079c15f55e2SGreg Clayton } 1080ebc1bb27SCaroline Tice return debugger_sp; 1081ebc1bb27SCaroline Tice } 10823df9a8dfSCaroline Tice 1083b9c1b51eSKate Stone bool Debugger::FormatDisassemblerAddress(const FormatEntity::Entry *format, 1084aff1b357SJason Molenda const SymbolContext *sc, 1085aff1b357SJason Molenda const SymbolContext *prev_sc, 1086aff1b357SJason Molenda const ExecutionContext *exe_ctx, 1087b9c1b51eSKate Stone const Address *addr, Stream &s) { 1088554f68d3SGreg Clayton FormatEntity::Entry format_entry; 1089554f68d3SGreg Clayton 1090b9c1b51eSKate Stone if (format == nullptr) { 1091df370550SEugene Zelenko if (exe_ctx != nullptr && exe_ctx->HasTargetScope()) 1092aff1b357SJason Molenda format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat(); 1093b9c1b51eSKate Stone if (format == nullptr) { 1094554f68d3SGreg Clayton FormatEntity::Parse("${addr}: ", format_entry); 1095554f68d3SGreg Clayton format = &format_entry; 1096554f68d3SGreg Clayton } 1097aff1b357SJason Molenda } 1098aff1b357SJason Molenda bool function_changed = false; 1099aff1b357SJason Molenda bool initial_function = false; 1100b9c1b51eSKate Stone if (prev_sc && (prev_sc->function || prev_sc->symbol)) { 1101b9c1b51eSKate Stone if (sc && (sc->function || sc->symbol)) { 1102b9c1b51eSKate Stone if (prev_sc->symbol && sc->symbol) { 1103b9c1b51eSKate Stone if (!sc->symbol->Compare(prev_sc->symbol->GetName(), 1104b9c1b51eSKate Stone prev_sc->symbol->GetType())) { 1105aff1b357SJason Molenda function_changed = true; 1106aff1b357SJason Molenda } 1107b9c1b51eSKate Stone } else if (prev_sc->function && sc->function) { 1108b9c1b51eSKate Stone if (prev_sc->function->GetMangled() != sc->function->GetMangled()) { 1109aff1b357SJason Molenda function_changed = true; 1110aff1b357SJason Molenda } 1111aff1b357SJason Molenda } 1112aff1b357SJason Molenda } 1113aff1b357SJason Molenda } 111405097246SAdrian Prantl // The first context on a list of instructions will have a prev_sc that has 111505097246SAdrian Prantl // no Function or Symbol -- if SymbolContext had an IsValid() method, it 1116aff1b357SJason Molenda // would return false. But we do get a prev_sc pointer. 1117b9c1b51eSKate Stone if ((sc && (sc->function || sc->symbol)) && prev_sc && 1118b9c1b51eSKate Stone (prev_sc->function == nullptr && prev_sc->symbol == nullptr)) { 1119aff1b357SJason Molenda initial_function = true; 1120aff1b357SJason Molenda } 1121b9c1b51eSKate Stone return FormatEntity::Format(*format, s, sc, exe_ctx, addr, nullptr, 1122b9c1b51eSKate Stone function_changed, initial_function); 1123aff1b357SJason Molenda } 1124aff1b357SJason Molenda 1125b9c1b51eSKate Stone void Debugger::SetLoggingCallback(lldb::LogOutputCallback log_callback, 1126b9c1b51eSKate Stone void *baton) { 11274f02b22dSJim Ingham // For simplicity's sake, I am not going to deal with how to close down any 11284f02b22dSJim Ingham // open logging streams, I just redirect everything from here on out to the 11294f02b22dSJim Ingham // callback. 11302f3df613SZachary Turner m_log_callback_stream_sp = 11312f3df613SZachary Turner std::make_shared<StreamCallback>(log_callback, baton); 1132228063cdSJim Ingham } 1133228063cdSJim Ingham 11345e336903SPavel Labath bool Debugger::EnableLog(llvm::StringRef channel, 11355e336903SPavel Labath llvm::ArrayRef<const char *> categories, 11365e336903SPavel Labath llvm::StringRef log_file, uint32_t log_options, 1137775588c0SPavel Labath llvm::raw_ostream &error_stream) { 11385fae71c5SPavel Labath const bool should_close = true; 11395fae71c5SPavel Labath const bool unbuffered = true; 11405fae71c5SPavel Labath 11415fae71c5SPavel Labath std::shared_ptr<llvm::raw_ostream> log_stream_sp; 1142b9c1b51eSKate Stone if (m_log_callback_stream_sp) { 1143228063cdSJim Ingham log_stream_sp = m_log_callback_stream_sp; 1144228063cdSJim Ingham // For now when using the callback mode you always get thread & timestamp. 1145b9c1b51eSKate Stone log_options |= 1146b9c1b51eSKate Stone LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; 11475e336903SPavel Labath } else if (log_file.empty()) { 11485fae71c5SPavel Labath log_stream_sp = std::make_shared<llvm::raw_fd_ostream>( 11497ca15ba7SLawrence D'Anna GetOutputFile().GetDescriptor(), !should_close, unbuffered); 1150b9c1b51eSKate Stone } else { 11515fae71c5SPavel Labath auto pos = m_log_streams.find(log_file); 1152c1b2ccfdSGreg Clayton if (pos != m_log_streams.end()) 1153c1b2ccfdSGreg Clayton log_stream_sp = pos->second.lock(); 1154b9c1b51eSKate Stone if (!log_stream_sp) { 11556b2e6765SJonas Devlieghere File::OpenOptions flags = 11566b2e6765SJonas Devlieghere File::eOpenOptionWrite | File::eOpenOptionCanCreate; 11575fae71c5SPavel Labath if (log_options & LLDB_LOG_OPTION_APPEND) 11586b2e6765SJonas Devlieghere flags |= File::eOpenOptionAppend; 11596b2e6765SJonas Devlieghere else 11606b2e6765SJonas Devlieghere flags |= File::eOpenOptionTruncate; 1161867c347cSRaphael Isemann llvm::Expected<FileUP> file = FileSystem::Instance().Open( 11626b2e6765SJonas Devlieghere FileSpec(log_file), flags, lldb::eFilePermissionsFileDefault, false); 11636b2e6765SJonas Devlieghere if (!file) { 1164867c347cSRaphael Isemann error_stream << "Unable to open log file '" << log_file 1165867c347cSRaphael Isemann << "': " << llvm::toString(file.takeError()) << "\n"; 11665fae71c5SPavel Labath return false; 11675fae71c5SPavel Labath } 11686b2e6765SJonas Devlieghere 11696b2e6765SJonas Devlieghere log_stream_sp = std::make_shared<llvm::raw_fd_ostream>( 11706b2e6765SJonas Devlieghere (*file)->GetDescriptor(), should_close, unbuffered); 1171228063cdSJim Ingham m_log_streams[log_file] = log_stream_sp; 1172228063cdSJim Ingham } 1173228063cdSJim Ingham } 1174df370550SEugene Zelenko assert(log_stream_sp); 1175228063cdSJim Ingham 1176228063cdSJim Ingham if (log_options == 0) 1177b9c1b51eSKate Stone log_options = 1178b9c1b51eSKate Stone LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE; 1179228063cdSJim Ingham 1180b9c1b51eSKate Stone return Log::EnableLogChannel(log_stream_sp, log_options, channel, categories, 1181b9c1b51eSKate Stone error_stream); 1182228063cdSJim Ingham } 1183228063cdSJim Ingham 1184bbf70c04SJonas Devlieghere ScriptInterpreter * 1185bbf70c04SJonas Devlieghere Debugger::GetScriptInterpreter(bool can_create, 1186bbf70c04SJonas Devlieghere llvm::Optional<lldb::ScriptLanguage> language) { 11872b29b432SJonas Devlieghere std::lock_guard<std::recursive_mutex> locker(m_script_interpreter_mutex); 1188bbf70c04SJonas Devlieghere lldb::ScriptLanguage script_language = 1189bbf70c04SJonas Devlieghere language ? *language : GetScriptLanguage(); 11902b29b432SJonas Devlieghere 1191bbf70c04SJonas Devlieghere if (!m_script_interpreters[script_language]) { 11922b29b432SJonas Devlieghere if (!can_create) 11932b29b432SJonas Devlieghere return nullptr; 1194bbf70c04SJonas Devlieghere m_script_interpreters[script_language] = 1195bbf70c04SJonas Devlieghere PluginManager::GetScriptInterpreterForLanguage(script_language, *this); 11962b29b432SJonas Devlieghere } 11972b29b432SJonas Devlieghere 1198bbf70c04SJonas Devlieghere return m_script_interpreters[script_language].get(); 11992b29b432SJonas Devlieghere } 12002b29b432SJonas Devlieghere 1201b9c1b51eSKate Stone SourceManager &Debugger::GetSourceManager() { 1202d5b44036SJonas Devlieghere if (!m_source_manager_up) 1203a8f3ae7cSJonas Devlieghere m_source_manager_up = std::make_unique<SourceManager>(shared_from_this()); 1204d5b44036SJonas Devlieghere return *m_source_manager_up; 12059585fbfcSGreg Clayton } 12069585fbfcSGreg Clayton 120744d93782SGreg Clayton // This function handles events that were broadcast by the process. 1208b9c1b51eSKate Stone void Debugger::HandleBreakpointEvent(const EventSP &event_sp) { 120944d93782SGreg Clayton using namespace lldb; 1210b9c1b51eSKate Stone const uint32_t event_type = 1211b9c1b51eSKate Stone Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent( 1212b9c1b51eSKate Stone event_sp); 121344d93782SGreg Clayton 121444d93782SGreg Clayton // if (event_type & eBreakpointEventTypeAdded 121544d93782SGreg Clayton // || event_type & eBreakpointEventTypeRemoved 121644d93782SGreg Clayton // || event_type & eBreakpointEventTypeEnabled 121744d93782SGreg Clayton // || event_type & eBreakpointEventTypeDisabled 121844d93782SGreg Clayton // || event_type & eBreakpointEventTypeCommandChanged 121944d93782SGreg Clayton // || event_type & eBreakpointEventTypeConditionChanged 122044d93782SGreg Clayton // || event_type & eBreakpointEventTypeIgnoreChanged 122144d93782SGreg Clayton // || event_type & eBreakpointEventTypeLocationsResolved) 122244d93782SGreg Clayton // { 1223b9c1b51eSKate Stone // // Don't do anything about these events, since the breakpoint 1224b9c1b51eSKate Stone // commands already echo these actions. 122544d93782SGreg Clayton // } 122644d93782SGreg Clayton // 1227b9c1b51eSKate Stone if (event_type & eBreakpointEventTypeLocationsAdded) { 1228b9c1b51eSKate Stone uint32_t num_new_locations = 1229b9c1b51eSKate Stone Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent( 1230b9c1b51eSKate Stone event_sp); 1231b9c1b51eSKate Stone if (num_new_locations > 0) { 1232b9c1b51eSKate Stone BreakpointSP breakpoint = 1233b9c1b51eSKate Stone Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp); 12344446487dSPavel Labath StreamSP output_sp(GetAsyncOutputStream()); 1235b9c1b51eSKate Stone if (output_sp) { 123644d93782SGreg Clayton output_sp->Printf("%d location%s added to breakpoint %d\n", 1237b9c1b51eSKate Stone num_new_locations, num_new_locations == 1 ? "" : "s", 123844d93782SGreg Clayton breakpoint->GetID()); 12394446487dSPavel Labath output_sp->Flush(); 124044d93782SGreg Clayton } 124144d93782SGreg Clayton } 124244d93782SGreg Clayton } 124344d93782SGreg Clayton // else if (event_type & eBreakpointEventTypeLocationsRemoved) 124444d93782SGreg Clayton // { 1245b9c1b51eSKate Stone // // These locations just get disabled, not sure it is worth spamming 1246b9c1b51eSKate Stone // folks about this on the command line. 124744d93782SGreg Clayton // } 124844d93782SGreg Clayton // else if (event_type & eBreakpointEventTypeLocationsResolved) 124944d93782SGreg Clayton // { 1250b9c1b51eSKate Stone // // This might be an interesting thing to note, but I'm going to 1251b9c1b51eSKate Stone // leave it quiet for now, it just looked noisy. 125244d93782SGreg Clayton // } 125344d93782SGreg Clayton } 125444d93782SGreg Clayton 1255a9d58436SPavel Labath void Debugger::FlushProcessOutput(Process &process, bool flush_stdout, 1256a9d58436SPavel Labath bool flush_stderr) { 1257a9d58436SPavel Labath const auto &flush = [&](Stream &stream, 1258a9d58436SPavel Labath size_t (Process::*get)(char *, size_t, Status &)) { 125997206d57SZachary Turner Status error; 126044d93782SGreg Clayton size_t len; 1261a9d58436SPavel Labath char buffer[1024]; 1262a9d58436SPavel Labath while ((len = (process.*get)(buffer, sizeof(buffer), error)) > 0) 1263a9d58436SPavel Labath stream.Write(buffer, len); 1264a9d58436SPavel Labath stream.Flush(); 1265a9d58436SPavel Labath }; 126644d93782SGreg Clayton 1267a9d58436SPavel Labath std::lock_guard<std::mutex> guard(m_output_flush_mutex); 1268a9d58436SPavel Labath if (flush_stdout) 1269a9d58436SPavel Labath flush(*GetAsyncOutputStream(), &Process::GetSTDOUT); 1270a9d58436SPavel Labath if (flush_stderr) 1271a9d58436SPavel Labath flush(*GetAsyncErrorStream(), &Process::GetSTDERR); 127244d93782SGreg Clayton } 127344d93782SGreg Clayton 127444d93782SGreg Clayton // This function handles events that were broadcast by the process. 1275b9c1b51eSKate Stone void Debugger::HandleProcessEvent(const EventSP &event_sp) { 127644d93782SGreg Clayton using namespace lldb; 127744d93782SGreg Clayton const uint32_t event_type = event_sp->GetType(); 1278b9c1b51eSKate Stone ProcessSP process_sp = 1279b9c1b51eSKate Stone (event_type == Process::eBroadcastBitStructuredData) 128075930019STodd Fiala ? EventDataStructuredData::GetProcessFromEvent(event_sp.get()) 128175930019STodd Fiala : Process::ProcessEventData::GetProcessFromEvent(event_sp.get()); 128244d93782SGreg Clayton 12834446487dSPavel Labath StreamSP output_stream_sp = GetAsyncOutputStream(); 12844446487dSPavel Labath StreamSP error_stream_sp = GetAsyncErrorStream(); 128544d93782SGreg Clayton const bool gui_enabled = IsForwardingEvents(); 128644d93782SGreg Clayton 1287b9c1b51eSKate Stone if (!gui_enabled) { 1288b4874f1aSGreg Clayton bool pop_process_io_handler = false; 128944d93782SGreg Clayton assert(process_sp); 129044d93782SGreg Clayton 12914446487dSPavel Labath bool state_is_stopped = false; 1292b9c1b51eSKate Stone const bool got_state_changed = 1293b9c1b51eSKate Stone (event_type & Process::eBroadcastBitStateChanged) != 0; 12944446487dSPavel Labath const bool got_stdout = (event_type & Process::eBroadcastBitSTDOUT) != 0; 12954446487dSPavel Labath const bool got_stderr = (event_type & Process::eBroadcastBitSTDERR) != 0; 1296b9c1b51eSKate Stone const bool got_structured_data = 1297b9c1b51eSKate Stone (event_type & Process::eBroadcastBitStructuredData) != 0; 129875930019STodd Fiala 1299b9c1b51eSKate Stone if (got_state_changed) { 1300b9c1b51eSKate Stone StateType event_state = 1301b9c1b51eSKate Stone Process::ProcessEventData::GetStateFromEvent(event_sp.get()); 13024446487dSPavel Labath state_is_stopped = StateIsStoppedState(event_state, false); 130344d93782SGreg Clayton } 1304b4874f1aSGreg Clayton 13054446487dSPavel Labath // Display running state changes first before any STDIO 1306b9c1b51eSKate Stone if (got_state_changed && !state_is_stopped) { 1307b9c1b51eSKate Stone Process::HandleProcessStateChangedEvent(event_sp, output_stream_sp.get(), 1308b9c1b51eSKate Stone pop_process_io_handler); 130944d93782SGreg Clayton } 1310b4874f1aSGreg Clayton 1311a9d58436SPavel Labath // Now display STDOUT and STDERR 1312a9d58436SPavel Labath FlushProcessOutput(*process_sp, got_stdout || got_state_changed, 1313a9d58436SPavel Labath got_stderr || got_state_changed); 1314b4874f1aSGreg Clayton 131575930019STodd Fiala // Give structured data events an opportunity to display. 1316b9c1b51eSKate Stone if (got_structured_data) { 131775930019STodd Fiala StructuredDataPluginSP plugin_sp = 131875930019STodd Fiala EventDataStructuredData::GetPluginFromEvent(event_sp.get()); 1319b9c1b51eSKate Stone if (plugin_sp) { 132075930019STodd Fiala auto structured_data_sp = 132175930019STodd Fiala EventDataStructuredData::GetObjectFromEvent(event_sp.get()); 1322b9c1b51eSKate Stone if (output_stream_sp) { 132375930019STodd Fiala StreamString content_stream; 132497206d57SZachary Turner Status error = 1325b9c1b51eSKate Stone plugin_sp->GetDescription(structured_data_sp, content_stream); 1326b9c1b51eSKate Stone if (error.Success()) { 1327b9c1b51eSKate Stone if (!content_stream.GetString().empty()) { 132875930019STodd Fiala // Add newline. 132975930019STodd Fiala content_stream.PutChar('\n'); 133075930019STodd Fiala content_stream.Flush(); 133175930019STodd Fiala 133275930019STodd Fiala // Print it. 1333771ef6d4SMalcolm Parsons output_stream_sp->PutCString(content_stream.GetString()); 133475930019STodd Fiala } 1335b9c1b51eSKate Stone } else { 133675930019STodd Fiala error_stream_sp->Printf("Failed to print structured " 133775930019STodd Fiala "data with plugin %s: %s", 1338b9c1b51eSKate Stone plugin_sp->GetPluginName().AsCString(), 133975930019STodd Fiala error.AsCString()); 134075930019STodd Fiala } 134175930019STodd Fiala } 134275930019STodd Fiala } 134375930019STodd Fiala } 134475930019STodd Fiala 13454446487dSPavel Labath // Now display any stopped state changes after any STDIO 1346b9c1b51eSKate Stone if (got_state_changed && state_is_stopped) { 1347b9c1b51eSKate Stone Process::HandleProcessStateChangedEvent(event_sp, output_stream_sp.get(), 1348b9c1b51eSKate Stone pop_process_io_handler); 134944d93782SGreg Clayton } 135044d93782SGreg Clayton 13514446487dSPavel Labath output_stream_sp->Flush(); 13524446487dSPavel Labath error_stream_sp->Flush(); 135344d93782SGreg Clayton 1354b4874f1aSGreg Clayton if (pop_process_io_handler) 1355b4874f1aSGreg Clayton process_sp->PopProcessIOHandler(); 1356b4874f1aSGreg Clayton } 1357b4874f1aSGreg Clayton } 1358b4874f1aSGreg Clayton 1359b9c1b51eSKate Stone void Debugger::HandleThreadEvent(const EventSP &event_sp) { 136005097246SAdrian Prantl // At present the only thread event we handle is the Frame Changed event, and 136105097246SAdrian Prantl // all we do for that is just reprint the thread status for that thread. 136244d93782SGreg Clayton using namespace lldb; 136344d93782SGreg Clayton const uint32_t event_type = event_sp->GetType(); 13646a9767c7SJim Ingham const bool stop_format = true; 136544d93782SGreg Clayton if (event_type == Thread::eBroadcastBitStackChanged || 1366b9c1b51eSKate Stone event_type == Thread::eBroadcastBitThreadSelected) { 1367b9c1b51eSKate Stone ThreadSP thread_sp( 1368b9c1b51eSKate Stone Thread::ThreadEventData::GetThreadFromEvent(event_sp.get())); 1369b9c1b51eSKate Stone if (thread_sp) { 13706a9767c7SJim Ingham thread_sp->GetStatus(*GetAsyncOutputStream(), 0, 1, 1, stop_format); 137144d93782SGreg Clayton } 137244d93782SGreg Clayton } 137344d93782SGreg Clayton } 137444d93782SGreg Clayton 1375b9c1b51eSKate Stone bool Debugger::IsForwardingEvents() { return (bool)m_forward_listener_sp; } 137644d93782SGreg Clayton 1377b9c1b51eSKate Stone void Debugger::EnableForwardEvents(const ListenerSP &listener_sp) { 137844d93782SGreg Clayton m_forward_listener_sp = listener_sp; 137944d93782SGreg Clayton } 138044d93782SGreg Clayton 1381b9c1b51eSKate Stone void Debugger::CancelForwardEvents(const ListenerSP &listener_sp) { 138244d93782SGreg Clayton m_forward_listener_sp.reset(); 138344d93782SGreg Clayton } 138444d93782SGreg Clayton 1385b9c1b51eSKate Stone void Debugger::DefaultEventHandler() { 1386583bbb1dSJim Ingham ListenerSP listener_sp(GetListener()); 138744d93782SGreg Clayton ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass()); 138844d93782SGreg Clayton ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass()); 138944d93782SGreg Clayton ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass()); 139044d93782SGreg Clayton BroadcastEventSpec target_event_spec(broadcaster_class_target, 139144d93782SGreg Clayton Target::eBroadcastBitBreakpointChanged); 139244d93782SGreg Clayton 1393b9c1b51eSKate Stone BroadcastEventSpec process_event_spec( 1394b9c1b51eSKate Stone broadcaster_class_process, 1395b9c1b51eSKate Stone Process::eBroadcastBitStateChanged | Process::eBroadcastBitSTDOUT | 1396b9c1b51eSKate Stone Process::eBroadcastBitSTDERR | Process::eBroadcastBitStructuredData); 139744d93782SGreg Clayton 139844d93782SGreg Clayton BroadcastEventSpec thread_event_spec(broadcaster_class_thread, 139944d93782SGreg Clayton Thread::eBroadcastBitStackChanged | 140044d93782SGreg Clayton Thread::eBroadcastBitThreadSelected); 140144d93782SGreg Clayton 1402b9c1b51eSKate Stone listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp, 1403b9c1b51eSKate Stone target_event_spec); 1404b9c1b51eSKate Stone listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp, 1405b9c1b51eSKate Stone process_event_spec); 1406b9c1b51eSKate Stone listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp, 1407b9c1b51eSKate Stone thread_event_spec); 1408b9c1b51eSKate Stone listener_sp->StartListeningForEvents( 1409d5b44036SJonas Devlieghere m_command_interpreter_up.get(), 141044d93782SGreg Clayton CommandInterpreter::eBroadcastBitQuitCommandReceived | 141144d93782SGreg Clayton CommandInterpreter::eBroadcastBitAsynchronousOutputData | 141244d93782SGreg Clayton CommandInterpreter::eBroadcastBitAsynchronousErrorData); 141344d93782SGreg Clayton 141405097246SAdrian Prantl // Let the thread that spawned us know that we have started up and that we 141505097246SAdrian Prantl // are now listening to all required events so no events get missed 1416afa91e33SGreg Clayton m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening); 1417afa91e33SGreg Clayton 141844d93782SGreg Clayton bool done = false; 1419b9c1b51eSKate Stone while (!done) { 142044d93782SGreg Clayton EventSP event_sp; 1421d35031e1SPavel Labath if (listener_sp->GetEvent(event_sp, llvm::None)) { 1422b9c1b51eSKate Stone if (event_sp) { 142344d93782SGreg Clayton Broadcaster *broadcaster = event_sp->GetBroadcaster(); 1424b9c1b51eSKate Stone if (broadcaster) { 142544d93782SGreg Clayton uint32_t event_type = event_sp->GetType(); 142644d93782SGreg Clayton ConstString broadcaster_class(broadcaster->GetBroadcasterClass()); 1427b9c1b51eSKate Stone if (broadcaster_class == broadcaster_class_process) { 142844d93782SGreg Clayton HandleProcessEvent(event_sp); 1429b9c1b51eSKate Stone } else if (broadcaster_class == broadcaster_class_target) { 1430b9c1b51eSKate Stone if (Breakpoint::BreakpointEventData::GetEventDataFromEvent( 1431b9c1b51eSKate Stone event_sp.get())) { 143244d93782SGreg Clayton HandleBreakpointEvent(event_sp); 143344d93782SGreg Clayton } 1434b9c1b51eSKate Stone } else if (broadcaster_class == broadcaster_class_thread) { 143544d93782SGreg Clayton HandleThreadEvent(event_sp); 1436d5b44036SJonas Devlieghere } else if (broadcaster == m_command_interpreter_up.get()) { 1437b9c1b51eSKate Stone if (event_type & 1438b9c1b51eSKate Stone CommandInterpreter::eBroadcastBitQuitCommandReceived) { 143944d93782SGreg Clayton done = true; 1440b9c1b51eSKate Stone } else if (event_type & 1441b9c1b51eSKate Stone CommandInterpreter::eBroadcastBitAsynchronousErrorData) { 144265fdb342SRaphael Isemann const char *data = static_cast<const char *>( 1443b9c1b51eSKate Stone EventDataBytes::GetBytesFromEvent(event_sp.get())); 1444b9c1b51eSKate Stone if (data && data[0]) { 14454446487dSPavel Labath StreamSP error_sp(GetAsyncErrorStream()); 1446b9c1b51eSKate Stone if (error_sp) { 144744d93782SGreg Clayton error_sp->PutCString(data); 144844d93782SGreg Clayton error_sp->Flush(); 144944d93782SGreg Clayton } 145044d93782SGreg Clayton } 1451b9c1b51eSKate Stone } else if (event_type & CommandInterpreter:: 1452b9c1b51eSKate Stone eBroadcastBitAsynchronousOutputData) { 145365fdb342SRaphael Isemann const char *data = static_cast<const char *>( 1454b9c1b51eSKate Stone EventDataBytes::GetBytesFromEvent(event_sp.get())); 1455b9c1b51eSKate Stone if (data && data[0]) { 14564446487dSPavel Labath StreamSP output_sp(GetAsyncOutputStream()); 1457b9c1b51eSKate Stone if (output_sp) { 145844d93782SGreg Clayton output_sp->PutCString(data); 145944d93782SGreg Clayton output_sp->Flush(); 146044d93782SGreg Clayton } 146144d93782SGreg Clayton } 146244d93782SGreg Clayton } 146344d93782SGreg Clayton } 146444d93782SGreg Clayton } 146544d93782SGreg Clayton 146644d93782SGreg Clayton if (m_forward_listener_sp) 146744d93782SGreg Clayton m_forward_listener_sp->AddEvent(event_sp); 146844d93782SGreg Clayton } 146944d93782SGreg Clayton } 147044d93782SGreg Clayton } 147144d93782SGreg Clayton } 147244d93782SGreg Clayton 1473b9c1b51eSKate Stone lldb::thread_result_t Debugger::EventHandlerThread(lldb::thread_arg_t arg) { 147444d93782SGreg Clayton ((Debugger *)arg)->DefaultEventHandler(); 147585200645SKonrad Kleine return {}; 147644d93782SGreg Clayton } 147744d93782SGreg Clayton 1478b9c1b51eSKate Stone bool Debugger::StartEventHandlerThread() { 1479b9c1b51eSKate Stone if (!m_event_handler_thread.IsJoinable()) { 148005097246SAdrian Prantl // We must synchronize with the DefaultEventHandler() thread to ensure it 148105097246SAdrian Prantl // is up and running and listening to events before we return from this 148205097246SAdrian Prantl // function. We do this by listening to events for the 1483afa91e33SGreg Clayton // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster 14841a728f66STatyana Krasnukha ConstString full_name("lldb.debugger.event-handler"); 14851a728f66STatyana Krasnukha ListenerSP listener_sp(Listener::MakeListener(full_name.AsCString())); 1486b9c1b51eSKate Stone listener_sp->StartListeningForEvents(&m_sync_broadcaster, 1487b9c1b51eSKate Stone eBroadcastBitEventThreadIsListening); 1488afa91e33SGreg Clayton 1489642bc15dSRaphael Isemann llvm::StringRef thread_name = 1490e063ecccSJonas Devlieghere full_name.GetLength() < llvm::get_max_thread_name_length() 1491642bc15dSRaphael Isemann ? full_name.GetStringRef() 1492e063ecccSJonas Devlieghere : "dbg.evt-handler"; 14931a728f66STatyana Krasnukha 14947c2896a2SZachary Turner // Use larger 8MB stack for this thread 1495f39c2e18SJonas Devlieghere llvm::Expected<HostThread> event_handler_thread = 1496f39c2e18SJonas Devlieghere ThreadLauncher::LaunchThread(thread_name, EventHandlerThread, this, 1497f39c2e18SJonas Devlieghere g_debugger_event_thread_stack_bytes); 1498f39c2e18SJonas Devlieghere 1499f39c2e18SJonas Devlieghere if (event_handler_thread) { 1500f39c2e18SJonas Devlieghere m_event_handler_thread = *event_handler_thread; 1501f39c2e18SJonas Devlieghere } else { 1502f39c2e18SJonas Devlieghere LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST), 1503f39c2e18SJonas Devlieghere "failed to launch host thread: {}", 1504f39c2e18SJonas Devlieghere llvm::toString(event_handler_thread.takeError())); 1505f39c2e18SJonas Devlieghere } 1506afa91e33SGreg Clayton 150705097246SAdrian Prantl // Make sure DefaultEventHandler() is running and listening to events 150805097246SAdrian Prantl // before we return from this function. We are only listening for events of 150905097246SAdrian Prantl // type eBroadcastBitEventThreadIsListening so we don't need to check the 151005097246SAdrian Prantl // event, we just need to wait an infinite amount of time for it (nullptr 151105097246SAdrian Prantl // timeout as the first parameter) 1512afa91e33SGreg Clayton lldb::EventSP event_sp; 1513d35031e1SPavel Labath listener_sp->GetEvent(event_sp, llvm::None); 1514807b6b32SGreg Clayton } 1515acee96aeSZachary Turner return m_event_handler_thread.IsJoinable(); 151644d93782SGreg Clayton } 151744d93782SGreg Clayton 1518b9c1b51eSKate Stone void Debugger::StopEventHandlerThread() { 1519b9c1b51eSKate Stone if (m_event_handler_thread.IsJoinable()) { 1520b9c1b51eSKate Stone GetCommandInterpreter().BroadcastEvent( 1521b9c1b51eSKate Stone CommandInterpreter::eBroadcastBitQuitCommandReceived); 152239de3110SZachary Turner m_event_handler_thread.Join(nullptr); 152344d93782SGreg Clayton } 152444d93782SGreg Clayton } 152544d93782SGreg Clayton 1526b9c1b51eSKate Stone lldb::thread_result_t Debugger::IOHandlerThread(lldb::thread_arg_t arg) { 152744d93782SGreg Clayton Debugger *debugger = (Debugger *)arg; 15282671df9bSJonas Devlieghere debugger->RunIOHandlers(); 152944d93782SGreg Clayton debugger->StopEventHandlerThread(); 153085200645SKonrad Kleine return {}; 153144d93782SGreg Clayton } 153244d93782SGreg Clayton 1533b9c1b51eSKate Stone bool Debugger::HasIOHandlerThread() { return m_io_handler_thread.IsJoinable(); } 15346681041dSSean Callanan 1535b9c1b51eSKate Stone bool Debugger::StartIOHandlerThread() { 1536f39c2e18SJonas Devlieghere if (!m_io_handler_thread.IsJoinable()) { 1537f39c2e18SJonas Devlieghere llvm::Expected<HostThread> io_handler_thread = ThreadLauncher::LaunchThread( 1538f39c2e18SJonas Devlieghere "lldb.debugger.io-handler", IOHandlerThread, this, 1539807b6b32SGreg Clayton 8 * 1024 * 1024); // Use larger 8MB stack for this thread 1540f39c2e18SJonas Devlieghere if (io_handler_thread) { 1541f39c2e18SJonas Devlieghere m_io_handler_thread = *io_handler_thread; 1542f39c2e18SJonas Devlieghere } else { 1543f39c2e18SJonas Devlieghere LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST), 1544f39c2e18SJonas Devlieghere "failed to launch host thread: {}", 1545f39c2e18SJonas Devlieghere llvm::toString(io_handler_thread.takeError())); 1546f39c2e18SJonas Devlieghere } 1547f39c2e18SJonas Devlieghere } 1548acee96aeSZachary Turner return m_io_handler_thread.IsJoinable(); 154944d93782SGreg Clayton } 155044d93782SGreg Clayton 1551b9c1b51eSKate Stone void Debugger::StopIOHandlerThread() { 1552b9c1b51eSKate Stone if (m_io_handler_thread.IsJoinable()) { 15537ca15ba7SLawrence D'Anna GetInputFile().Close(); 155439de3110SZachary Turner m_io_handler_thread.Join(nullptr); 155544d93782SGreg Clayton } 155644d93782SGreg Clayton } 155744d93782SGreg Clayton 1558b9c1b51eSKate Stone void Debugger::JoinIOHandlerThread() { 1559b9c1b51eSKate Stone if (HasIOHandlerThread()) { 15606681041dSSean Callanan thread_result_t result; 15616681041dSSean Callanan m_io_handler_thread.Join(&result); 15626681041dSSean Callanan m_io_handler_thread = LLDB_INVALID_HOST_THREAD; 15636681041dSSean Callanan } 15646681041dSSean Callanan } 15656681041dSSean Callanan 1566b2fa3b92SJonas Devlieghere Target &Debugger::GetSelectedOrDummyTarget(bool prefer_dummy) { 1567b9c1b51eSKate Stone if (!prefer_dummy) { 1568b2fa3b92SJonas Devlieghere if (TargetSP target = m_target_list.GetSelectedTarget()) 1569b2fa3b92SJonas Devlieghere return *target; 157033df7cd3SJim Ingham } 1571893c932aSJim Ingham return GetDummyTarget(); 1572893c932aSJim Ingham } 157344d93782SGreg Clayton 157497206d57SZachary Turner Status Debugger::RunREPL(LanguageType language, const char *repl_options) { 157597206d57SZachary Turner Status err; 15763e7e915dSSean Callanan FileSpec repl_executable; 15773e7e915dSSean Callanan 1578b9c1b51eSKate Stone if (language == eLanguageTypeUnknown) { 1579aa97a89dSAdrian Prantl LanguageSet repl_languages = Language::GetLanguagesSupportingREPLs(); 158097f84e87SSean Callanan 1581aa97a89dSAdrian Prantl if (auto single_lang = repl_languages.GetSingularLanguage()) { 1582aa97a89dSAdrian Prantl language = *single_lang; 1583aa97a89dSAdrian Prantl } else if (repl_languages.Empty()) { 1584b9c1b51eSKate Stone err.SetErrorStringWithFormat( 1585b9c1b51eSKate Stone "LLDB isn't configured with REPL support for any languages."); 158697f84e87SSean Callanan return err; 1587b9c1b51eSKate Stone } else { 1588b9c1b51eSKate Stone err.SetErrorStringWithFormat( 1589b9c1b51eSKate Stone "Multiple possible REPL languages. Please specify a language."); 159097f84e87SSean Callanan return err; 159197f84e87SSean Callanan } 159297f84e87SSean Callanan } 159397f84e87SSean Callanan 1594b9c1b51eSKate Stone Target *const target = 1595b9c1b51eSKate Stone nullptr; // passing in an empty target means the REPL must create one 15963e7e915dSSean Callanan 15973b682de6SSean Callanan REPLSP repl_sp(REPL::Create(err, language, this, target, repl_options)); 15983e7e915dSSean Callanan 1599b9c1b51eSKate Stone if (!err.Success()) { 16003e7e915dSSean Callanan return err; 16013e7e915dSSean Callanan } 16023e7e915dSSean Callanan 1603b9c1b51eSKate Stone if (!repl_sp) { 1604b9c1b51eSKate Stone err.SetErrorStringWithFormat("couldn't find a REPL for %s", 1605b9c1b51eSKate Stone Language::GetNameForLanguageType(language)); 16063e7e915dSSean Callanan return err; 16073e7e915dSSean Callanan } 16083e7e915dSSean Callanan 16093e7e915dSSean Callanan repl_sp->SetCompilerOptions(repl_options); 16103e7e915dSSean Callanan repl_sp->RunLoop(); 16113e7e915dSSean Callanan 16123e7e915dSSean Callanan return err; 16133e7e915dSSean Callanan } 1614