blob: 3941d82d47b03d901c9ad085cadfcacdca194d04 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- Debugger.cpp --------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Daniel Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Enrico Granata21dfcd92012-09-28 23:57:51 +000012#include "lldb/API/SBDebugger.h"
13
Greg Clayton4a33d312011-06-23 17:59:56 +000014#include "lldb/Core/Debugger.h"
15
16#include <map>
17
Enrico Granata4becb372011-06-29 22:27:15 +000018#include "clang/AST/DeclCXX.h"
19#include "clang/AST/Type.h"
20
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021#include "lldb/lldb-private.h"
22#include "lldb/Core/ConnectionFileDescriptor.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023#include "lldb/Core/InputReader.h"
Greg Clayton1f746072012-08-29 21:13:06 +000024#include "lldb/Core/Module.h"
Greg Claytone8cd0c92012-10-19 18:02:49 +000025#include "lldb/Core/PluginManager.h"
Greg Clayton7349bd92011-05-09 20:18:18 +000026#include "lldb/Core/RegisterValue.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027#include "lldb/Core/State.h"
Jim Ingham5b52f0c2011-06-02 23:58:26 +000028#include "lldb/Core/StreamAsynchronousIO.h"
Jim Ingham228063c2012-02-21 02:23:08 +000029#include "lldb/Core/StreamCallback.h"
Greg Clayton1b654882010-09-19 02:33:57 +000030#include "lldb/Core/StreamString.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031#include "lldb/Core/Timer.h"
Enrico Granata4becb372011-06-29 22:27:15 +000032#include "lldb/Core/ValueObject.h"
Greg Clayton6d3dbf52012-01-13 08:39:16 +000033#include "lldb/Core/ValueObjectVariable.h"
Enrico Granata5548cb52013-01-28 23:47:25 +000034#include "lldb/DataFormatters/DataVisualization.h"
35#include "lldb/DataFormatters/FormatManager.h"
Enrico Granata21dfcd92012-09-28 23:57:51 +000036#include "lldb/Host/DynamicLibrary.h"
Greg Claytona3406612011-02-07 23:24:47 +000037#include "lldb/Host/Terminal.h"
Greg Clayton66111032010-06-23 01:19:29 +000038#include "lldb/Interpreter/CommandInterpreter.h"
Greg Clayton67cc0632012-08-22 17:17:09 +000039#include "lldb/Interpreter/OptionValueSInt64.h"
40#include "lldb/Interpreter/OptionValueString.h"
Greg Clayton1f746072012-08-29 21:13:06 +000041#include "lldb/Symbol/ClangASTContext.h"
42#include "lldb/Symbol/CompileUnit.h"
43#include "lldb/Symbol/Function.h"
44#include "lldb/Symbol/Symbol.h"
Greg Clayton6d3dbf52012-01-13 08:39:16 +000045#include "lldb/Symbol/VariableList.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046#include "lldb/Target/TargetList.h"
47#include "lldb/Target/Process.h"
Greg Clayton1b654882010-09-19 02:33:57 +000048#include "lldb/Target/RegisterContext.h"
49#include "lldb/Target/StopInfo.h"
Enrico Granata84a53df2013-05-20 22:29:23 +000050#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051#include "lldb/Target/Thread.h"
Greg Clayton5a314712011-10-14 07:41:33 +000052#include "lldb/Utility/AnsiTerminal.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000053
54using namespace lldb;
55using namespace lldb_private;
56
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057
Greg Clayton1b654882010-09-19 02:33:57 +000058static uint32_t g_shared_debugger_refcount = 0;
Caroline Ticeebc1bb22010-06-30 16:22:25 +000059static lldb::user_id_t g_unique_id = 1;
60
Greg Clayton1b654882010-09-19 02:33:57 +000061#pragma mark Static Functions
62
63static Mutex &
64GetDebuggerListMutex ()
65{
66 static Mutex g_mutex(Mutex::eMutexTypeRecursive);
67 return g_mutex;
68}
69
70typedef std::vector<DebuggerSP> DebuggerList;
71
72static DebuggerList &
73GetDebuggerList()
74{
75 // hide the static debugger list inside a singleton accessor to avoid
76 // global init contructors
77 static DebuggerList g_list;
78 return g_list;
79}
Greg Claytone372b982011-11-21 21:44:34 +000080
81OptionEnumValueElement
Greg Clayton67cc0632012-08-22 17:17:09 +000082g_show_disassembly_enum_values[] =
Greg Claytone372b982011-11-21 21:44:34 +000083{
Greg Clayton67cc0632012-08-22 17:17:09 +000084 { Debugger::eStopDisassemblyTypeNever, "never", "Never show disassembly when displaying a stop context."},
85 { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."},
86 { Debugger::eStopDisassemblyTypeAlways, "always", "Always show disassembly when displaying a stop context."},
Greg Claytone372b982011-11-21 21:44:34 +000087 { 0, NULL, NULL }
88};
89
Greg Clayton67cc0632012-08-22 17:17:09 +000090OptionEnumValueElement
91g_language_enumerators[] =
92{
93 { eScriptLanguageNone, "none", "Disable scripting languages."},
94 { eScriptLanguagePython, "python", "Select python as the default scripting language."},
95 { eScriptLanguageDefault, "default", "Select the lldb default as the default scripting language."},
Greg Claytona12993c2012-09-13 23:03:20 +000096 { 0, NULL, NULL }
Greg Clayton67cc0632012-08-22 17:17:09 +000097};
Greg Claytone372b982011-11-21 21:44:34 +000098
Greg Clayton67cc0632012-08-22 17:17:09 +000099#define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}"
100#define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
101
Michael Sartain0769b2b2013-07-30 16:44:36 +0000102#define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id%tid}"\
Greg Clayton67cc0632012-08-22 17:17:09 +0000103 "{, ${frame.pc}}"\
104 MODULE_WITH_FUNC\
105 FILE_AND_LINE\
Michael Sartain0769b2b2013-07-30 16:44:36 +0000106 "{, name = '${thread.name}'}"\
107 "{, queue = '${thread.queue}'}"\
Greg Clayton67cc0632012-08-22 17:17:09 +0000108 "{, stop reason = ${thread.stop-reason}}"\
109 "{\\nReturn value: ${thread.return-value}}"\
110 "\\n"
111
112#define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
113 MODULE_WITH_FUNC\
114 FILE_AND_LINE\
115 "\\n"
116
117
118
Greg Clayton754a9362012-08-23 00:22:02 +0000119static PropertyDefinition
120g_properties[] =
Greg Clayton67cc0632012-08-22 17:17:09 +0000121{
122{ "auto-confirm", OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." },
123{ "frame-format", OptionValue::eTypeString , true, 0 , DEFAULT_FRAME_FORMAT, NULL, "The default frame format string to use when displaying stack frame information for threads." },
124{ "notify-void", OptionValue::eTypeBoolean, true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." },
Greg Clayton4c054102012-09-01 00:38:36 +0000125{ "prompt", OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." },
Greg Clayton67cc0632012-08-22 17:17:09 +0000126{ "script-lang", OptionValue::eTypeEnum , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." },
127{ "stop-disassembly-count", OptionValue::eTypeSInt64 , true, 4 , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." },
128{ "stop-disassembly-display", OptionValue::eTypeEnum , true, Debugger::eStopDisassemblyTypeNoSource, NULL, g_show_disassembly_enum_values, "Control when to display disassembly when displaying a stopped context." },
129{ "stop-line-count-after", OptionValue::eTypeSInt64 , true, 3 , NULL, NULL, "The number of sources lines to display that come after the current source line when displaying a stopped context." },
130{ "stop-line-count-before", OptionValue::eTypeSInt64 , true, 3 , NULL, NULL, "The number of sources lines to display that come before the current source line when displaying a stopped context." },
131{ "term-width", OptionValue::eTypeSInt64 , true, 80 , NULL, NULL, "The maximum number of columns to use for displaying text." },
132{ "thread-format", OptionValue::eTypeString , true, 0 , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." },
133{ "use-external-editor", OptionValue::eTypeBoolean, true, false, NULL, NULL, "Whether to use an external editor or not." },
Michael Sartainc3ce7f272013-05-23 20:47:45 +0000134{ "use-color", OptionValue::eTypeBoolean, true, true , NULL, NULL, "Whether to use Ansi color codes or not." },
Enrico Granata90a8db32013-10-31 21:01:07 +0000135{ "auto-one-line-summaries", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, LLDB will automatically display small structs in one-liner format (default: true)." },
Greg Claytone8cd0c92012-10-19 18:02:49 +0000136
137 { NULL, OptionValue::eTypeInvalid, true, 0 , NULL, NULL, NULL }
Greg Clayton67cc0632012-08-22 17:17:09 +0000138};
139
140enum
141{
142 ePropertyAutoConfirm = 0,
143 ePropertyFrameFormat,
144 ePropertyNotiftVoid,
145 ePropertyPrompt,
146 ePropertyScriptLanguage,
147 ePropertyStopDisassemblyCount,
148 ePropertyStopDisassemblyDisplay,
149 ePropertyStopLineCountAfter,
150 ePropertyStopLineCountBefore,
151 ePropertyTerminalWidth,
152 ePropertyThreadFormat,
Michael Sartainc3ce7f272013-05-23 20:47:45 +0000153 ePropertyUseExternalEditor,
154 ePropertyUseColor,
Enrico Granata90a8db32013-10-31 21:01:07 +0000155 ePropertyAutoOneLineSummaries
Greg Clayton67cc0632012-08-22 17:17:09 +0000156};
157
158//
159//const char *
160//Debugger::GetFrameFormat() const
161//{
162// return m_properties_sp->GetFrameFormat();
163//}
164//const char *
165//Debugger::GetThreadFormat() const
166//{
167// return m_properties_sp->GetThreadFormat();
168//}
169//
Greg Clayton4c054102012-09-01 00:38:36 +0000170
171
172Error
173Debugger::SetPropertyValue (const ExecutionContext *exe_ctx,
174 VarSetOperationType op,
175 const char *property_path,
176 const char *value)
177{
Enrico Granata84a53df2013-05-20 22:29:23 +0000178 bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0;
179 TargetSP target_sp;
Enrico Granata397ddd52013-05-21 20:13:34 +0000180 LoadScriptFromSymFile load_script_old_value;
Enrico Granata84a53df2013-05-20 22:29:23 +0000181 if (is_load_script && exe_ctx->GetTargetSP())
182 {
183 target_sp = exe_ctx->GetTargetSP();
184 load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
185 }
Greg Clayton4c054102012-09-01 00:38:36 +0000186 Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value));
187 if (error.Success())
188 {
Enrico Granata84a53df2013-05-20 22:29:23 +0000189 // FIXME it would be nice to have "on-change" callbacks for properties
Greg Clayton4c054102012-09-01 00:38:36 +0000190 if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0)
191 {
192 const char *new_prompt = GetPrompt();
Michael Sartainc3ce7f272013-05-23 20:47:45 +0000193 std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
194 if (str.length())
195 new_prompt = str.c_str();
Greg Clayton4c054102012-09-01 00:38:36 +0000196 EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));
197 GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
198 }
Michael Sartainc3ce7f272013-05-23 20:47:45 +0000199 else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0)
200 {
201 // use-color changed. Ping the prompt so it can reset the ansi terminal codes.
202 SetPrompt (GetPrompt());
203 }
Enrico Granata397ddd52013-05-21 20:13:34 +0000204 else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn)
Enrico Granata84a53df2013-05-20 22:29:23 +0000205 {
Enrico Granata397ddd52013-05-21 20:13:34 +0000206 if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue)
Enrico Granata84a53df2013-05-20 22:29:23 +0000207 {
208 std::list<Error> errors;
Enrico Granata97303392013-05-21 00:00:30 +0000209 StreamString feedback_stream;
210 if (!target_sp->LoadScriptingResources(errors,&feedback_stream))
Enrico Granata84a53df2013-05-20 22:29:23 +0000211 {
212 for (auto error : errors)
213 {
Enrico Granata97303392013-05-21 00:00:30 +0000214 GetErrorStream().Printf("%s\n",error.AsCString());
Enrico Granata84a53df2013-05-20 22:29:23 +0000215 }
Enrico Granata97303392013-05-21 00:00:30 +0000216 if (feedback_stream.GetSize())
217 GetErrorStream().Printf("%s",feedback_stream.GetData());
Enrico Granata84a53df2013-05-20 22:29:23 +0000218 }
219 }
220 }
Greg Clayton4c054102012-09-01 00:38:36 +0000221 }
222 return error;
223}
224
Greg Clayton67cc0632012-08-22 17:17:09 +0000225bool
226Debugger::GetAutoConfirm () const
227{
228 const uint32_t idx = ePropertyAutoConfirm;
Greg Clayton754a9362012-08-23 00:22:02 +0000229 return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
Greg Clayton67cc0632012-08-22 17:17:09 +0000230}
231
232const char *
233Debugger::GetFrameFormat() const
234{
235 const uint32_t idx = ePropertyFrameFormat;
Greg Clayton754a9362012-08-23 00:22:02 +0000236 return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
Greg Clayton67cc0632012-08-22 17:17:09 +0000237}
238
239bool
240Debugger::GetNotifyVoid () const
241{
242 const uint32_t idx = ePropertyNotiftVoid;
Greg Clayton754a9362012-08-23 00:22:02 +0000243 return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
Greg Clayton67cc0632012-08-22 17:17:09 +0000244}
245
246const char *
247Debugger::GetPrompt() const
248{
249 const uint32_t idx = ePropertyPrompt;
Greg Clayton754a9362012-08-23 00:22:02 +0000250 return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
Greg Clayton67cc0632012-08-22 17:17:09 +0000251}
252
253void
254Debugger::SetPrompt(const char *p)
255{
256 const uint32_t idx = ePropertyPrompt;
257 m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p);
258 const char *new_prompt = GetPrompt();
Michael Sartainc3ce7f272013-05-23 20:47:45 +0000259 std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
260 if (str.length())
261 new_prompt = str.c_str();
Greg Clayton67cc0632012-08-22 17:17:09 +0000262 EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));;
263 GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
264}
265
266const char *
267Debugger::GetThreadFormat() const
268{
269 const uint32_t idx = ePropertyThreadFormat;
Greg Clayton754a9362012-08-23 00:22:02 +0000270 return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
Greg Clayton67cc0632012-08-22 17:17:09 +0000271}
272
273lldb::ScriptLanguage
274Debugger::GetScriptLanguage() const
275{
276 const uint32_t idx = ePropertyScriptLanguage;
Greg Clayton754a9362012-08-23 00:22:02 +0000277 return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
Greg Clayton67cc0632012-08-22 17:17:09 +0000278}
279
280bool
281Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang)
282{
283 const uint32_t idx = ePropertyScriptLanguage;
284 return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang);
285}
286
287uint32_t
288Debugger::GetTerminalWidth () const
289{
290 const uint32_t idx = ePropertyTerminalWidth;
Greg Clayton754a9362012-08-23 00:22:02 +0000291 return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
Greg Clayton67cc0632012-08-22 17:17:09 +0000292}
293
294bool
295Debugger::SetTerminalWidth (uint32_t term_width)
296{
297 const uint32_t idx = ePropertyTerminalWidth;
298 return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width);
299}
300
301bool
302Debugger::GetUseExternalEditor () const
303{
304 const uint32_t idx = ePropertyUseExternalEditor;
Greg Clayton754a9362012-08-23 00:22:02 +0000305 return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
Greg Clayton67cc0632012-08-22 17:17:09 +0000306}
307
308bool
309Debugger::SetUseExternalEditor (bool b)
310{
311 const uint32_t idx = ePropertyUseExternalEditor;
312 return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
313}
314
Michael Sartainc3ce7f272013-05-23 20:47:45 +0000315bool
316Debugger::GetUseColor () const
317{
318 const uint32_t idx = ePropertyUseColor;
319 return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
320}
321
322bool
323Debugger::SetUseColor (bool b)
324{
325 const uint32_t idx = ePropertyUseColor;
326 bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
327 SetPrompt (GetPrompt());
328 return ret;
329}
330
Greg Clayton67cc0632012-08-22 17:17:09 +0000331uint32_t
332Debugger::GetStopSourceLineCount (bool before) const
333{
334 const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
Greg Clayton754a9362012-08-23 00:22:02 +0000335 return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
Greg Clayton67cc0632012-08-22 17:17:09 +0000336}
337
338Debugger::StopDisassemblyType
339Debugger::GetStopDisassemblyDisplay () const
340{
341 const uint32_t idx = ePropertyStopDisassemblyDisplay;
Greg Clayton754a9362012-08-23 00:22:02 +0000342 return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
Greg Clayton67cc0632012-08-22 17:17:09 +0000343}
344
345uint32_t
346Debugger::GetDisassemblyLineCount () const
347{
348 const uint32_t idx = ePropertyStopDisassemblyCount;
Greg Clayton754a9362012-08-23 00:22:02 +0000349 return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
Greg Clayton67cc0632012-08-22 17:17:09 +0000350}
Greg Claytone372b982011-11-21 21:44:34 +0000351
Enrico Granata553fad52013-10-25 23:09:40 +0000352bool
Enrico Granata90a8db32013-10-31 21:01:07 +0000353Debugger::GetAutoOneLineSummaries () const
Enrico Granata553fad52013-10-25 23:09:40 +0000354{
Enrico Granata90a8db32013-10-31 21:01:07 +0000355 const uint32_t idx = ePropertyAutoOneLineSummaries;
Enrico Granata553fad52013-10-25 23:09:40 +0000356 return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
357
358}
359
Greg Clayton1b654882010-09-19 02:33:57 +0000360#pragma mark Debugger
361
Greg Clayton67cc0632012-08-22 17:17:09 +0000362//const DebuggerPropertiesSP &
363//Debugger::GetSettings() const
364//{
365// return m_properties_sp;
366//}
367//
Greg Clayton99d0faf2010-11-18 23:32:35 +0000368
Caroline Tice2f88aad2011-01-14 00:29:16 +0000369int
370Debugger::TestDebuggerRefCount ()
371{
372 return g_shared_debugger_refcount;
373}
374
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000375void
376Debugger::Initialize ()
377{
Greg Claytonc15f55e2012-03-30 20:53:46 +0000378 if (g_shared_debugger_refcount++ == 0)
Greg Claytondbe54502010-11-19 03:46:01 +0000379 lldb_private::Initialize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000380}
381
382void
383Debugger::Terminate ()
384{
Greg Clayton66111032010-06-23 01:19:29 +0000385 if (g_shared_debugger_refcount > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000386 {
Greg Clayton66111032010-06-23 01:19:29 +0000387 g_shared_debugger_refcount--;
388 if (g_shared_debugger_refcount == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000389 {
Greg Claytondbe54502010-11-19 03:46:01 +0000390 lldb_private::WillTerminate();
391 lldb_private::Terminate();
Caroline Tice6760a512011-01-17 21:55:19 +0000392
393 // Clear our master list of debugger objects
394 Mutex::Locker locker (GetDebuggerListMutex ());
395 GetDebuggerList().clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000396 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000397 }
398}
399
Caroline Tice20bd37f2011-03-10 22:14:10 +0000400void
401Debugger::SettingsInitialize ()
402{
Greg Clayton6920b522012-08-22 18:39:03 +0000403 Target::SettingsInitialize ();
Caroline Tice20bd37f2011-03-10 22:14:10 +0000404}
405
406void
407Debugger::SettingsTerminate ()
408{
Greg Clayton6920b522012-08-22 18:39:03 +0000409 Target::SettingsTerminate ();
Caroline Tice20bd37f2011-03-10 22:14:10 +0000410}
411
Enrico Granata21dfcd92012-09-28 23:57:51 +0000412bool
Enrico Granatae743c782013-04-24 21:29:08 +0000413Debugger::LoadPlugin (const FileSpec& spec, Error& error)
Enrico Granata21dfcd92012-09-28 23:57:51 +0000414{
415 lldb::DynamicLibrarySP dynlib_sp(new lldb_private::DynamicLibrary(spec));
Enrico Granatae743c782013-04-24 21:29:08 +0000416 if (!dynlib_sp || dynlib_sp->IsValid() == false)
417 {
418 if (spec.Exists())
419 error.SetErrorString("this file does not represent a loadable dylib");
420 else
421 error.SetErrorString("no such file");
422 return false;
423 }
Enrico Granata21dfcd92012-09-28 23:57:51 +0000424 lldb::DebuggerSP debugger_sp(shared_from_this());
425 lldb::SBDebugger debugger_sb(debugger_sp);
Michael Sartain3cf443d2013-07-17 00:26:30 +0000426 // This calls the bool lldb::PluginInitialize(lldb::SBDebugger debugger) function.
Enrico Granata21dfcd92012-09-28 23:57:51 +0000427 // TODO: mangle this differently for your system - on OSX, the first underscore needs to be removed and the second one stays
428 LLDBCommandPluginInit init_func = dynlib_sp->GetSymbol<LLDBCommandPluginInit>("_ZN4lldb16PluginInitializeENS_10SBDebuggerE");
429 if (!init_func)
Enrico Granatae743c782013-04-24 21:29:08 +0000430 {
431 error.SetErrorString("cannot find the initialization function lldb::PluginInitialize(lldb::SBDebugger)");
Enrico Granata21dfcd92012-09-28 23:57:51 +0000432 return false;
Enrico Granatae743c782013-04-24 21:29:08 +0000433 }
Enrico Granata21dfcd92012-09-28 23:57:51 +0000434 if (init_func(debugger_sb))
435 {
436 m_loaded_plugins.push_back(dynlib_sp);
437 return true;
438 }
Enrico Granatae743c782013-04-24 21:29:08 +0000439 error.SetErrorString("dylib refused to be loaded");
Enrico Granata21dfcd92012-09-28 23:57:51 +0000440 return false;
441}
442
443static FileSpec::EnumerateDirectoryResult
444LoadPluginCallback
445(
446 void *baton,
447 FileSpec::FileType file_type,
448 const FileSpec &file_spec
449 )
450{
451 Error error;
452
453 static ConstString g_dylibext("dylib");
Michael Sartain3cf443d2013-07-17 00:26:30 +0000454 static ConstString g_solibext("so");
Enrico Granata21dfcd92012-09-28 23:57:51 +0000455
456 if (!baton)
457 return FileSpec::eEnumerateDirectoryResultQuit;
458
459 Debugger *debugger = (Debugger*)baton;
460
461 // If we have a regular file, a symbolic link or unknown file type, try
462 // and process the file. We must handle unknown as sometimes the directory
463 // enumeration might be enumerating a file system that doesn't have correct
464 // file type information.
465 if (file_type == FileSpec::eFileTypeRegular ||
466 file_type == FileSpec::eFileTypeSymbolicLink ||
467 file_type == FileSpec::eFileTypeUnknown )
468 {
469 FileSpec plugin_file_spec (file_spec);
470 plugin_file_spec.ResolvePath ();
471
Michael Sartain3cf443d2013-07-17 00:26:30 +0000472 if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
473 plugin_file_spec.GetFileNameExtension() != g_solibext)
474 {
Enrico Granata21dfcd92012-09-28 23:57:51 +0000475 return FileSpec::eEnumerateDirectoryResultNext;
Michael Sartain3cf443d2013-07-17 00:26:30 +0000476 }
Enrico Granata21dfcd92012-09-28 23:57:51 +0000477
Enrico Granatae743c782013-04-24 21:29:08 +0000478 Error plugin_load_error;
479 debugger->LoadPlugin (plugin_file_spec, plugin_load_error);
Enrico Granata21dfcd92012-09-28 23:57:51 +0000480
481 return FileSpec::eEnumerateDirectoryResultNext;
482 }
483
484 else if (file_type == FileSpec::eFileTypeUnknown ||
485 file_type == FileSpec::eFileTypeDirectory ||
486 file_type == FileSpec::eFileTypeSymbolicLink )
487 {
488 // Try and recurse into anything that a directory or symbolic link.
489 // We must also do this for unknown as sometimes the directory enumeration
490 // might be enurating a file system that doesn't have correct file type
491 // information.
492 return FileSpec::eEnumerateDirectoryResultEnter;
493 }
494
495 return FileSpec::eEnumerateDirectoryResultNext;
496}
497
498void
499Debugger::InstanceInitialize ()
500{
501 FileSpec dir_spec;
502 const bool find_directories = true;
503 const bool find_files = true;
504 const bool find_other = true;
505 char dir_path[PATH_MAX];
506 if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec))
507 {
508 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
509 {
510 FileSpec::EnumerateDirectory (dir_path,
511 find_directories,
512 find_files,
513 find_other,
514 LoadPluginCallback,
515 this);
516 }
517 }
518
519 if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec))
520 {
521 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
522 {
523 FileSpec::EnumerateDirectory (dir_path,
524 find_directories,
525 find_files,
526 find_other,
527 LoadPluginCallback,
528 this);
529 }
530 }
Greg Claytone8cd0c92012-10-19 18:02:49 +0000531
532 PluginManager::DebuggerInitialize (*this);
Enrico Granata21dfcd92012-09-28 23:57:51 +0000533}
534
Greg Clayton66111032010-06-23 01:19:29 +0000535DebuggerSP
Jim Ingham228063c2012-02-21 02:23:08 +0000536Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
Greg Clayton66111032010-06-23 01:19:29 +0000537{
Jim Ingham228063c2012-02-21 02:23:08 +0000538 DebuggerSP debugger_sp (new Debugger(log_callback, baton));
Greg Claytonc15f55e2012-03-30 20:53:46 +0000539 if (g_shared_debugger_refcount > 0)
Greg Clayton66111032010-06-23 01:19:29 +0000540 {
541 Mutex::Locker locker (GetDebuggerListMutex ());
542 GetDebuggerList().push_back(debugger_sp);
543 }
Enrico Granata21dfcd92012-09-28 23:57:51 +0000544 debugger_sp->InstanceInitialize ();
Greg Clayton66111032010-06-23 01:19:29 +0000545 return debugger_sp;
546}
547
Caroline Ticee02657b2011-01-22 01:02:07 +0000548void
Greg Clayton4d122c42011-09-17 08:33:22 +0000549Debugger::Destroy (DebuggerSP &debugger_sp)
Caroline Ticee02657b2011-01-22 01:02:07 +0000550{
551 if (debugger_sp.get() == NULL)
552 return;
553
Jim Ingham8314c522011-09-15 21:36:42 +0000554 debugger_sp->Clear();
555
Greg Claytonc15f55e2012-03-30 20:53:46 +0000556 if (g_shared_debugger_refcount > 0)
Caroline Ticee02657b2011-01-22 01:02:07 +0000557 {
Greg Claytonc15f55e2012-03-30 20:53:46 +0000558 Mutex::Locker locker (GetDebuggerListMutex ());
559 DebuggerList &debugger_list = GetDebuggerList ();
560 DebuggerList::iterator pos, end = debugger_list.end();
561 for (pos = debugger_list.begin (); pos != end; ++pos)
Caroline Ticee02657b2011-01-22 01:02:07 +0000562 {
Greg Claytonc15f55e2012-03-30 20:53:46 +0000563 if ((*pos).get() == debugger_sp.get())
564 {
565 debugger_list.erase (pos);
566 return;
567 }
Caroline Ticee02657b2011-01-22 01:02:07 +0000568 }
569 }
Caroline Ticee02657b2011-01-22 01:02:07 +0000570}
571
Greg Clayton4d122c42011-09-17 08:33:22 +0000572DebuggerSP
Caroline Tice3df9a8d2010-09-04 00:03:46 +0000573Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
574{
Greg Clayton4d122c42011-09-17 08:33:22 +0000575 DebuggerSP debugger_sp;
Greg Clayton6920b522012-08-22 18:39:03 +0000576 if (g_shared_debugger_refcount > 0)
577 {
578 Mutex::Locker locker (GetDebuggerListMutex ());
579 DebuggerList &debugger_list = GetDebuggerList();
580 DebuggerList::iterator pos, end = debugger_list.end();
581
582 for (pos = debugger_list.begin(); pos != end; ++pos)
583 {
584 if ((*pos).get()->m_instance_name == instance_name)
585 {
586 debugger_sp = *pos;
587 break;
588 }
589 }
590 }
Caroline Tice3df9a8d2010-09-04 00:03:46 +0000591 return debugger_sp;
592}
Greg Clayton66111032010-06-23 01:19:29 +0000593
594TargetSP
595Debugger::FindTargetWithProcessID (lldb::pid_t pid)
596{
Greg Clayton4d122c42011-09-17 08:33:22 +0000597 TargetSP target_sp;
Greg Claytonc15f55e2012-03-30 20:53:46 +0000598 if (g_shared_debugger_refcount > 0)
Greg Clayton66111032010-06-23 01:19:29 +0000599 {
Greg Claytonc15f55e2012-03-30 20:53:46 +0000600 Mutex::Locker locker (GetDebuggerListMutex ());
601 DebuggerList &debugger_list = GetDebuggerList();
602 DebuggerList::iterator pos, end = debugger_list.end();
603 for (pos = debugger_list.begin(); pos != end; ++pos)
604 {
605 target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
606 if (target_sp)
607 break;
608 }
Greg Clayton66111032010-06-23 01:19:29 +0000609 }
610 return target_sp;
611}
612
Greg Claytone4e45922011-11-16 05:37:56 +0000613TargetSP
614Debugger::FindTargetWithProcess (Process *process)
615{
616 TargetSP target_sp;
Greg Claytonc15f55e2012-03-30 20:53:46 +0000617 if (g_shared_debugger_refcount > 0)
Greg Claytone4e45922011-11-16 05:37:56 +0000618 {
Greg Claytonc15f55e2012-03-30 20:53:46 +0000619 Mutex::Locker locker (GetDebuggerListMutex ());
620 DebuggerList &debugger_list = GetDebuggerList();
621 DebuggerList::iterator pos, end = debugger_list.end();
622 for (pos = debugger_list.begin(); pos != end; ++pos)
623 {
624 target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
625 if (target_sp)
626 break;
627 }
Greg Claytone4e45922011-11-16 05:37:56 +0000628 }
629 return target_sp;
630}
631
Jim Ingham228063c2012-02-21 02:23:08 +0000632Debugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) :
Caroline Ticeebc1bb22010-06-30 16:22:25 +0000633 UserID (g_unique_id++),
Greg Clayton67cc0632012-08-22 17:17:09 +0000634 Properties(OptionValuePropertiesSP(new OptionValueProperties())),
Greg Claytond46c87a2010-12-04 02:39:47 +0000635 m_input_comm("debugger.input"),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000636 m_input_file (),
637 m_output_file (),
638 m_error_file (),
Jim Inghamc5917d92012-11-30 20:23:19 +0000639 m_terminal_state (),
Jim Ingham4bddaeb2012-02-16 06:50:00 +0000640 m_target_list (*this),
Greg Claytonded470d2011-03-19 01:12:21 +0000641 m_platform_list (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000642 m_listener ("lldb.Debugger"),
Greg Clayton9585fbf2013-03-19 00:20:55 +0000643 m_source_manager_ap(),
Jim Inghame37d6052011-09-13 00:29:56 +0000644 m_source_file_cache(),
Greg Clayton66111032010-06-23 01:19:29 +0000645 m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000646 m_input_reader_stack (),
Greg Clayton67cc0632012-08-22 17:17:09 +0000647 m_input_reader_data (),
648 m_instance_name()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000649{
Greg Clayton67cc0632012-08-22 17:17:09 +0000650 char instance_cstr[256];
651 snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
652 m_instance_name.SetCString(instance_cstr);
Jim Ingham228063c2012-02-21 02:23:08 +0000653 if (log_callback)
654 m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
Greg Clayton66111032010-06-23 01:19:29 +0000655 m_command_interpreter_ap->Initialize ();
Greg Claytonded470d2011-03-19 01:12:21 +0000656 // Always add our default platform to the platform list
657 PlatformSP default_platform_sp (Platform::GetDefaultPlatform());
658 assert (default_platform_sp.get());
659 m_platform_list.Append (default_platform_sp, true);
Greg Clayton67cc0632012-08-22 17:17:09 +0000660
Greg Clayton754a9362012-08-23 00:22:02 +0000661 m_collection_sp->Initialize (g_properties);
Greg Clayton67cc0632012-08-22 17:17:09 +0000662 m_collection_sp->AppendProperty (ConstString("target"),
663 ConstString("Settings specify to debugging targets."),
664 true,
665 Target::GetGlobalProperties()->GetValueProperties());
Greg Clayton754a9362012-08-23 00:22:02 +0000666 if (m_command_interpreter_ap.get())
667 {
668 m_collection_sp->AppendProperty (ConstString("interpreter"),
669 ConstString("Settings specify to the debugger's command interpreter."),
670 true,
671 m_command_interpreter_ap->GetValueProperties());
672 }
Greg Clayton67cc0632012-08-22 17:17:09 +0000673 OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth);
674 term_width->SetMinimumValue(10);
675 term_width->SetMaximumValue(1024);
Michael Sartainc3ce7f272013-05-23 20:47:45 +0000676
677 // Turn off use-color if this is a dumb terminal.
678 const char *term = getenv ("TERM");
679 if (term && !strcmp (term, "dumb"))
680 SetUseColor (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000681}
682
683Debugger::~Debugger ()
684{
Jim Ingham8314c522011-09-15 21:36:42 +0000685 Clear();
686}
687
688void
689Debugger::Clear()
690{
Caroline Tice3d6086f2010-12-20 18:35:50 +0000691 CleanUpInputReaders();
Greg Clayton1ed54f52011-10-01 00:45:15 +0000692 m_listener.Clear();
Greg Clayton66111032010-06-23 01:19:29 +0000693 int num_targets = m_target_list.GetNumTargets();
694 for (int i = 0; i < num_targets; i++)
695 {
Greg Claytonccbc08e2012-01-14 17:04:19 +0000696 TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
697 if (target_sp)
Jim Ingham8314c522011-09-15 21:36:42 +0000698 {
Greg Claytonccbc08e2012-01-14 17:04:19 +0000699 ProcessSP process_sp (target_sp->GetProcessSP());
700 if (process_sp)
Jim Ingham1fd07052013-02-27 19:13:05 +0000701 process_sp->Finalize();
Greg Claytonccbc08e2012-01-14 17:04:19 +0000702 target_sp->Destroy();
Jim Ingham8314c522011-09-15 21:36:42 +0000703 }
Greg Clayton66111032010-06-23 01:19:29 +0000704 }
Jim Ingham4bddaeb2012-02-16 06:50:00 +0000705 BroadcasterManager::Clear ();
Greg Clayton0d69a3a2012-05-16 00:11:54 +0000706
707 // Close the input file _before_ we close the input read communications class
708 // as it does NOT own the input file, our m_input_file does.
Jim Inghamc5917d92012-11-30 20:23:19 +0000709 m_terminal_state.Clear();
Greg Clayton0d69a3a2012-05-16 00:11:54 +0000710 GetInputFile().Close ();
711 // Now that we have closed m_input_file, we can now tell our input communication
712 // class to close down. Its read thread should quickly exit after we close
713 // the input file handle above.
714 m_input_comm.Clear ();
Jim Ingham8314c522011-09-15 21:36:42 +0000715}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000716
717bool
Greg Claytonfc3f0272011-05-29 04:06:55 +0000718Debugger::GetCloseInputOnEOF () const
719{
720 return m_input_comm.GetCloseOnEOF();
721}
722
723void
724Debugger::SetCloseInputOnEOF (bool b)
725{
726 m_input_comm.SetCloseOnEOF(b);
727}
728
729bool
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000730Debugger::GetAsyncExecution ()
731{
Greg Clayton66111032010-06-23 01:19:29 +0000732 return !m_command_interpreter_ap->GetSynchronous();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000733}
734
735void
736Debugger::SetAsyncExecution (bool async_execution)
737{
Greg Clayton66111032010-06-23 01:19:29 +0000738 m_command_interpreter_ap->SetSynchronous (!async_execution);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000739}
740
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000741
742void
743Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
744{
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000745 File &in_file = GetInputFile();
746 in_file.SetStream (fh, tranfer_ownership);
747 if (in_file.IsValid() == false)
748 in_file.SetStream (stdin, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000749
750 // Disconnect from any old connection if we had one
751 m_input_comm.Disconnect ();
Greg Clayton32720b52012-01-14 20:47:38 +0000752 // Pass false as the second argument to ConnectionFileDescriptor below because
753 // our "in_file" above will already take ownership if requested and we don't
754 // want to objects trying to own and close a file descriptor.
755 m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), false));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000756 m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this);
Jim Inghamc5917d92012-11-30 20:23:19 +0000757
758 // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState.
759 SaveInputTerminalState ();
760
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000761 Error error;
762 if (m_input_comm.StartReadThread (&error) == false)
763 {
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000764 File &err_file = GetErrorFile();
765
766 err_file.Printf ("error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error");
767 exit(1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000768 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000769}
770
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000771void
772Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
773{
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000774 File &out_file = GetOutputFile();
775 out_file.SetStream (fh, tranfer_ownership);
776 if (out_file.IsValid() == false)
777 out_file.SetStream (stdout, false);
Caroline Tice2f88aad2011-01-14 00:29:16 +0000778
Enrico Granatab5887262012-10-29 21:18:03 +0000779 // do not create the ScriptInterpreter just for setting the output file handle
780 // as the constructor will know how to do the right thing on its own
781 const bool can_create = false;
782 ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create);
783 if (script_interpreter)
784 script_interpreter->ResetOutputFileHandle (fh);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000785}
786
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000787void
788Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
789{
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000790 File &err_file = GetErrorFile();
791 err_file.SetStream (fh, tranfer_ownership);
792 if (err_file.IsValid() == false)
793 err_file.SetStream (stderr, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000794}
795
Jim Inghamc5917d92012-11-30 20:23:19 +0000796void
797Debugger::SaveInputTerminalState ()
798{
799 File &in_file = GetInputFile();
800 if (in_file.GetDescriptor() != File::kInvalidDescriptor)
801 m_terminal_state.Save(in_file.GetDescriptor(), true);
802}
803
804void
805Debugger::RestoreInputTerminalState ()
806{
807 m_terminal_state.Restore();
808}
809
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000810ExecutionContext
Jim Ingham2976d002010-08-26 21:32:51 +0000811Debugger::GetSelectedExecutionContext ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000812{
813 ExecutionContext exe_ctx;
Greg Claytonc14ee322011-09-22 04:58:26 +0000814 TargetSP target_sp(GetSelectedTarget());
815 exe_ctx.SetTargetSP (target_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000816
817 if (target_sp)
818 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000819 ProcessSP process_sp (target_sp->GetProcessSP());
820 exe_ctx.SetProcessSP (process_sp);
821 if (process_sp && process_sp->IsRunning() == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000822 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000823 ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
824 if (thread_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000825 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000826 exe_ctx.SetThreadSP (thread_sp);
827 exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
828 if (exe_ctx.GetFramePtr() == NULL)
829 exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000830 }
831 }
832 }
833 return exe_ctx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000834}
835
Caroline Ticeb44880c2011-02-10 01:15:13 +0000836InputReaderSP
837Debugger::GetCurrentInputReader ()
838{
839 InputReaderSP reader_sp;
840
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000841 if (!m_input_reader_stack.IsEmpty())
Caroline Ticeb44880c2011-02-10 01:15:13 +0000842 {
843 // Clear any finished readers from the stack
844 while (CheckIfTopInputReaderIsDone()) ;
845
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000846 if (!m_input_reader_stack.IsEmpty())
847 reader_sp = m_input_reader_stack.Top();
Caroline Ticeb44880c2011-02-10 01:15:13 +0000848 }
849
850 return reader_sp;
851}
852
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000853void
854Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len)
855{
Caroline Ticeefed6132010-11-19 20:47:54 +0000856 if (bytes_len > 0)
857 ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len);
858 else
859 ((Debugger *)baton)->DispatchInputEndOfFile ();
860}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000861
862
863void
864Debugger::DispatchInput (const char *bytes, size_t bytes_len)
865{
Caroline Ticeefed6132010-11-19 20:47:54 +0000866 if (bytes == NULL || bytes_len == 0)
867 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000868
869 WriteToDefaultReader (bytes, bytes_len);
870}
871
872void
Caroline Ticeefed6132010-11-19 20:47:54 +0000873Debugger::DispatchInputInterrupt ()
874{
875 m_input_reader_data.clear();
876
Caroline Ticeb44880c2011-02-10 01:15:13 +0000877 InputReaderSP reader_sp (GetCurrentInputReader ());
878 if (reader_sp)
Caroline Ticeefed6132010-11-19 20:47:54 +0000879 {
Caroline Ticeb44880c2011-02-10 01:15:13 +0000880 reader_sp->Notify (eInputReaderInterrupt);
Caroline Ticeefed6132010-11-19 20:47:54 +0000881
Caroline Ticeb44880c2011-02-10 01:15:13 +0000882 // If notifying the reader of the interrupt finished the reader, we should pop it off the stack.
Caroline Ticeefed6132010-11-19 20:47:54 +0000883 while (CheckIfTopInputReaderIsDone ()) ;
884 }
885}
886
887void
888Debugger::DispatchInputEndOfFile ()
889{
890 m_input_reader_data.clear();
891
Caroline Ticeb44880c2011-02-10 01:15:13 +0000892 InputReaderSP reader_sp (GetCurrentInputReader ());
893 if (reader_sp)
Caroline Ticeefed6132010-11-19 20:47:54 +0000894 {
Caroline Ticeb44880c2011-02-10 01:15:13 +0000895 reader_sp->Notify (eInputReaderEndOfFile);
Caroline Ticeefed6132010-11-19 20:47:54 +0000896
Caroline Ticeb44880c2011-02-10 01:15:13 +0000897 // If notifying the reader of the end-of-file finished the reader, we should pop it off the stack.
Caroline Ticeefed6132010-11-19 20:47:54 +0000898 while (CheckIfTopInputReaderIsDone ()) ;
899 }
900}
901
902void
Caroline Tice3d6086f2010-12-20 18:35:50 +0000903Debugger::CleanUpInputReaders ()
904{
905 m_input_reader_data.clear();
906
Caroline Ticeb44880c2011-02-10 01:15:13 +0000907 // The bottom input reader should be the main debugger input reader. We do not want to close that one here.
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000908 while (m_input_reader_stack.GetSize() > 1)
Caroline Tice3d6086f2010-12-20 18:35:50 +0000909 {
Caroline Ticeb44880c2011-02-10 01:15:13 +0000910 InputReaderSP reader_sp (GetCurrentInputReader ());
Caroline Tice3d6086f2010-12-20 18:35:50 +0000911 if (reader_sp)
912 {
913 reader_sp->Notify (eInputReaderEndOfFile);
914 reader_sp->SetIsDone (true);
915 }
916 }
917}
918
919void
Caroline Tice969ed3d2011-05-02 20:41:46 +0000920Debugger::NotifyTopInputReader (InputReaderAction notification)
921{
922 InputReaderSP reader_sp (GetCurrentInputReader());
923 if (reader_sp)
924 {
925 reader_sp->Notify (notification);
926
927 // Flush out any input readers that are done.
928 while (CheckIfTopInputReaderIsDone ())
929 /* Do nothing. */;
930 }
931}
932
Caroline Tice9088b062011-05-09 23:06:58 +0000933bool
Greg Clayton4d122c42011-09-17 08:33:22 +0000934Debugger::InputReaderIsTopReader (const InputReaderSP& reader_sp)
Caroline Tice9088b062011-05-09 23:06:58 +0000935{
Caroline Ticed61c10b2011-06-16 16:27:19 +0000936 InputReaderSP top_reader_sp (GetCurrentInputReader());
Caroline Tice9088b062011-05-09 23:06:58 +0000937
Caroline Ticed61c10b2011-06-16 16:27:19 +0000938 return (reader_sp.get() == top_reader_sp.get());
Caroline Tice9088b062011-05-09 23:06:58 +0000939}
940
941
Caroline Tice969ed3d2011-05-02 20:41:46 +0000942void
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000943Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len)
944{
945 if (bytes && bytes_len)
946 m_input_reader_data.append (bytes, bytes_len);
947
948 if (m_input_reader_data.empty())
949 return;
950
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000951 while (!m_input_reader_stack.IsEmpty() && !m_input_reader_data.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000952 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000953 // Get the input reader from the top of the stack
Caroline Ticeb44880c2011-02-10 01:15:13 +0000954 InputReaderSP reader_sp (GetCurrentInputReader ());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000955 if (!reader_sp)
956 break;
957
Greg Clayton471b31c2010-07-20 22:52:08 +0000958 size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000959 m_input_reader_data.size());
960 if (bytes_handled)
961 {
962 m_input_reader_data.erase (0, bytes_handled);
963 }
964 else
965 {
966 // No bytes were handled, we might not have reached our
967 // granularity, just return and wait for more data
968 break;
969 }
970 }
971
Caroline Ticeb44880c2011-02-10 01:15:13 +0000972 // Flush out any input readers that are done.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000973 while (CheckIfTopInputReaderIsDone ())
974 /* Do nothing. */;
975
976}
977
978void
979Debugger::PushInputReader (const InputReaderSP& reader_sp)
980{
981 if (!reader_sp)
982 return;
Caroline Ticeb44880c2011-02-10 01:15:13 +0000983
984 // Deactivate the old top reader
985 InputReaderSP top_reader_sp (GetCurrentInputReader ());
986
987 if (top_reader_sp)
988 top_reader_sp->Notify (eInputReaderDeactivate);
989
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000990 m_input_reader_stack.Push (reader_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000991 reader_sp->Notify (eInputReaderActivate);
992 ActivateInputReader (reader_sp);
993}
994
995bool
Greg Clayton4d122c42011-09-17 08:33:22 +0000996Debugger::PopInputReader (const InputReaderSP& pop_reader_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000997{
998 bool result = false;
999
1000 // The reader on the stop of the stack is done, so let the next
1001 // read on the stack referesh its prompt and if there is one...
Caroline Ticed5a0a01b2011-06-02 19:18:55 +00001002 if (!m_input_reader_stack.IsEmpty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001003 {
Caroline Ticeb44880c2011-02-10 01:15:13 +00001004 // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
Caroline Ticed5a0a01b2011-06-02 19:18:55 +00001005 InputReaderSP reader_sp(m_input_reader_stack.Top());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001006
1007 if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
1008 {
Caroline Ticed5a0a01b2011-06-02 19:18:55 +00001009 m_input_reader_stack.Pop ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001010 reader_sp->Notify (eInputReaderDeactivate);
1011 reader_sp->Notify (eInputReaderDone);
1012 result = true;
1013
Caroline Ticed5a0a01b2011-06-02 19:18:55 +00001014 if (!m_input_reader_stack.IsEmpty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001015 {
Caroline Ticed5a0a01b2011-06-02 19:18:55 +00001016 reader_sp = m_input_reader_stack.Top();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001017 if (reader_sp)
1018 {
1019 ActivateInputReader (reader_sp);
1020 reader_sp->Notify (eInputReaderReactivate);
1021 }
1022 }
1023 }
1024 }
1025 return result;
1026}
1027
1028bool
1029Debugger::CheckIfTopInputReaderIsDone ()
1030{
1031 bool result = false;
Caroline Ticed5a0a01b2011-06-02 19:18:55 +00001032 if (!m_input_reader_stack.IsEmpty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001033 {
Caroline Ticeb44880c2011-02-10 01:15:13 +00001034 // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
Caroline Ticed5a0a01b2011-06-02 19:18:55 +00001035 InputReaderSP reader_sp(m_input_reader_stack.Top());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001036
1037 if (reader_sp && reader_sp->IsDone())
1038 {
1039 result = true;
1040 PopInputReader (reader_sp);
1041 }
1042 }
1043 return result;
1044}
1045
1046void
1047Debugger::ActivateInputReader (const InputReaderSP &reader_sp)
1048{
Greg Clayton51b1e2d2011-02-09 01:08:52 +00001049 int input_fd = m_input_file.GetFile().GetDescriptor();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001050
Greg Clayton51b1e2d2011-02-09 01:08:52 +00001051 if (input_fd >= 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001052 {
Greg Clayton51b1e2d2011-02-09 01:08:52 +00001053 Terminal tty(input_fd);
Greg Claytona3406612011-02-07 23:24:47 +00001054
1055 tty.SetEcho(reader_sp->GetEcho());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001056
Greg Claytona3406612011-02-07 23:24:47 +00001057 switch (reader_sp->GetGranularity())
1058 {
1059 case eInputReaderGranularityByte:
1060 case eInputReaderGranularityWord:
1061 tty.SetCanonical (false);
1062 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001063
Greg Claytona3406612011-02-07 23:24:47 +00001064 case eInputReaderGranularityLine:
1065 case eInputReaderGranularityAll:
1066 tty.SetCanonical (true);
1067 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001068
Greg Claytona3406612011-02-07 23:24:47 +00001069 default:
1070 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001071 }
1072 }
1073}
Greg Clayton66111032010-06-23 01:19:29 +00001074
Jim Ingham5b52f0c2011-06-02 23:58:26 +00001075StreamSP
1076Debugger::GetAsyncOutputStream ()
1077{
1078 return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
1079 CommandInterpreter::eBroadcastBitAsynchronousOutputData));
1080}
1081
1082StreamSP
1083Debugger::GetAsyncErrorStream ()
1084{
1085 return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
1086 CommandInterpreter::eBroadcastBitAsynchronousErrorData));
1087}
1088
Greg Claytonc7bece562013-01-25 18:06:21 +00001089size_t
Enrico Granata061858c2012-02-15 02:34:21 +00001090Debugger::GetNumDebuggers()
1091{
Greg Claytonc15f55e2012-03-30 20:53:46 +00001092 if (g_shared_debugger_refcount > 0)
1093 {
1094 Mutex::Locker locker (GetDebuggerListMutex ());
1095 return GetDebuggerList().size();
1096 }
1097 return 0;
Enrico Granata061858c2012-02-15 02:34:21 +00001098}
1099
1100lldb::DebuggerSP
Greg Claytonc7bece562013-01-25 18:06:21 +00001101Debugger::GetDebuggerAtIndex (size_t index)
Enrico Granata061858c2012-02-15 02:34:21 +00001102{
1103 DebuggerSP debugger_sp;
1104
Greg Claytonc15f55e2012-03-30 20:53:46 +00001105 if (g_shared_debugger_refcount > 0)
1106 {
1107 Mutex::Locker locker (GetDebuggerListMutex ());
1108 DebuggerList &debugger_list = GetDebuggerList();
Enrico Granata061858c2012-02-15 02:34:21 +00001109
Greg Claytonc15f55e2012-03-30 20:53:46 +00001110 if (index < debugger_list.size())
1111 debugger_sp = debugger_list[index];
1112 }
1113
Enrico Granata061858c2012-02-15 02:34:21 +00001114 return debugger_sp;
1115}
1116
Caroline Ticeebc1bb22010-06-30 16:22:25 +00001117DebuggerSP
1118Debugger::FindDebuggerWithID (lldb::user_id_t id)
1119{
Greg Clayton4d122c42011-09-17 08:33:22 +00001120 DebuggerSP debugger_sp;
Caroline Ticeebc1bb22010-06-30 16:22:25 +00001121
Greg Claytonc15f55e2012-03-30 20:53:46 +00001122 if (g_shared_debugger_refcount > 0)
Caroline Ticeebc1bb22010-06-30 16:22:25 +00001123 {
Greg Claytonc15f55e2012-03-30 20:53:46 +00001124 Mutex::Locker locker (GetDebuggerListMutex ());
1125 DebuggerList &debugger_list = GetDebuggerList();
1126 DebuggerList::iterator pos, end = debugger_list.end();
1127 for (pos = debugger_list.begin(); pos != end; ++pos)
Caroline Ticeebc1bb22010-06-30 16:22:25 +00001128 {
Greg Claytonc15f55e2012-03-30 20:53:46 +00001129 if ((*pos).get()->GetID() == id)
1130 {
1131 debugger_sp = *pos;
1132 break;
1133 }
Caroline Ticeebc1bb22010-06-30 16:22:25 +00001134 }
1135 }
1136 return debugger_sp;
1137}
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001138
Greg Clayton1b654882010-09-19 02:33:57 +00001139static void
Jason Molendab57e4a12013-11-04 09:33:30 +00001140TestPromptFormats (StackFrame *frame)
Greg Clayton1b654882010-09-19 02:33:57 +00001141{
1142 if (frame == NULL)
1143 return;
1144
1145 StreamString s;
1146 const char *prompt_format =
1147 "{addr = '${addr}'\n}"
1148 "{process.id = '${process.id}'\n}"
1149 "{process.name = '${process.name}'\n}"
1150 "{process.file.basename = '${process.file.basename}'\n}"
1151 "{process.file.fullpath = '${process.file.fullpath}'\n}"
1152 "{thread.id = '${thread.id}'\n}"
1153 "{thread.index = '${thread.index}'\n}"
1154 "{thread.name = '${thread.name}'\n}"
1155 "{thread.queue = '${thread.queue}'\n}"
1156 "{thread.stop-reason = '${thread.stop-reason}'\n}"
1157 "{target.arch = '${target.arch}'\n}"
1158 "{module.file.basename = '${module.file.basename}'\n}"
1159 "{module.file.fullpath = '${module.file.fullpath}'\n}"
1160 "{file.basename = '${file.basename}'\n}"
1161 "{file.fullpath = '${file.fullpath}'\n}"
1162 "{frame.index = '${frame.index}'\n}"
1163 "{frame.pc = '${frame.pc}'\n}"
1164 "{frame.sp = '${frame.sp}'\n}"
1165 "{frame.fp = '${frame.fp}'\n}"
1166 "{frame.flags = '${frame.flags}'\n}"
1167 "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
1168 "{frame.reg.rip = '${frame.reg.rip}'\n}"
1169 "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
1170 "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
1171 "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
1172 "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
1173 "{frame.reg.carp = '${frame.reg.carp}'\n}"
1174 "{function.id = '${function.id}'\n}"
1175 "{function.name = '${function.name}'\n}"
Greg Claytonccbc08e2012-01-14 17:04:19 +00001176 "{function.name-with-args = '${function.name-with-args}'\n}"
Greg Clayton1b654882010-09-19 02:33:57 +00001177 "{function.addr-offset = '${function.addr-offset}'\n}"
1178 "{function.line-offset = '${function.line-offset}'\n}"
1179 "{function.pc-offset = '${function.pc-offset}'\n}"
1180 "{line.file.basename = '${line.file.basename}'\n}"
1181 "{line.file.fullpath = '${line.file.fullpath}'\n}"
1182 "{line.number = '${line.number}'\n}"
1183 "{line.start-addr = '${line.start-addr}'\n}"
1184 "{line.end-addr = '${line.end-addr}'\n}"
1185;
1186
1187 SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
1188 ExecutionContext exe_ctx;
Greg Clayton0603aa92010-10-04 01:05:56 +00001189 frame->CalculateExecutionContext(exe_ctx);
Michael Sartainc3ce7f272013-05-23 20:47:45 +00001190 if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s))
Greg Clayton1b654882010-09-19 02:33:57 +00001191 {
1192 printf("%s\n", s.GetData());
1193 }
1194 else
1195 {
Greg Clayton1b654882010-09-19 02:33:57 +00001196 printf ("what we got: %s\n", s.GetData());
1197 }
1198}
1199
Enrico Granata9fc19442011-07-06 02:13:41 +00001200static bool
Enrico Granatadc940732011-08-23 00:32:52 +00001201ScanFormatDescriptor (const char* var_name_begin,
1202 const char* var_name_end,
1203 const char** var_name_final,
1204 const char** percent_position,
Greg Clayton4d122c42011-09-17 08:33:22 +00001205 Format* custom_format,
Enrico Granatadc940732011-08-23 00:32:52 +00001206 ValueObject::ValueObjectRepresentationStyle* val_obj_display)
Enrico Granata9fc19442011-07-06 02:13:41 +00001207{
Greg Clayton5160ce52013-03-27 23:08:40 +00001208 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
Enrico Granata9fc19442011-07-06 02:13:41 +00001209 *percent_position = ::strchr(var_name_begin,'%');
Greg Clayton34132752011-07-06 04:07:21 +00001210 if (!*percent_position || *percent_position > var_name_end)
Enrico Granatae992a082011-07-22 17:03:19 +00001211 {
1212 if (log)
Enrico Granatad2284832012-10-17 22:23:56 +00001213 log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping");
Enrico Granata9fc19442011-07-06 02:13:41 +00001214 *var_name_final = var_name_end;
Enrico Granatae992a082011-07-22 17:03:19 +00001215 }
Enrico Granata9fc19442011-07-06 02:13:41 +00001216 else
1217 {
1218 *var_name_final = *percent_position;
Enrico Granata36aa5ae2013-05-06 17:18:22 +00001219 std::string format_name(*var_name_final+1, var_name_end-*var_name_final-1);
Enrico Granatae992a082011-07-22 17:03:19 +00001220 if (log)
Enrico Granata68ae4112013-06-18 18:23:07 +00001221 log->Printf("[ScanFormatDescriptor] parsing %s as a format descriptor", format_name.c_str());
Enrico Granata36aa5ae2013-05-06 17:18:22 +00001222 if ( !FormatManager::GetFormatFromCString(format_name.c_str(),
Enrico Granata9fc19442011-07-06 02:13:41 +00001223 true,
1224 *custom_format) )
1225 {
Enrico Granatae992a082011-07-22 17:03:19 +00001226 if (log)
Enrico Granata68ae4112013-06-18 18:23:07 +00001227 log->Printf("[ScanFormatDescriptor] %s is an unknown format", format_name.c_str());
Enrico Granata36aa5ae2013-05-06 17:18:22 +00001228
1229 switch (format_name.front())
1230 {
1231 case '@': // if this is an @ sign, print ObjC description
1232 *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific;
1233 break;
1234 case 'V': // if this is a V, print the value using the default format
1235 *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1236 break;
1237 case 'L': // if this is an L, print the location of the value
1238 *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation;
1239 break;
1240 case 'S': // if this is an S, print the summary after all
1241 *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
1242 break;
1243 case '#': // if this is a '#', print the number of children
1244 *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount;
1245 break;
1246 case 'T': // if this is a 'T', print the type
1247 *val_obj_display = ValueObject::eValueObjectRepresentationStyleType;
1248 break;
Enrico Granata2c75f112013-06-21 00:04:51 +00001249 case 'N': // if this is a 'N', print the name
1250 *val_obj_display = ValueObject::eValueObjectRepresentationStyleName;
1251 break;
1252 case '>': // if this is a '>', print the name
1253 *val_obj_display = ValueObject::eValueObjectRepresentationStyleExpressionPath;
1254 break;
Enrico Granata36aa5ae2013-05-06 17:18:22 +00001255 default:
Jim Ingham5c42d8a2013-05-15 18:27:08 +00001256 if (log)
1257 log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name.c_str());
Enrico Granata36aa5ae2013-05-06 17:18:22 +00001258 break;
1259 }
Enrico Granata9fc19442011-07-06 02:13:41 +00001260 }
1261 // a good custom format tells us to print the value using it
1262 else
Enrico Granatae992a082011-07-22 17:03:19 +00001263 {
1264 if (log)
Enrico Granata68ae4112013-06-18 18:23:07 +00001265 log->Printf("[ScanFormatDescriptor] will display value for this VO");
Enrico Granata86cc9822012-03-19 22:58:49 +00001266 *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
Enrico Granatae992a082011-07-22 17:03:19 +00001267 }
Enrico Granata9fc19442011-07-06 02:13:41 +00001268 }
Enrico Granatae992a082011-07-22 17:03:19 +00001269 if (log)
Enrico Granata68ae4112013-06-18 18:23:07 +00001270 log->Printf("[ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d",
Enrico Granatae992a082011-07-22 17:03:19 +00001271 *custom_format,
1272 *val_obj_display);
Enrico Granata9fc19442011-07-06 02:13:41 +00001273 return true;
1274}
1275
1276static bool
Enrico Granatadc940732011-08-23 00:32:52 +00001277ScanBracketedRange (const char* var_name_begin,
1278 const char* var_name_end,
1279 const char* var_name_final,
1280 const char** open_bracket_position,
1281 const char** separator_position,
1282 const char** close_bracket_position,
1283 const char** var_name_final_if_array_range,
1284 int64_t* index_lower,
1285 int64_t* index_higher)
Enrico Granata9fc19442011-07-06 02:13:41 +00001286{
Greg Clayton5160ce52013-03-27 23:08:40 +00001287 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
Enrico Granata9fc19442011-07-06 02:13:41 +00001288 *open_bracket_position = ::strchr(var_name_begin,'[');
Greg Clayton34132752011-07-06 04:07:21 +00001289 if (*open_bracket_position && *open_bracket_position < var_name_final)
Enrico Granata9fc19442011-07-06 02:13:41 +00001290 {
1291 *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield
1292 *close_bracket_position = ::strchr(*open_bracket_position,']');
1293 // as usual, we assume that [] will come before %
1294 //printf("trying to expand a []\n");
1295 *var_name_final_if_array_range = *open_bracket_position;
Greg Clayton34132752011-07-06 04:07:21 +00001296 if (*close_bracket_position - *open_bracket_position == 1)
Enrico Granata9fc19442011-07-06 02:13:41 +00001297 {
Enrico Granatae992a082011-07-22 17:03:19 +00001298 if (log)
Enrico Granatad2284832012-10-17 22:23:56 +00001299 log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
Enrico Granata9fc19442011-07-06 02:13:41 +00001300 *index_lower = 0;
1301 }
1302 else if (*separator_position == NULL || *separator_position > var_name_end)
1303 {
1304 char *end = NULL;
1305 *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
1306 *index_higher = *index_lower;
Enrico Granatae992a082011-07-22 17:03:19 +00001307 if (log)
Daniel Malead01b2952012-11-29 21:49:15 +00001308 log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower);
Enrico Granata9fc19442011-07-06 02:13:41 +00001309 }
Greg Clayton34132752011-07-06 04:07:21 +00001310 else if (*close_bracket_position && *close_bracket_position < var_name_end)
Enrico Granata9fc19442011-07-06 02:13:41 +00001311 {
1312 char *end = NULL;
1313 *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
1314 *index_higher = ::strtoul (*separator_position+1, &end, 0);
Enrico Granatae992a082011-07-22 17:03:19 +00001315 if (log)
Daniel Malead01b2952012-11-29 21:49:15 +00001316 log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher);
Enrico Granata9fc19442011-07-06 02:13:41 +00001317 }
1318 else
Enrico Granatae992a082011-07-22 17:03:19 +00001319 {
1320 if (log)
Enrico Granatad2284832012-10-17 22:23:56 +00001321 log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it");
Enrico Granata9fc19442011-07-06 02:13:41 +00001322 return false;
Enrico Granatae992a082011-07-22 17:03:19 +00001323 }
Enrico Granata9fc19442011-07-06 02:13:41 +00001324 if (*index_lower > *index_higher && *index_higher > 0)
1325 {
Enrico Granatae992a082011-07-22 17:03:19 +00001326 if (log)
Enrico Granatad2284832012-10-17 22:23:56 +00001327 log->Printf("[ScanBracketedRange] swapping indices");
Greg Claytonc7bece562013-01-25 18:06:21 +00001328 int64_t temp = *index_lower;
Enrico Granata9fc19442011-07-06 02:13:41 +00001329 *index_lower = *index_higher;
1330 *index_higher = temp;
1331 }
1332 }
Enrico Granatae992a082011-07-22 17:03:19 +00001333 else if (log)
Enrico Granatad2284832012-10-17 22:23:56 +00001334 log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
Enrico Granata9fc19442011-07-06 02:13:41 +00001335 return true;
1336}
1337
Michael Sartain0769b2b2013-07-30 16:44:36 +00001338template <typename T>
1339static bool RunScriptFormatKeyword(Stream &s, ScriptInterpreter *script_interpreter, T t, const std::string& script_name)
1340{
1341 if (script_interpreter)
1342 {
1343 Error script_error;
1344 std::string script_output;
1345
1346 if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), t, script_output, script_error) && script_error.Success())
1347 {
1348 s.Printf("%s", script_output.c_str());
1349 return true;
1350 }
1351 else
1352 {
1353 s.Printf("<error: %s>",script_error.AsCString());
1354 }
1355 }
1356 return false;
1357}
1358
Enrico Granata9fc19442011-07-06 02:13:41 +00001359static ValueObjectSP
Enrico Granatadc940732011-08-23 00:32:52 +00001360ExpandIndexedExpression (ValueObject* valobj,
Greg Claytonc7bece562013-01-25 18:06:21 +00001361 size_t index,
Jason Molendab57e4a12013-11-04 09:33:30 +00001362 StackFrame* frame,
Enrico Granatadc940732011-08-23 00:32:52 +00001363 bool deref_pointer)
Enrico Granata9fc19442011-07-06 02:13:41 +00001364{
Greg Clayton5160ce52013-03-27 23:08:40 +00001365 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001366 const char* ptr_deref_format = "[%d]";
Enrico Granata599171a2013-02-01 23:59:44 +00001367 std::string ptr_deref_buffer(10,0);
1368 ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index);
Enrico Granatae992a082011-07-22 17:03:19 +00001369 if (log)
Enrico Granata599171a2013-02-01 23:59:44 +00001370 log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str());
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001371 const char* first_unparsed;
1372 ValueObject::GetValueForExpressionPathOptions options;
1373 ValueObject::ExpressionPathEndResultType final_value_type;
1374 ValueObject::ExpressionPathScanEndReason reason_to_stop;
Enrico Granata86cc9822012-03-19 22:58:49 +00001375 ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
Enrico Granata599171a2013-02-01 23:59:44 +00001376 ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(),
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001377 &first_unparsed,
1378 &reason_to_stop,
1379 &final_value_type,
1380 options,
1381 &what_next);
1382 if (!item)
1383 {
Enrico Granatae992a082011-07-22 17:03:19 +00001384 if (log)
Enrico Granatad2284832012-10-17 22:23:56 +00001385 log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d,"
Enrico Granatae992a082011-07-22 17:03:19 +00001386 " final_value_type %d",
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001387 first_unparsed, reason_to_stop, final_value_type);
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001388 }
Enrico Granata9fc19442011-07-06 02:13:41 +00001389 else
1390 {
Enrico Granatae992a082011-07-22 17:03:19 +00001391 if (log)
Enrico Granatad2284832012-10-17 22:23:56 +00001392 log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
Enrico Granatae992a082011-07-22 17:03:19 +00001393 " final_value_type %d",
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001394 first_unparsed, reason_to_stop, final_value_type);
Enrico Granata9fc19442011-07-06 02:13:41 +00001395 }
1396 return item;
1397}
1398
Michael Sartain0769b2b2013-07-30 16:44:36 +00001399static inline bool
1400IsToken(const char *var_name_begin, const char *var)
1401{
1402 return (::strncmp (var_name_begin, var, strlen(var)) == 0);
1403}
1404
1405static bool
1406IsTokenWithFormat(const char *var_name_begin, const char *var, std::string &format, const char *default_format,
1407 const ExecutionContext *exe_ctx_ptr, const SymbolContext *sc_ptr)
1408{
1409 int var_len = strlen(var);
1410 if (::strncmp (var_name_begin, var, var_len) == 0)
1411 {
1412 var_name_begin += var_len;
1413 if (*var_name_begin == '}')
1414 {
1415 format = default_format;
1416 return true;
1417 }
1418 else if (*var_name_begin == '%')
1419 {
1420 // Allow format specifiers: x|X|u with optional width specifiers.
1421 // ${thread.id%x} ; hex
1422 // ${thread.id%X} ; uppercase hex
1423 // ${thread.id%u} ; unsigned decimal
1424 // ${thread.id%8.8X} ; width.precision + specifier
1425 // ${thread.id%tid} ; unsigned on FreeBSD/Linux, otherwise default_format (0x%4.4x for thread.id)
1426 int dot_count = 0;
1427 const char *specifier = NULL;
1428 int width_precision_length = 0;
1429 const char *width_precision = ++var_name_begin;
1430 while (isdigit(*var_name_begin) || *var_name_begin == '.')
1431 {
1432 dot_count += (*var_name_begin == '.');
1433 if (dot_count > 1)
1434 break;
1435 var_name_begin++;
1436 width_precision_length++;
1437 }
1438
1439 if (IsToken (var_name_begin, "tid}"))
1440 {
1441 Target *target = Target::GetTargetFromContexts (exe_ctx_ptr, sc_ptr);
1442 if (target)
1443 {
1444 ArchSpec arch (target->GetArchitecture ());
1445 llvm::Triple::OSType ostype = arch.IsValid() ? arch.GetTriple().getOS() : llvm::Triple::UnknownOS;
1446 if ((ostype == llvm::Triple::FreeBSD) || (ostype == llvm::Triple::Linux))
1447 specifier = PRIu64;
1448 }
1449 if (!specifier)
1450 {
1451 format = default_format;
1452 return true;
1453 }
1454 }
1455 else if (IsToken (var_name_begin, "x}"))
1456 specifier = PRIx64;
1457 else if (IsToken (var_name_begin, "X}"))
1458 specifier = PRIX64;
1459 else if (IsToken (var_name_begin, "u}"))
1460 specifier = PRIu64;
1461
1462 if (specifier)
1463 {
1464 format = "%";
1465 if (width_precision_length)
1466 format += std::string(width_precision, width_precision_length);
1467 format += specifier;
1468 return true;
1469 }
1470 }
1471 }
1472 return false;
1473}
1474
Michael Sartainc3ce7f272013-05-23 20:47:45 +00001475static bool
1476FormatPromptRecurse
Greg Clayton1b654882010-09-19 02:33:57 +00001477(
1478 const char *format,
1479 const SymbolContext *sc,
1480 const ExecutionContext *exe_ctx,
1481 const Address *addr,
1482 Stream &s,
Enrico Granata4becb372011-06-29 22:27:15 +00001483 const char **end,
Enrico Granatac482a192011-08-17 22:13:59 +00001484 ValueObject* valobj
Greg Clayton1b654882010-09-19 02:33:57 +00001485)
1486{
Enrico Granatac482a192011-08-17 22:13:59 +00001487 ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers
Greg Clayton1b654882010-09-19 02:33:57 +00001488 bool success = true;
1489 const char *p;
Greg Clayton5160ce52013-03-27 23:08:40 +00001490 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
Michael Sartainc3ce7f272013-05-23 20:47:45 +00001491
Greg Clayton1b654882010-09-19 02:33:57 +00001492 for (p = format; *p != '\0'; ++p)
1493 {
Enrico Granatac482a192011-08-17 22:13:59 +00001494 if (realvalobj)
Enrico Granata4becb372011-06-29 22:27:15 +00001495 {
Enrico Granatac482a192011-08-17 22:13:59 +00001496 valobj = realvalobj;
1497 realvalobj = NULL;
Enrico Granata4becb372011-06-29 22:27:15 +00001498 }
Greg Clayton1b654882010-09-19 02:33:57 +00001499 size_t non_special_chars = ::strcspn (p, "${}\\");
1500 if (non_special_chars > 0)
1501 {
1502 if (success)
1503 s.Write (p, non_special_chars);
1504 p += non_special_chars;
1505 }
1506
1507 if (*p == '\0')
1508 {
1509 break;
1510 }
1511 else if (*p == '{')
1512 {
1513 // Start a new scope that must have everything it needs if it is to
1514 // to make it into the final output stream "s". If you want to make
1515 // a format that only prints out the function or symbol name if there
1516 // is one in the symbol context you can use:
1517 // "{function =${function.name}}"
1518 // The first '{' starts a new scope that end with the matching '}' at
1519 // the end of the string. The contents "function =${function.name}"
1520 // will then be evaluated and only be output if there is a function
1521 // or symbol with a valid name.
1522 StreamString sub_strm;
1523
1524 ++p; // Skip the '{'
Michael Sartainc3ce7f272013-05-23 20:47:45 +00001525
1526 if (FormatPromptRecurse (p, sc, exe_ctx, addr, sub_strm, &p, valobj))
Greg Clayton1b654882010-09-19 02:33:57 +00001527 {
1528 // The stream had all it needed
1529 s.Write(sub_strm.GetData(), sub_strm.GetSize());
1530 }
1531 if (*p != '}')
1532 {
1533 success = false;
1534 break;
1535 }
1536 }
1537 else if (*p == '}')
1538 {
1539 // End of a enclosing scope
1540 break;
1541 }
1542 else if (*p == '$')
1543 {
1544 // We have a prompt variable to print
1545 ++p;
1546 if (*p == '{')
1547 {
1548 ++p;
1549 const char *var_name_begin = p;
1550 const char *var_name_end = ::strchr (p, '}');
1551
1552 if (var_name_end && var_name_begin < var_name_end)
1553 {
1554 // if we have already failed to parse, skip this variable
1555 if (success)
1556 {
1557 const char *cstr = NULL;
Michael Sartain0769b2b2013-07-30 16:44:36 +00001558 std::string token_format;
Greg Clayton1b654882010-09-19 02:33:57 +00001559 Address format_addr;
1560 bool calculate_format_addr_function_offset = false;
1561 // Set reg_kind and reg_num to invalid values
1562 RegisterKind reg_kind = kNumRegisterKinds;
1563 uint32_t reg_num = LLDB_INVALID_REGNUM;
1564 FileSpec format_file_spec;
Greg Claytone0d378b2011-03-24 21:19:54 +00001565 const RegisterInfo *reg_info = NULL;
Greg Clayton1b654882010-09-19 02:33:57 +00001566 RegisterContext *reg_ctx = NULL;
Enrico Granata9fc19442011-07-06 02:13:41 +00001567 bool do_deref_pointer = false;
Enrico Granata86cc9822012-03-19 22:58:49 +00001568 ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
1569 ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001570
Greg Clayton1b654882010-09-19 02:33:57 +00001571 // Each variable must set success to true below...
1572 bool var_success = false;
1573 switch (var_name_begin[0])
1574 {
Enrico Granata4becb372011-06-29 22:27:15 +00001575 case '*':
Enrico Granata4becb372011-06-29 22:27:15 +00001576 case 'v':
Enrico Granata6f3533f2011-07-29 19:53:35 +00001577 case 's':
Enrico Granata4becb372011-06-29 22:27:15 +00001578 {
Enrico Granatac482a192011-08-17 22:13:59 +00001579 if (!valobj)
Enrico Granata6f3533f2011-07-29 19:53:35 +00001580 break;
1581
Enrico Granatac3e320a2011-08-02 17:27:39 +00001582 if (log)
Enrico Granatad2284832012-10-17 22:23:56 +00001583 log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
Enrico Granatac3e320a2011-08-02 17:27:39 +00001584
Enrico Granata6f3533f2011-07-29 19:53:35 +00001585 // check for *var and *svar
1586 if (*var_name_begin == '*')
1587 {
1588 do_deref_pointer = true;
1589 var_name_begin++;
Enrico Granata68ae4112013-06-18 18:23:07 +00001590 if (log)
1591 log->Printf("[Debugger::FormatPrompt] found a deref, new string is: %s",var_name_begin);
Enrico Granata6f3533f2011-07-29 19:53:35 +00001592 }
Enrico Granatac3e320a2011-08-02 17:27:39 +00001593
Enrico Granata6f3533f2011-07-29 19:53:35 +00001594 if (*var_name_begin == 's')
1595 {
Enrico Granatac5bc4122012-03-27 02:35:13 +00001596 if (!valobj->IsSynthetic())
1597 valobj = valobj->GetSyntheticValue().get();
Enrico Granata86cc9822012-03-19 22:58:49 +00001598 if (!valobj)
1599 break;
Enrico Granata6f3533f2011-07-29 19:53:35 +00001600 var_name_begin++;
Enrico Granata68ae4112013-06-18 18:23:07 +00001601 if (log)
1602 log->Printf("[Debugger::FormatPrompt] found a synthetic, new string is: %s",var_name_begin);
Enrico Granata6f3533f2011-07-29 19:53:35 +00001603 }
1604
1605 // should be a 'v' by now
1606 if (*var_name_begin != 'v')
1607 break;
1608
Enrico Granatac3e320a2011-08-02 17:27:39 +00001609 if (log)
Enrico Granata68ae4112013-06-18 18:23:07 +00001610 log->Printf("[Debugger::FormatPrompt] string I am working with: %s",var_name_begin);
Enrico Granatac3e320a2011-08-02 17:27:39 +00001611
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001612 ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
Enrico Granata86cc9822012-03-19 22:58:49 +00001613 ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001614 ValueObject::GetValueForExpressionPathOptions options;
Enrico Granata8c9d3562011-08-11 17:08:01 +00001615 options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
Enrico Granata86cc9822012-03-19 22:58:49 +00001616 ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
Greg Clayton34132752011-07-06 04:07:21 +00001617 ValueObject* target = NULL;
Greg Clayton4d122c42011-09-17 08:33:22 +00001618 Format custom_format = eFormatInvalid;
Greg Clayton34132752011-07-06 04:07:21 +00001619 const char* var_name_final = NULL;
1620 const char* var_name_final_if_array_range = NULL;
1621 const char* close_bracket_position = NULL;
1622 int64_t index_lower = -1;
1623 int64_t index_higher = -1;
1624 bool is_array_range = false;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001625 const char* first_unparsed;
Enrico Granata85933ed2011-08-18 16:38:26 +00001626 bool was_plain_var = false;
1627 bool was_var_format = false;
Enrico Granataa777dc22012-05-08 21:49:57 +00001628 bool was_var_indexed = false;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001629
Enrico Granatac482a192011-08-17 22:13:59 +00001630 if (!valobj) break;
1631 // simplest case ${var}, just print valobj's value
Michael Sartain0769b2b2013-07-30 16:44:36 +00001632 if (IsToken (var_name_begin, "var}"))
Enrico Granata4becb372011-06-29 22:27:15 +00001633 {
Enrico Granata85933ed2011-08-18 16:38:26 +00001634 was_plain_var = true;
Enrico Granatac482a192011-08-17 22:13:59 +00001635 target = valobj;
Enrico Granata86cc9822012-03-19 22:58:49 +00001636 val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
Greg Clayton34132752011-07-06 04:07:21 +00001637 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00001638 else if (IsToken (var_name_begin,"var%"))
Greg Clayton34132752011-07-06 04:07:21 +00001639 {
Enrico Granata85933ed2011-08-18 16:38:26 +00001640 was_var_format = true;
Greg Clayton34132752011-07-06 04:07:21 +00001641 // this is a variable with some custom format applied to it
1642 const char* percent_position;
Enrico Granatac482a192011-08-17 22:13:59 +00001643 target = valobj;
Enrico Granata86cc9822012-03-19 22:58:49 +00001644 val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
Greg Clayton34132752011-07-06 04:07:21 +00001645 ScanFormatDescriptor (var_name_begin,
1646 var_name_end,
1647 &var_name_final,
1648 &percent_position,
1649 &custom_format,
1650 &val_obj_display);
1651 }
1652 // this is ${var.something} or multiple .something nested
Michael Sartain0769b2b2013-07-30 16:44:36 +00001653 else if (IsToken (var_name_begin, "var"))
Greg Clayton34132752011-07-06 04:07:21 +00001654 {
Michael Sartain0769b2b2013-07-30 16:44:36 +00001655 if (IsToken (var_name_begin, "var["))
Enrico Granataa777dc22012-05-08 21:49:57 +00001656 was_var_indexed = true;
Greg Clayton34132752011-07-06 04:07:21 +00001657 const char* percent_position;
1658 ScanFormatDescriptor (var_name_begin,
1659 var_name_end,
1660 &var_name_final,
1661 &percent_position,
1662 &custom_format,
1663 &val_obj_display);
1664
1665 const char* open_bracket_position;
1666 const char* separator_position;
1667 ScanBracketedRange (var_name_begin,
1668 var_name_end,
1669 var_name_final,
1670 &open_bracket_position,
1671 &separator_position,
1672 &close_bracket_position,
1673 &var_name_final_if_array_range,
1674 &index_lower,
1675 &index_higher);
1676
1677 Error error;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001678
Enrico Granata599171a2013-02-01 23:59:44 +00001679 std::string expr_path(var_name_final-var_name_begin-1,0);
1680 memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3);
1681
1682 if (log)
1683 log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str());
1684
1685 target = valobj->GetValueForExpressionPath(expr_path.c_str(),
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001686 &first_unparsed,
1687 &reason_to_stop,
1688 &final_value_type,
1689 options,
1690 &what_next).get();
1691
1692 if (!target)
Enrico Granata9fc19442011-07-06 02:13:41 +00001693 {
Enrico Granatae992a082011-07-22 17:03:19 +00001694 if (log)
Enrico Granatad2284832012-10-17 22:23:56 +00001695 log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d,"
Enrico Granatae992a082011-07-22 17:03:19 +00001696 " final_value_type %d",
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001697 first_unparsed, reason_to_stop, final_value_type);
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001698 break;
Enrico Granata9fc19442011-07-06 02:13:41 +00001699 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001700 else
1701 {
Enrico Granatae992a082011-07-22 17:03:19 +00001702 if (log)
Enrico Granatad2284832012-10-17 22:23:56 +00001703 log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
Enrico Granatae992a082011-07-22 17:03:19 +00001704 " final_value_type %d",
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001705 first_unparsed, reason_to_stop, final_value_type);
1706 }
Enrico Granata4becb372011-06-29 22:27:15 +00001707 }
Greg Clayton34132752011-07-06 04:07:21 +00001708 else
Enrico Granata9fc19442011-07-06 02:13:41 +00001709 break;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001710
Enrico Granata86cc9822012-03-19 22:58:49 +00001711 is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
1712 final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001713
Enrico Granata86cc9822012-03-19 22:58:49 +00001714 do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference);
Enrico Granata9fc19442011-07-06 02:13:41 +00001715
Enrico Granataa7187d02011-07-06 19:27:11 +00001716 if (do_deref_pointer && !is_array_range)
Enrico Granata9fc19442011-07-06 02:13:41 +00001717 {
Greg Clayton34132752011-07-06 04:07:21 +00001718 // I have not deref-ed yet, let's do it
1719 // this happens when we are not going through GetValueForVariableExpressionPath
1720 // to get to the target ValueObject
Enrico Granata9fc19442011-07-06 02:13:41 +00001721 Error error;
Greg Clayton34132752011-07-06 04:07:21 +00001722 target = target->Dereference(error).get();
Enrico Granatadc940732011-08-23 00:32:52 +00001723 if (error.Fail())
1724 {
1725 if (log)
Enrico Granatad2284832012-10-17 22:23:56 +00001726 log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \
Enrico Granatadc940732011-08-23 00:32:52 +00001727 break;
1728 }
Greg Clayton34132752011-07-06 04:07:21 +00001729 do_deref_pointer = false;
Enrico Granata9fc19442011-07-06 02:13:41 +00001730 }
Enrico Granataf4efecd2011-07-12 22:56:10 +00001731
Enrico Granataa777dc22012-05-08 21:49:57 +00001732 // we do not want to use the summary for a bitfield of type T:n
1733 // if we were originally dealing with just a T - that would get
1734 // us into an endless recursion
1735 if (target->IsBitfield() && was_var_indexed)
1736 {
1737 // TODO: check for a (T:n)-specific summary - we should still obey that
1738 StreamString bitfield_name;
1739 bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize());
1740 lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false));
1741 if (!DataVisualization::GetSummaryForType(type_sp))
1742 val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1743 }
1744
Enrico Granata85933ed2011-08-18 16:38:26 +00001745 // TODO use flags for these
Greg Clayton57ee3062013-07-11 22:46:58 +00001746 const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL);
1747 bool is_array = (type_info_flags & ClangASTType::eTypeIsArray) != 0;
1748 bool is_pointer = (type_info_flags & ClangASTType::eTypeIsPointer) != 0;
1749 bool is_aggregate = target->GetClangType().IsAggregateType();
Enrico Granataf4efecd2011-07-12 22:56:10 +00001750
Enrico Granata86cc9822012-03-19 22:58:49 +00001751 if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
Enrico Granataf4efecd2011-07-12 22:56:10 +00001752 {
Enrico Granata85933ed2011-08-18 16:38:26 +00001753 StreamString str_temp;
Enrico Granatae992a082011-07-22 17:03:19 +00001754 if (log)
Enrico Granatad2284832012-10-17 22:23:56 +00001755 log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range");
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001756
Greg Clayton5088c482013-03-25 21:06:13 +00001757 if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format))
Enrico Granata85933ed2011-08-18 16:38:26 +00001758 {
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001759 // try to use the special cases
1760 var_success = target->DumpPrintableRepresentation(str_temp,
1761 val_obj_display,
1762 custom_format);
1763 if (log)
Enrico Granatad2284832012-10-17 22:23:56 +00001764 log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't");
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001765
1766 // should not happen
Greg Clayton5088c482013-03-25 21:06:13 +00001767 if (var_success)
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001768 s << str_temp.GetData();
Enrico Granata85933ed2011-08-18 16:38:26 +00001769 var_success = true;
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001770 break;
Enrico Granata85933ed2011-08-18 16:38:26 +00001771 }
1772 else
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001773 {
Enrico Granata88da35f2011-08-23 21:26:09 +00001774 if (was_plain_var) // if ${var}
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001775 {
1776 s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1777 }
Enrico Granata88da35f2011-08-23 21:26:09 +00001778 else if (is_pointer) // if pointer, value is the address stored
1779 {
Greg Clayton23f59502012-07-17 03:23:13 +00001780 target->DumpPrintableRepresentation (s,
1781 val_obj_display,
1782 custom_format,
1783 ValueObject::ePrintableRepresentationSpecialCasesDisable);
Enrico Granata88da35f2011-08-23 21:26:09 +00001784 }
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001785 var_success = true;
1786 break;
1787 }
1788 }
1789
1790 // if directly trying to print ${var}, and this is an aggregate, display a nice
1791 // type @ location message
1792 if (is_aggregate && was_plain_var)
1793 {
1794 s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1795 var_success = true;
Enrico Granata85933ed2011-08-18 16:38:26 +00001796 break;
1797 }
1798
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001799 // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
Enrico Granata86cc9822012-03-19 22:58:49 +00001800 if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)))
Enrico Granata85933ed2011-08-18 16:38:26 +00001801 {
1802 s << "<invalid use of aggregate type>";
1803 var_success = true;
Enrico Granataf4efecd2011-07-12 22:56:10 +00001804 break;
1805 }
Greg Clayton34132752011-07-06 04:07:21 +00001806
1807 if (!is_array_range)
Enrico Granatae992a082011-07-22 17:03:19 +00001808 {
1809 if (log)
Enrico Granatad2284832012-10-17 22:23:56 +00001810 log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output");
Greg Clayton34132752011-07-06 04:07:21 +00001811 var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
Enrico Granatae992a082011-07-22 17:03:19 +00001812 }
Greg Clayton34132752011-07-06 04:07:21 +00001813 else
Enrico Granatae992a082011-07-22 17:03:19 +00001814 {
1815 if (log)
Enrico Granatad2284832012-10-17 22:23:56 +00001816 log->Printf("[Debugger::FormatPrompt] checking if I can handle as array");
Greg Clayton34132752011-07-06 04:07:21 +00001817 if (!is_array && !is_pointer)
1818 break;
Enrico Granatae992a082011-07-22 17:03:19 +00001819 if (log)
Enrico Granatad2284832012-10-17 22:23:56 +00001820 log->Printf("[Debugger::FormatPrompt] handle as array");
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001821 const char* special_directions = NULL;
1822 StreamString special_directions_writer;
Greg Clayton34132752011-07-06 04:07:21 +00001823 if (close_bracket_position && (var_name_end-close_bracket_position > 1))
1824 {
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001825 ConstString additional_data;
1826 additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1);
1827 special_directions_writer.Printf("${%svar%s}",
1828 do_deref_pointer ? "*" : "",
1829 additional_data.GetCString());
1830 special_directions = special_directions_writer.GetData();
Greg Clayton34132752011-07-06 04:07:21 +00001831 }
1832
1833 // let us display items index_lower thru index_higher of this array
1834 s.PutChar('[');
1835 var_success = true;
1836
1837 if (index_higher < 0)
Enrico Granatac482a192011-08-17 22:13:59 +00001838 index_higher = valobj->GetNumChildren() - 1;
Greg Clayton34132752011-07-06 04:07:21 +00001839
Greg Claytoncc4d0142012-02-17 07:49:44 +00001840 uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
Enrico Granata22c55d12011-08-12 02:00:06 +00001841
Greg Clayton34132752011-07-06 04:07:21 +00001842 for (;index_lower<=index_higher;index_lower++)
1843 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001844 ValueObject* item = ExpandIndexedExpression (target,
1845 index_lower,
1846 exe_ctx->GetFramePtr(),
1847 false).get();
Greg Clayton34132752011-07-06 04:07:21 +00001848
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001849 if (!item)
1850 {
Enrico Granatae992a082011-07-22 17:03:19 +00001851 if (log)
Daniel Malead01b2952012-11-29 21:49:15 +00001852 log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower);
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001853 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001854 else
1855 {
Enrico Granatae992a082011-07-22 17:03:19 +00001856 if (log)
Enrico Granatad2284832012-10-17 22:23:56 +00001857 log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions);
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001858 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001859
Greg Clayton34132752011-07-06 04:07:21 +00001860 if (!special_directions)
1861 var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1862 else
Michael Sartainc3ce7f272013-05-23 20:47:45 +00001863 var_success &= FormatPromptRecurse(special_directions, sc, exe_ctx, addr, s, NULL, item);
Greg Clayton34132752011-07-06 04:07:21 +00001864
Enrico Granata22c55d12011-08-12 02:00:06 +00001865 if (--max_num_children == 0)
1866 {
1867 s.PutCString(", ...");
1868 break;
1869 }
1870
Greg Clayton34132752011-07-06 04:07:21 +00001871 if (index_lower < index_higher)
1872 s.PutChar(',');
1873 }
1874 s.PutChar(']');
1875 }
Enrico Granata4becb372011-06-29 22:27:15 +00001876 }
Enrico Granata9fc19442011-07-06 02:13:41 +00001877 break;
Greg Clayton1b654882010-09-19 02:33:57 +00001878 case 'a':
Michael Sartain0769b2b2013-07-30 16:44:36 +00001879 if (IsToken (var_name_begin, "addr}"))
Greg Clayton1b654882010-09-19 02:33:57 +00001880 {
1881 if (addr && addr->IsValid())
1882 {
1883 var_success = true;
1884 format_addr = *addr;
1885 }
1886 }
1887 break;
1888
1889 case 'p':
Michael Sartain0769b2b2013-07-30 16:44:36 +00001890 if (IsToken (var_name_begin, "process."))
Greg Clayton1b654882010-09-19 02:33:57 +00001891 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001892 if (exe_ctx)
Greg Clayton1b654882010-09-19 02:33:57 +00001893 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001894 Process *process = exe_ctx->GetProcessPtr();
1895 if (process)
Greg Clayton1b654882010-09-19 02:33:57 +00001896 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001897 var_name_begin += ::strlen ("process.");
Michael Sartain0769b2b2013-07-30 16:44:36 +00001898 if (IsTokenWithFormat (var_name_begin, "id", token_format, "%" PRIu64, exe_ctx, sc))
Greg Clayton1b654882010-09-19 02:33:57 +00001899 {
Michael Sartain0769b2b2013-07-30 16:44:36 +00001900 s.Printf(token_format.c_str(), process->GetID());
Greg Claytonc14ee322011-09-22 04:58:26 +00001901 var_success = true;
1902 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00001903 else if ((IsToken (var_name_begin, "name}")) ||
1904 (IsToken (var_name_begin, "file.basename}")) ||
1905 (IsToken (var_name_begin, "file.fullpath}")))
Greg Claytonc14ee322011-09-22 04:58:26 +00001906 {
1907 Module *exe_module = process->GetTarget().GetExecutableModulePointer();
1908 if (exe_module)
Greg Clayton1b654882010-09-19 02:33:57 +00001909 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001910 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
1911 {
1912 format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename();
Sean Callanan9076c0f2013-10-04 21:35:29 +00001913 var_success = (bool)format_file_spec;
Greg Claytonc14ee322011-09-22 04:58:26 +00001914 }
1915 else
1916 {
1917 format_file_spec = exe_module->GetFileSpec();
Sean Callanan9076c0f2013-10-04 21:35:29 +00001918 var_success = (bool)format_file_spec;
Greg Claytonc14ee322011-09-22 04:58:26 +00001919 }
Greg Clayton1b654882010-09-19 02:33:57 +00001920 }
1921 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00001922 else if (IsToken (var_name_begin, "script:"))
Enrico Granataaad8e482013-06-20 23:40:21 +00001923 {
1924 var_name_begin += ::strlen("script:");
1925 std::string script_name(var_name_begin,var_name_end);
1926 ScriptInterpreter* script_interpreter = process->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
Michael Sartain0769b2b2013-07-30 16:44:36 +00001927 if (RunScriptFormatKeyword (s, script_interpreter, process, script_name))
1928 var_success = true;
Enrico Granataaad8e482013-06-20 23:40:21 +00001929 }
Greg Clayton1b654882010-09-19 02:33:57 +00001930 }
Greg Claytonc14ee322011-09-22 04:58:26 +00001931 }
Greg Clayton1b654882010-09-19 02:33:57 +00001932 }
1933 break;
1934
1935 case 't':
Michael Sartain0769b2b2013-07-30 16:44:36 +00001936 if (IsToken (var_name_begin, "thread."))
Greg Clayton1b654882010-09-19 02:33:57 +00001937 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001938 if (exe_ctx)
Greg Clayton1b654882010-09-19 02:33:57 +00001939 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001940 Thread *thread = exe_ctx->GetThreadPtr();
1941 if (thread)
Greg Clayton1b654882010-09-19 02:33:57 +00001942 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001943 var_name_begin += ::strlen ("thread.");
Michael Sartain0769b2b2013-07-30 16:44:36 +00001944 if (IsTokenWithFormat (var_name_begin, "id", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
Greg Clayton1b654882010-09-19 02:33:57 +00001945 {
Michael Sartain0769b2b2013-07-30 16:44:36 +00001946 s.Printf(token_format.c_str(), thread->GetID());
Greg Claytonc14ee322011-09-22 04:58:26 +00001947 var_success = true;
1948 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00001949 else if (IsTokenWithFormat (var_name_begin, "protocol_id", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
Greg Clayton160c9d82013-05-01 21:54:04 +00001950 {
Michael Sartain0769b2b2013-07-30 16:44:36 +00001951 s.Printf(token_format.c_str(), thread->GetProtocolID());
Greg Clayton160c9d82013-05-01 21:54:04 +00001952 var_success = true;
1953 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00001954 else if (IsTokenWithFormat (var_name_begin, "index", token_format, "%" PRIu64, exe_ctx, sc))
Greg Claytonc14ee322011-09-22 04:58:26 +00001955 {
Michael Sartain0769b2b2013-07-30 16:44:36 +00001956 s.Printf(token_format.c_str(), (uint64_t)thread->GetIndexID());
Greg Claytonc14ee322011-09-22 04:58:26 +00001957 var_success = true;
1958 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00001959 else if (IsToken (var_name_begin, "name}"))
Greg Claytonc14ee322011-09-22 04:58:26 +00001960 {
1961 cstr = thread->GetName();
1962 var_success = cstr && cstr[0];
1963 if (var_success)
Greg Clayton1b654882010-09-19 02:33:57 +00001964 s.PutCString(cstr);
Greg Claytonc14ee322011-09-22 04:58:26 +00001965 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00001966 else if (IsToken (var_name_begin, "queue}"))
Greg Claytonc14ee322011-09-22 04:58:26 +00001967 {
1968 cstr = thread->GetQueueName();
1969 var_success = cstr && cstr[0];
1970 if (var_success)
1971 s.PutCString(cstr);
1972 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00001973 else if (IsToken (var_name_begin, "stop-reason}"))
Greg Claytonc14ee322011-09-22 04:58:26 +00001974 {
1975 StopInfoSP stop_info_sp = thread->GetStopInfo ();
Jim Ingham5d88a062012-10-16 00:09:33 +00001976 if (stop_info_sp && stop_info_sp->IsValid())
Greg Claytonc14ee322011-09-22 04:58:26 +00001977 {
1978 cstr = stop_info_sp->GetDescription();
1979 if (cstr && cstr[0])
1980 {
1981 s.PutCString(cstr);
1982 var_success = true;
1983 }
Greg Clayton1b654882010-09-19 02:33:57 +00001984 }
1985 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00001986 else if (IsToken (var_name_begin, "return-value}"))
Jim Ingham73ca05a2011-12-17 01:35:57 +00001987 {
1988 StopInfoSP stop_info_sp = thread->GetStopInfo ();
Jim Ingham5d88a062012-10-16 00:09:33 +00001989 if (stop_info_sp && stop_info_sp->IsValid())
Jim Ingham73ca05a2011-12-17 01:35:57 +00001990 {
1991 ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
1992 if (return_valobj_sp)
1993 {
Enrico Granata4d93b8c2013-09-30 19:11:51 +00001994 return_valobj_sp->Dump(s);
Jim Inghamef651602011-12-22 19:12:40 +00001995 var_success = true;
Jim Ingham73ca05a2011-12-17 01:35:57 +00001996 }
1997 }
1998 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00001999 else if (IsToken (var_name_begin, "script:"))
Enrico Granataaad8e482013-06-20 23:40:21 +00002000 {
2001 var_name_begin += ::strlen("script:");
2002 std::string script_name(var_name_begin,var_name_end);
2003 ScriptInterpreter* script_interpreter = thread->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
Michael Sartain0769b2b2013-07-30 16:44:36 +00002004 if (RunScriptFormatKeyword (s, script_interpreter, thread, script_name))
2005 var_success = true;
Enrico Granataaad8e482013-06-20 23:40:21 +00002006 }
Greg Clayton1b654882010-09-19 02:33:57 +00002007 }
2008 }
2009 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00002010 else if (IsToken (var_name_begin, "target."))
Greg Clayton1b654882010-09-19 02:33:57 +00002011 {
Greg Clayton67cc0632012-08-22 17:17:09 +00002012 // TODO: hookup properties
2013// if (!target_properties_sp)
2014// {
2015// Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
2016// if (target)
2017// target_properties_sp = target->GetProperties();
2018// }
2019//
2020// if (target_properties_sp)
2021// {
2022// var_name_begin += ::strlen ("target.");
2023// const char *end_property = strchr(var_name_begin, '}');
2024// if (end_property)
2025// {
2026// ConstString property_name(var_name_begin, end_property - var_name_begin);
2027// std::string property_value (target_properties_sp->GetPropertyValue(property_name));
2028// if (!property_value.empty())
2029// {
2030// s.PutCString (property_value.c_str());
2031// var_success = true;
2032// }
2033// }
2034// }
Greg Clayton0603aa92010-10-04 01:05:56 +00002035 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
2036 if (target)
Greg Clayton1b654882010-09-19 02:33:57 +00002037 {
Greg Clayton1b654882010-09-19 02:33:57 +00002038 var_name_begin += ::strlen ("target.");
Michael Sartain0769b2b2013-07-30 16:44:36 +00002039 if (IsToken (var_name_begin, "arch}"))
Greg Clayton1b654882010-09-19 02:33:57 +00002040 {
2041 ArchSpec arch (target->GetArchitecture ());
2042 if (arch.IsValid())
2043 {
Greg Clayton64195a22011-02-23 00:35:02 +00002044 s.PutCString (arch.GetArchitectureName());
Greg Clayton1b654882010-09-19 02:33:57 +00002045 var_success = true;
2046 }
2047 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00002048 else if (IsToken (var_name_begin, "script:"))
Enrico Granataaad8e482013-06-20 23:40:21 +00002049 {
2050 var_name_begin += ::strlen("script:");
2051 std::string script_name(var_name_begin,var_name_end);
2052 ScriptInterpreter* script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
Michael Sartain0769b2b2013-07-30 16:44:36 +00002053 if (RunScriptFormatKeyword (s, script_interpreter, target, script_name))
2054 var_success = true;
Enrico Granataaad8e482013-06-20 23:40:21 +00002055 }
Greg Clayton67cc0632012-08-22 17:17:09 +00002056 }
Greg Clayton1b654882010-09-19 02:33:57 +00002057 }
2058 break;
2059
2060
2061 case 'm':
Michael Sartain0769b2b2013-07-30 16:44:36 +00002062 if (IsToken (var_name_begin, "module."))
Greg Clayton1b654882010-09-19 02:33:57 +00002063 {
Greg Clayton0603aa92010-10-04 01:05:56 +00002064 if (sc && sc->module_sp.get())
Greg Clayton1b654882010-09-19 02:33:57 +00002065 {
Greg Clayton0603aa92010-10-04 01:05:56 +00002066 Module *module = sc->module_sp.get();
Greg Clayton1b654882010-09-19 02:33:57 +00002067 var_name_begin += ::strlen ("module.");
2068
Michael Sartain0769b2b2013-07-30 16:44:36 +00002069 if (IsToken (var_name_begin, "file."))
Greg Clayton1b654882010-09-19 02:33:57 +00002070 {
2071 if (module->GetFileSpec())
2072 {
2073 var_name_begin += ::strlen ("file.");
2074
Michael Sartain0769b2b2013-07-30 16:44:36 +00002075 if (IsToken (var_name_begin, "basename}"))
Greg Clayton1b654882010-09-19 02:33:57 +00002076 {
2077 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
Sean Callanan9076c0f2013-10-04 21:35:29 +00002078 var_success = (bool)format_file_spec;
Greg Clayton1b654882010-09-19 02:33:57 +00002079 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00002080 else if (IsToken (var_name_begin, "fullpath}"))
Greg Clayton1b654882010-09-19 02:33:57 +00002081 {
2082 format_file_spec = module->GetFileSpec();
Sean Callanan9076c0f2013-10-04 21:35:29 +00002083 var_success = (bool)format_file_spec;
Greg Clayton1b654882010-09-19 02:33:57 +00002084 }
2085 }
2086 }
2087 }
2088 }
2089 break;
2090
2091
2092 case 'f':
Michael Sartain0769b2b2013-07-30 16:44:36 +00002093 if (IsToken (var_name_begin, "file."))
Greg Clayton1b654882010-09-19 02:33:57 +00002094 {
2095 if (sc && sc->comp_unit != NULL)
2096 {
2097 var_name_begin += ::strlen ("file.");
2098
Michael Sartain0769b2b2013-07-30 16:44:36 +00002099 if (IsToken (var_name_begin, "basename}"))
Greg Clayton1b654882010-09-19 02:33:57 +00002100 {
2101 format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
Sean Callanan9076c0f2013-10-04 21:35:29 +00002102 var_success = (bool)format_file_spec;
Greg Clayton1b654882010-09-19 02:33:57 +00002103 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00002104 else if (IsToken (var_name_begin, "fullpath}"))
Greg Clayton1b654882010-09-19 02:33:57 +00002105 {
2106 format_file_spec = *sc->comp_unit;
Sean Callanan9076c0f2013-10-04 21:35:29 +00002107 var_success = (bool)format_file_spec;
Greg Clayton1b654882010-09-19 02:33:57 +00002108 }
2109 }
2110 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00002111 else if (IsToken (var_name_begin, "frame."))
Greg Clayton1b654882010-09-19 02:33:57 +00002112 {
Greg Claytonc14ee322011-09-22 04:58:26 +00002113 if (exe_ctx)
Greg Clayton1b654882010-09-19 02:33:57 +00002114 {
Jason Molendab57e4a12013-11-04 09:33:30 +00002115 StackFrame *frame = exe_ctx->GetFramePtr();
Greg Claytonc14ee322011-09-22 04:58:26 +00002116 if (frame)
Greg Clayton1b654882010-09-19 02:33:57 +00002117 {
Greg Claytonc14ee322011-09-22 04:58:26 +00002118 var_name_begin += ::strlen ("frame.");
Michael Sartain0769b2b2013-07-30 16:44:36 +00002119 if (IsToken (var_name_begin, "index}"))
Greg Clayton1b654882010-09-19 02:33:57 +00002120 {
Greg Claytonc14ee322011-09-22 04:58:26 +00002121 s.Printf("%u", frame->GetFrameIndex());
2122 var_success = true;
2123 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00002124 else if (IsToken (var_name_begin, "pc}"))
Greg Claytonc14ee322011-09-22 04:58:26 +00002125 {
2126 reg_kind = eRegisterKindGeneric;
2127 reg_num = LLDB_REGNUM_GENERIC_PC;
2128 var_success = true;
2129 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00002130 else if (IsToken (var_name_begin, "sp}"))
Greg Claytonc14ee322011-09-22 04:58:26 +00002131 {
2132 reg_kind = eRegisterKindGeneric;
2133 reg_num = LLDB_REGNUM_GENERIC_SP;
2134 var_success = true;
2135 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00002136 else if (IsToken (var_name_begin, "fp}"))
Greg Claytonc14ee322011-09-22 04:58:26 +00002137 {
2138 reg_kind = eRegisterKindGeneric;
2139 reg_num = LLDB_REGNUM_GENERIC_FP;
2140 var_success = true;
2141 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00002142 else if (IsToken (var_name_begin, "flags}"))
Greg Claytonc14ee322011-09-22 04:58:26 +00002143 {
2144 reg_kind = eRegisterKindGeneric;
2145 reg_num = LLDB_REGNUM_GENERIC_FLAGS;
2146 var_success = true;
2147 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00002148 else if (IsToken (var_name_begin, "reg."))
Greg Claytonc14ee322011-09-22 04:58:26 +00002149 {
2150 reg_ctx = frame->GetRegisterContext().get();
2151 if (reg_ctx)
Greg Clayton1b654882010-09-19 02:33:57 +00002152 {
Greg Claytonc14ee322011-09-22 04:58:26 +00002153 var_name_begin += ::strlen ("reg.");
2154 if (var_name_begin < var_name_end)
2155 {
2156 std::string reg_name (var_name_begin, var_name_end);
2157 reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
2158 if (reg_info)
2159 var_success = true;
2160 }
Greg Clayton1b654882010-09-19 02:33:57 +00002161 }
2162 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00002163 else if (IsToken (var_name_begin, "script:"))
Enrico Granataaad8e482013-06-20 23:40:21 +00002164 {
2165 var_name_begin += ::strlen("script:");
2166 std::string script_name(var_name_begin,var_name_end);
2167 ScriptInterpreter* script_interpreter = frame->GetThread()->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
Michael Sartain0769b2b2013-07-30 16:44:36 +00002168 if (RunScriptFormatKeyword (s, script_interpreter, frame, script_name))
2169 var_success = true;
Enrico Granataaad8e482013-06-20 23:40:21 +00002170 }
Greg Clayton1b654882010-09-19 02:33:57 +00002171 }
2172 }
2173 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00002174 else if (IsToken (var_name_begin, "function."))
Greg Clayton1b654882010-09-19 02:33:57 +00002175 {
2176 if (sc && (sc->function != NULL || sc->symbol != NULL))
2177 {
2178 var_name_begin += ::strlen ("function.");
Michael Sartain0769b2b2013-07-30 16:44:36 +00002179 if (IsToken (var_name_begin, "id}"))
Greg Clayton1b654882010-09-19 02:33:57 +00002180 {
2181 if (sc->function)
Daniel Malead01b2952012-11-29 21:49:15 +00002182 s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID());
Greg Clayton1b654882010-09-19 02:33:57 +00002183 else
2184 s.Printf("symbol[%u]", sc->symbol->GetID());
2185
2186 var_success = true;
2187 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00002188 else if (IsToken (var_name_begin, "name}"))
Greg Clayton1b654882010-09-19 02:33:57 +00002189 {
2190 if (sc->function)
2191 cstr = sc->function->GetName().AsCString (NULL);
2192 else if (sc->symbol)
2193 cstr = sc->symbol->GetName().AsCString (NULL);
2194 if (cstr)
2195 {
2196 s.PutCString(cstr);
Greg Clayton0d9c9932010-10-04 17:26:49 +00002197
2198 if (sc->block)
2199 {
2200 Block *inline_block = sc->block->GetContainingInlinedBlock ();
2201 if (inline_block)
2202 {
2203 const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
2204 if (inline_info)
2205 {
2206 s.PutCString(" [inlined] ");
2207 inline_info->GetName().Dump(&s);
2208 }
2209 }
2210 }
Greg Clayton1b654882010-09-19 02:33:57 +00002211 var_success = true;
2212 }
2213 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00002214 else if (IsToken (var_name_begin, "name-with-args}"))
Greg Clayton6d3dbf52012-01-13 08:39:16 +00002215 {
2216 // Print the function name with arguments in it
2217
2218 if (sc->function)
2219 {
2220 var_success = true;
2221 ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
2222 cstr = sc->function->GetName().AsCString (NULL);
2223 if (cstr)
2224 {
2225 const InlineFunctionInfo *inline_info = NULL;
2226 VariableListSP variable_list_sp;
2227 bool get_function_vars = true;
2228 if (sc->block)
2229 {
2230 Block *inline_block = sc->block->GetContainingInlinedBlock ();
2231
2232 if (inline_block)
2233 {
2234 get_function_vars = false;
2235 inline_info = sc->block->GetInlinedFunctionInfo();
2236 if (inline_info)
2237 variable_list_sp = inline_block->GetBlockVariableList (true);
2238 }
2239 }
2240
2241 if (get_function_vars)
2242 {
2243 variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
2244 }
2245
2246 if (inline_info)
2247 {
2248 s.PutCString (cstr);
2249 s.PutCString (" [inlined] ");
2250 cstr = inline_info->GetName().GetCString();
2251 }
2252
2253 VariableList args;
2254 if (variable_list_sp)
Enrico Granatacc7f9bf2013-05-08 20:27:37 +00002255 variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args);
Greg Clayton6d3dbf52012-01-13 08:39:16 +00002256 if (args.GetSize() > 0)
2257 {
2258 const char *open_paren = strchr (cstr, '(');
2259 const char *close_paren = NULL;
2260 if (open_paren)
Greg Clayton855958c2013-03-26 01:45:43 +00002261 {
Michael Sartain0769b2b2013-07-30 16:44:36 +00002262 if (IsToken (open_paren, "(anonymous namespace)"))
Greg Clayton855958c2013-03-26 01:45:43 +00002263 {
2264 open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '(');
2265 if (open_paren)
2266 close_paren = strchr (open_paren, ')');
2267 }
2268 else
2269 close_paren = strchr (open_paren, ')');
2270 }
Greg Clayton6d3dbf52012-01-13 08:39:16 +00002271
2272 if (open_paren)
2273 s.Write(cstr, open_paren - cstr + 1);
2274 else
2275 {
2276 s.PutCString (cstr);
2277 s.PutChar ('(');
2278 }
Greg Clayton5b6889b2012-01-18 21:56:18 +00002279 const size_t num_args = args.GetSize();
Greg Clayton6d3dbf52012-01-13 08:39:16 +00002280 for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx)
2281 {
2282 VariableSP var_sp (args.GetVariableAtIndex (arg_idx));
2283 ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
2284 const char *var_name = var_value_sp->GetName().GetCString();
2285 const char *var_value = var_value_sp->GetValueAsCString();
Greg Clayton3b188b12012-12-10 22:26:34 +00002286 if (arg_idx > 0)
2287 s.PutCString (", ");
Greg Clayton6d3dbf52012-01-13 08:39:16 +00002288 if (var_value_sp->GetError().Success())
Enrico Granatacc7f9bf2013-05-08 20:27:37 +00002289 {
2290 if (var_value)
2291 s.Printf ("%s=%s", var_name, var_value);
2292 else
2293 s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString());
2294 }
Greg Clayton3b188b12012-12-10 22:26:34 +00002295 else
2296 s.Printf ("%s=<unavailable>", var_name);
Greg Clayton6d3dbf52012-01-13 08:39:16 +00002297 }
2298
2299 if (close_paren)
2300 s.PutCString (close_paren);
2301 else
2302 s.PutChar(')');
2303
2304 }
2305 else
2306 {
2307 s.PutCString(cstr);
2308 }
2309 }
2310 }
2311 else if (sc->symbol)
2312 {
2313 cstr = sc->symbol->GetName().AsCString (NULL);
2314 if (cstr)
2315 {
2316 s.PutCString(cstr);
2317 var_success = true;
2318 }
2319 }
2320 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00002321 else if (IsToken (var_name_begin, "addr-offset}"))
Greg Clayton1b654882010-09-19 02:33:57 +00002322 {
2323 var_success = addr != NULL;
2324 if (var_success)
2325 {
2326 format_addr = *addr;
2327 calculate_format_addr_function_offset = true;
2328 }
2329 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00002330 else if (IsToken (var_name_begin, "line-offset}"))
Greg Clayton1b654882010-09-19 02:33:57 +00002331 {
2332 var_success = sc->line_entry.range.GetBaseAddress().IsValid();
2333 if (var_success)
2334 {
2335 format_addr = sc->line_entry.range.GetBaseAddress();
2336 calculate_format_addr_function_offset = true;
2337 }
2338 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00002339 else if (IsToken (var_name_begin, "pc-offset}"))
Greg Clayton1b654882010-09-19 02:33:57 +00002340 {
Jason Molendab57e4a12013-11-04 09:33:30 +00002341 StackFrame *frame = exe_ctx->GetFramePtr();
Greg Claytonc14ee322011-09-22 04:58:26 +00002342 var_success = frame != NULL;
Greg Clayton1b654882010-09-19 02:33:57 +00002343 if (var_success)
2344 {
Greg Claytonc14ee322011-09-22 04:58:26 +00002345 format_addr = frame->GetFrameCodeAddress();
Greg Clayton1b654882010-09-19 02:33:57 +00002346 calculate_format_addr_function_offset = true;
2347 }
2348 }
2349 }
2350 }
2351 break;
2352
2353 case 'l':
Michael Sartain0769b2b2013-07-30 16:44:36 +00002354 if (IsToken (var_name_begin, "line."))
Greg Clayton1b654882010-09-19 02:33:57 +00002355 {
2356 if (sc && sc->line_entry.IsValid())
2357 {
2358 var_name_begin += ::strlen ("line.");
Michael Sartain0769b2b2013-07-30 16:44:36 +00002359 if (IsToken (var_name_begin, "file."))
Greg Clayton1b654882010-09-19 02:33:57 +00002360 {
2361 var_name_begin += ::strlen ("file.");
2362
Michael Sartain0769b2b2013-07-30 16:44:36 +00002363 if (IsToken (var_name_begin, "basename}"))
Greg Clayton1b654882010-09-19 02:33:57 +00002364 {
2365 format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
Sean Callanan9076c0f2013-10-04 21:35:29 +00002366 var_success = (bool)format_file_spec;
Greg Clayton1b654882010-09-19 02:33:57 +00002367 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00002368 else if (IsToken (var_name_begin, "fullpath}"))
Greg Clayton1b654882010-09-19 02:33:57 +00002369 {
2370 format_file_spec = sc->line_entry.file;
Sean Callanan9076c0f2013-10-04 21:35:29 +00002371 var_success = (bool)format_file_spec;
Greg Clayton1b654882010-09-19 02:33:57 +00002372 }
2373 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00002374 else if (IsTokenWithFormat (var_name_begin, "number", token_format, "%" PRIu64, exe_ctx, sc))
Greg Clayton1b654882010-09-19 02:33:57 +00002375 {
2376 var_success = true;
Michael Sartain0769b2b2013-07-30 16:44:36 +00002377 s.Printf(token_format.c_str(), (uint64_t)sc->line_entry.line);
Greg Clayton1b654882010-09-19 02:33:57 +00002378 }
Michael Sartain0769b2b2013-07-30 16:44:36 +00002379 else if ((IsToken (var_name_begin, "start-addr}")) ||
2380 (IsToken (var_name_begin, "end-addr}")))
Greg Clayton1b654882010-09-19 02:33:57 +00002381 {
2382 var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
2383 if (var_success)
2384 {
2385 format_addr = sc->line_entry.range.GetBaseAddress();
2386 if (var_name_begin[0] == 'e')
2387 format_addr.Slide (sc->line_entry.range.GetByteSize());
2388 }
2389 }
2390 }
2391 }
2392 break;
2393 }
2394
2395 if (var_success)
2396 {
2397 // If format addr is valid, then we need to print an address
2398 if (reg_num != LLDB_INVALID_REGNUM)
2399 {
Jason Molendab57e4a12013-11-04 09:33:30 +00002400 StackFrame *frame = exe_ctx->GetFramePtr();
Greg Clayton1b654882010-09-19 02:33:57 +00002401 // We have a register value to display...
2402 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
2403 {
Greg Claytonc14ee322011-09-22 04:58:26 +00002404 format_addr = frame->GetFrameCodeAddress();
Greg Clayton1b654882010-09-19 02:33:57 +00002405 }
2406 else
2407 {
2408 if (reg_ctx == NULL)
Greg Claytonc14ee322011-09-22 04:58:26 +00002409 reg_ctx = frame->GetRegisterContext().get();
Greg Clayton1b654882010-09-19 02:33:57 +00002410
2411 if (reg_ctx)
2412 {
2413 if (reg_kind != kNumRegisterKinds)
2414 reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
2415 reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
2416 var_success = reg_info != NULL;
2417 }
2418 }
2419 }
2420
2421 if (reg_info != NULL)
2422 {
Greg Clayton7349bd92011-05-09 20:18:18 +00002423 RegisterValue reg_value;
2424 var_success = reg_ctx->ReadRegister (reg_info, reg_value);
2425 if (var_success)
Greg Clayton1b654882010-09-19 02:33:57 +00002426 {
Greg Clayton9a8fa912011-05-15 04:12:07 +00002427 reg_value.Dump(&s, reg_info, false, false, eFormatDefault);
Greg Clayton1b654882010-09-19 02:33:57 +00002428 }
2429 }
2430
2431 if (format_file_spec)
2432 {
2433 s << format_file_spec;
2434 }
2435
2436 // If format addr is valid, then we need to print an address
2437 if (format_addr.IsValid())
2438 {
Greg Clayton0603aa92010-10-04 01:05:56 +00002439 var_success = false;
2440
Greg Clayton1b654882010-09-19 02:33:57 +00002441 if (calculate_format_addr_function_offset)
2442 {
2443 Address func_addr;
Greg Clayton1b654882010-09-19 02:33:57 +00002444
Greg Clayton0603aa92010-10-04 01:05:56 +00002445 if (sc)
2446 {
2447 if (sc->function)
Greg Clayton0d9c9932010-10-04 17:26:49 +00002448 {
Greg Clayton0603aa92010-10-04 01:05:56 +00002449 func_addr = sc->function->GetAddressRange().GetBaseAddress();
Greg Clayton0d9c9932010-10-04 17:26:49 +00002450 if (sc->block)
2451 {
2452 // Check to make sure we aren't in an inline
2453 // function. If we are, use the inline block
2454 // range that contains "format_addr" since
2455 // blocks can be discontiguous.
2456 Block *inline_block = sc->block->GetContainingInlinedBlock ();
2457 AddressRange inline_range;
2458 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
2459 func_addr = inline_range.GetBaseAddress();
2460 }
2461 }
Greg Claytone7612132012-03-07 21:03:09 +00002462 else if (sc->symbol && sc->symbol->ValueIsAddress())
2463 func_addr = sc->symbol->GetAddress();
Greg Clayton0603aa92010-10-04 01:05:56 +00002464 }
2465
2466 if (func_addr.IsValid())
Greg Clayton1b654882010-09-19 02:33:57 +00002467 {
2468 if (func_addr.GetSection() == format_addr.GetSection())
2469 {
2470 addr_t func_file_addr = func_addr.GetFileAddress();
2471 addr_t addr_file_addr = format_addr.GetFileAddress();
2472 if (addr_file_addr > func_file_addr)
Daniel Malead01b2952012-11-29 21:49:15 +00002473 s.Printf(" + %" PRIu64, addr_file_addr - func_file_addr);
Greg Clayton1b654882010-09-19 02:33:57 +00002474 else if (addr_file_addr < func_file_addr)
Daniel Malead01b2952012-11-29 21:49:15 +00002475 s.Printf(" - %" PRIu64, func_file_addr - addr_file_addr);
Greg Clayton0603aa92010-10-04 01:05:56 +00002476 var_success = true;
Greg Clayton1b654882010-09-19 02:33:57 +00002477 }
2478 else
Greg Clayton0603aa92010-10-04 01:05:56 +00002479 {
2480 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
2481 if (target)
2482 {
2483 addr_t func_load_addr = func_addr.GetLoadAddress (target);
2484 addr_t addr_load_addr = format_addr.GetLoadAddress (target);
2485 if (addr_load_addr > func_load_addr)
Daniel Malead01b2952012-11-29 21:49:15 +00002486 s.Printf(" + %" PRIu64, addr_load_addr - func_load_addr);
Greg Clayton0603aa92010-10-04 01:05:56 +00002487 else if (addr_load_addr < func_load_addr)
Daniel Malead01b2952012-11-29 21:49:15 +00002488 s.Printf(" - %" PRIu64, func_load_addr - addr_load_addr);
Greg Clayton0603aa92010-10-04 01:05:56 +00002489 var_success = true;
2490 }
2491 }
Greg Clayton1b654882010-09-19 02:33:57 +00002492 }
2493 }
2494 else
2495 {
Greg Clayton0603aa92010-10-04 01:05:56 +00002496 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
Greg Clayton1b654882010-09-19 02:33:57 +00002497 addr_t vaddr = LLDB_INVALID_ADDRESS;
Greg Clayton0603aa92010-10-04 01:05:56 +00002498 if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
2499 vaddr = format_addr.GetLoadAddress (target);
Greg Clayton1b654882010-09-19 02:33:57 +00002500 if (vaddr == LLDB_INVALID_ADDRESS)
2501 vaddr = format_addr.GetFileAddress ();
2502
2503 if (vaddr != LLDB_INVALID_ADDRESS)
Greg Clayton0603aa92010-10-04 01:05:56 +00002504 {
Greg Clayton514487e2011-02-15 21:59:32 +00002505 int addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
Greg Clayton35f1a0d2010-11-19 04:16:11 +00002506 if (addr_width == 0)
2507 addr_width = 16;
Daniel Malead01b2952012-11-29 21:49:15 +00002508 s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
Greg Clayton0603aa92010-10-04 01:05:56 +00002509 var_success = true;
2510 }
Greg Clayton1b654882010-09-19 02:33:57 +00002511 }
2512 }
2513 }
2514
2515 if (var_success == false)
2516 success = false;
2517 }
2518 p = var_name_end;
2519 }
2520 else
2521 break;
2522 }
2523 else
2524 {
2525 // We got a dollar sign with no '{' after it, it must just be a dollar sign
2526 s.PutChar(*p);
2527 }
2528 }
2529 else if (*p == '\\')
2530 {
2531 ++p; // skip the slash
2532 switch (*p)
2533 {
2534 case 'a': s.PutChar ('\a'); break;
2535 case 'b': s.PutChar ('\b'); break;
2536 case 'f': s.PutChar ('\f'); break;
2537 case 'n': s.PutChar ('\n'); break;
2538 case 'r': s.PutChar ('\r'); break;
2539 case 't': s.PutChar ('\t'); break;
2540 case 'v': s.PutChar ('\v'); break;
2541 case '\'': s.PutChar ('\''); break;
2542 case '\\': s.PutChar ('\\'); break;
2543 case '0':
2544 // 1 to 3 octal chars
2545 {
Greg Clayton0603aa92010-10-04 01:05:56 +00002546 // Make a string that can hold onto the initial zero char,
2547 // up to 3 octal digits, and a terminating NULL.
2548 char oct_str[5] = { 0, 0, 0, 0, 0 };
2549
2550 int i;
2551 for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
2552 oct_str[i] = p[i];
2553
2554 // We don't want to consume the last octal character since
2555 // the main for loop will do this for us, so we advance p by
2556 // one less than i (even if i is zero)
2557 p += i - 1;
2558 unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
2559 if (octal_value <= UINT8_MAX)
Greg Clayton1b654882010-09-19 02:33:57 +00002560 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002561 s.PutChar((char)octal_value);
Greg Clayton1b654882010-09-19 02:33:57 +00002562 }
Greg Clayton1b654882010-09-19 02:33:57 +00002563 }
2564 break;
2565
2566 case 'x':
2567 // hex number in the format
Greg Clayton0603aa92010-10-04 01:05:56 +00002568 if (isxdigit(p[1]))
Greg Clayton1b654882010-09-19 02:33:57 +00002569 {
Greg Clayton0603aa92010-10-04 01:05:56 +00002570 ++p; // Skip the 'x'
Greg Clayton1b654882010-09-19 02:33:57 +00002571
Greg Clayton0603aa92010-10-04 01:05:56 +00002572 // Make a string that can hold onto two hex chars plus a
2573 // NULL terminator
2574 char hex_str[3] = { 0,0,0 };
2575 hex_str[0] = *p;
2576 if (isxdigit(p[1]))
Greg Clayton1b654882010-09-19 02:33:57 +00002577 {
Greg Clayton0603aa92010-10-04 01:05:56 +00002578 ++p; // Skip the first of the two hex chars
2579 hex_str[1] = *p;
2580 }
2581
2582 unsigned long hex_value = strtoul (hex_str, NULL, 16);
2583 if (hex_value <= UINT8_MAX)
Greg Claytonc7bece562013-01-25 18:06:21 +00002584 s.PutChar ((char)hex_value);
Greg Clayton0603aa92010-10-04 01:05:56 +00002585 }
2586 else
2587 {
2588 s.PutChar('x');
Greg Clayton1b654882010-09-19 02:33:57 +00002589 }
2590 break;
2591
2592 default:
Greg Clayton0603aa92010-10-04 01:05:56 +00002593 // Just desensitize any other character by just printing what
2594 // came after the '\'
2595 s << *p;
Greg Clayton1b654882010-09-19 02:33:57 +00002596 break;
2597
2598 }
2599
2600 }
2601 }
2602 if (end)
2603 *end = p;
2604 return success;
2605}
2606
Michael Sartainc3ce7f272013-05-23 20:47:45 +00002607bool
2608Debugger::FormatPrompt
2609(
2610 const char *format,
2611 const SymbolContext *sc,
2612 const ExecutionContext *exe_ctx,
2613 const Address *addr,
2614 Stream &s,
2615 ValueObject* valobj
2616)
2617{
2618 bool use_color = exe_ctx ? exe_ctx->GetTargetRef().GetDebugger().GetUseColor() : true;
2619 std::string format_str = lldb_utility::ansi::FormatAnsiTerminalCodes (format, use_color);
2620 if (format_str.length())
2621 format = format_str.c_str();
2622 return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, valobj);
2623}
2624
Jim Ingham228063c2012-02-21 02:23:08 +00002625void
2626Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
2627{
Jim Ingham4f02b222012-02-22 22:49:20 +00002628 // For simplicity's sake, I am not going to deal with how to close down any
2629 // open logging streams, I just redirect everything from here on out to the
2630 // callback.
Jim Ingham228063c2012-02-21 02:23:08 +00002631 m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
2632}
2633
2634bool
2635Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
2636{
2637 Log::Callbacks log_callbacks;
2638
2639 StreamSP log_stream_sp;
Sean Callanan9a028512012-08-09 00:50:26 +00002640 if (m_log_callback_stream_sp)
Jim Ingham228063c2012-02-21 02:23:08 +00002641 {
2642 log_stream_sp = m_log_callback_stream_sp;
2643 // For now when using the callback mode you always get thread & timestamp.
2644 log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
2645 }
2646 else if (log_file == NULL || *log_file == '\0')
2647 {
2648 log_stream_sp.reset(new StreamFile(GetOutputFile().GetDescriptor(), false));
2649 }
2650 else
2651 {
2652 LogStreamMap::iterator pos = m_log_streams.find(log_file);
Greg Claytonc1b2ccf2013-01-08 00:01:36 +00002653 if (pos != m_log_streams.end())
2654 log_stream_sp = pos->second.lock();
2655 if (!log_stream_sp)
Jim Ingham228063c2012-02-21 02:23:08 +00002656 {
2657 log_stream_sp.reset (new StreamFile (log_file));
2658 m_log_streams[log_file] = log_stream_sp;
2659 }
Jim Ingham228063c2012-02-21 02:23:08 +00002660 }
2661 assert (log_stream_sp.get());
2662
2663 if (log_options == 0)
2664 log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
2665
Greg Clayton57abc5d2013-05-10 21:47:16 +00002666 if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks))
Jim Ingham228063c2012-02-21 02:23:08 +00002667 {
2668 log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream);
2669 return true;
2670 }
2671 else
2672 {
2673 LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel));
2674 if (log_channel_sp)
2675 {
2676 if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories))
2677 {
2678 return true;
2679 }
2680 else
2681 {
2682 error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2683 return false;
2684 }
2685 }
2686 else
2687 {
2688 error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2689 return false;
2690 }
2691 }
2692 return false;
2693}
2694
Greg Clayton9585fbf2013-03-19 00:20:55 +00002695SourceManager &
2696Debugger::GetSourceManager ()
2697{
2698 if (m_source_manager_ap.get() == NULL)
2699 m_source_manager_ap.reset (new SourceManager (shared_from_this()));
2700 return *m_source_manager_ap;
2701}
2702
2703