1 //===-- 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 10 #include "lldb/lldb-python.h" 11 12 #include "lldb/API/SBDebugger.h" 13 14 #include "lldb/Core/Debugger.h" 15 16 #include <map> 17 18 #include "clang/AST/DeclCXX.h" 19 #include "clang/AST/Type.h" 20 21 #include "lldb/lldb-private.h" 22 #include "lldb/Core/ConnectionFileDescriptor.h" 23 #include "lldb/Core/InputReader.h" 24 #include "lldb/Core/Module.h" 25 #include "lldb/Core/PluginManager.h" 26 #include "lldb/Core/RegisterValue.h" 27 #include "lldb/Core/State.h" 28 #include "lldb/Core/StreamAsynchronousIO.h" 29 #include "lldb/Core/StreamCallback.h" 30 #include "lldb/Core/StreamString.h" 31 #include "lldb/Core/Timer.h" 32 #include "lldb/Core/ValueObject.h" 33 #include "lldb/Core/ValueObjectVariable.h" 34 #include "lldb/DataFormatters/DataVisualization.h" 35 #include "lldb/DataFormatters/FormatManager.h" 36 #include "lldb/Host/DynamicLibrary.h" 37 #include "lldb/Host/Terminal.h" 38 #include "lldb/Interpreter/CommandInterpreter.h" 39 #include "lldb/Interpreter/OptionValueSInt64.h" 40 #include "lldb/Interpreter/OptionValueString.h" 41 #include "lldb/Symbol/ClangASTContext.h" 42 #include "lldb/Symbol/CompileUnit.h" 43 #include "lldb/Symbol/Function.h" 44 #include "lldb/Symbol/Symbol.h" 45 #include "lldb/Symbol/VariableList.h" 46 #include "lldb/Target/TargetList.h" 47 #include "lldb/Target/Process.h" 48 #include "lldb/Target/RegisterContext.h" 49 #include "lldb/Target/StopInfo.h" 50 #include "lldb/Target/Target.h" 51 #include "lldb/Target/Thread.h" 52 #include "lldb/Utility/AnsiTerminal.h" 53 54 using namespace lldb; 55 using namespace lldb_private; 56 57 58 static uint32_t g_shared_debugger_refcount = 0; 59 static lldb::user_id_t g_unique_id = 1; 60 61 #pragma mark Static Functions 62 63 static Mutex & 64 GetDebuggerListMutex () 65 { 66 static Mutex g_mutex(Mutex::eMutexTypeRecursive); 67 return g_mutex; 68 } 69 70 typedef std::vector<DebuggerSP> DebuggerList; 71 72 static DebuggerList & 73 GetDebuggerList() 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 } 80 81 OptionEnumValueElement 82 g_show_disassembly_enum_values[] = 83 { 84 { 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."}, 87 { 0, NULL, NULL } 88 }; 89 90 OptionEnumValueElement 91 g_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."}, 96 { 0, NULL, NULL } 97 }; 98 99 #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 102 #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\ 103 "{, ${frame.pc}}"\ 104 MODULE_WITH_FUNC\ 105 FILE_AND_LINE\ 106 "{, name = '${thread.name}}"\ 107 "{, queue = '${thread.queue}}"\ 108 "{, 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 119 static PropertyDefinition 120 g_properties[] = 121 { 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)." }, 125 { "prompt", OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." }, 126 { "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." }, 134 { "use-color", OptionValue::eTypeBoolean, true, true , NULL, NULL, "Whether to use Ansi color codes or not." }, 135 136 { NULL, OptionValue::eTypeInvalid, true, 0 , NULL, NULL, NULL } 137 }; 138 139 enum 140 { 141 ePropertyAutoConfirm = 0, 142 ePropertyFrameFormat, 143 ePropertyNotiftVoid, 144 ePropertyPrompt, 145 ePropertyScriptLanguage, 146 ePropertyStopDisassemblyCount, 147 ePropertyStopDisassemblyDisplay, 148 ePropertyStopLineCountAfter, 149 ePropertyStopLineCountBefore, 150 ePropertyTerminalWidth, 151 ePropertyThreadFormat, 152 ePropertyUseExternalEditor, 153 ePropertyUseColor, 154 }; 155 156 // 157 //const char * 158 //Debugger::GetFrameFormat() const 159 //{ 160 // return m_properties_sp->GetFrameFormat(); 161 //} 162 //const char * 163 //Debugger::GetThreadFormat() const 164 //{ 165 // return m_properties_sp->GetThreadFormat(); 166 //} 167 // 168 169 170 Error 171 Debugger::SetPropertyValue (const ExecutionContext *exe_ctx, 172 VarSetOperationType op, 173 const char *property_path, 174 const char *value) 175 { 176 bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0; 177 TargetSP target_sp; 178 LoadScriptFromSymFile load_script_old_value; 179 if (is_load_script && exe_ctx->GetTargetSP()) 180 { 181 target_sp = exe_ctx->GetTargetSP(); 182 load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile(); 183 } 184 Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value)); 185 if (error.Success()) 186 { 187 // FIXME it would be nice to have "on-change" callbacks for properties 188 if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0) 189 { 190 const char *new_prompt = GetPrompt(); 191 std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor()); 192 if (str.length()) 193 new_prompt = str.c_str(); 194 EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt))); 195 GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp); 196 } 197 else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0) 198 { 199 // use-color changed. Ping the prompt so it can reset the ansi terminal codes. 200 SetPrompt (GetPrompt()); 201 } 202 else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn) 203 { 204 if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue) 205 { 206 std::list<Error> errors; 207 StreamString feedback_stream; 208 if (!target_sp->LoadScriptingResources(errors,&feedback_stream)) 209 { 210 for (auto error : errors) 211 { 212 GetErrorStream().Printf("%s\n",error.AsCString()); 213 } 214 if (feedback_stream.GetSize()) 215 GetErrorStream().Printf("%s",feedback_stream.GetData()); 216 } 217 } 218 } 219 } 220 return error; 221 } 222 223 bool 224 Debugger::GetAutoConfirm () const 225 { 226 const uint32_t idx = ePropertyAutoConfirm; 227 return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 228 } 229 230 const char * 231 Debugger::GetFrameFormat() const 232 { 233 const uint32_t idx = ePropertyFrameFormat; 234 return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 235 } 236 237 bool 238 Debugger::GetNotifyVoid () const 239 { 240 const uint32_t idx = ePropertyNotiftVoid; 241 return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 242 } 243 244 const char * 245 Debugger::GetPrompt() const 246 { 247 const uint32_t idx = ePropertyPrompt; 248 return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 249 } 250 251 void 252 Debugger::SetPrompt(const char *p) 253 { 254 const uint32_t idx = ePropertyPrompt; 255 m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p); 256 const char *new_prompt = GetPrompt(); 257 std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor()); 258 if (str.length()) 259 new_prompt = str.c_str(); 260 EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));; 261 GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp); 262 } 263 264 const char * 265 Debugger::GetThreadFormat() const 266 { 267 const uint32_t idx = ePropertyThreadFormat; 268 return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 269 } 270 271 lldb::ScriptLanguage 272 Debugger::GetScriptLanguage() const 273 { 274 const uint32_t idx = ePropertyScriptLanguage; 275 return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value); 276 } 277 278 bool 279 Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang) 280 { 281 const uint32_t idx = ePropertyScriptLanguage; 282 return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang); 283 } 284 285 uint32_t 286 Debugger::GetTerminalWidth () const 287 { 288 const uint32_t idx = ePropertyTerminalWidth; 289 return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 290 } 291 292 bool 293 Debugger::SetTerminalWidth (uint32_t term_width) 294 { 295 const uint32_t idx = ePropertyTerminalWidth; 296 return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width); 297 } 298 299 bool 300 Debugger::GetUseExternalEditor () const 301 { 302 const uint32_t idx = ePropertyUseExternalEditor; 303 return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 304 } 305 306 bool 307 Debugger::SetUseExternalEditor (bool b) 308 { 309 const uint32_t idx = ePropertyUseExternalEditor; 310 return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b); 311 } 312 313 bool 314 Debugger::GetUseColor () const 315 { 316 const uint32_t idx = ePropertyUseColor; 317 return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 318 } 319 320 bool 321 Debugger::SetUseColor (bool b) 322 { 323 const uint32_t idx = ePropertyUseColor; 324 bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b); 325 SetPrompt (GetPrompt()); 326 return ret; 327 } 328 329 uint32_t 330 Debugger::GetStopSourceLineCount (bool before) const 331 { 332 const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter; 333 return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 334 } 335 336 Debugger::StopDisassemblyType 337 Debugger::GetStopDisassemblyDisplay () const 338 { 339 const uint32_t idx = ePropertyStopDisassemblyDisplay; 340 return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value); 341 } 342 343 uint32_t 344 Debugger::GetDisassemblyLineCount () const 345 { 346 const uint32_t idx = ePropertyStopDisassemblyCount; 347 return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 348 } 349 350 #pragma mark Debugger 351 352 //const DebuggerPropertiesSP & 353 //Debugger::GetSettings() const 354 //{ 355 // return m_properties_sp; 356 //} 357 // 358 359 int 360 Debugger::TestDebuggerRefCount () 361 { 362 return g_shared_debugger_refcount; 363 } 364 365 void 366 Debugger::Initialize () 367 { 368 if (g_shared_debugger_refcount++ == 0) 369 lldb_private::Initialize(); 370 } 371 372 void 373 Debugger::Terminate () 374 { 375 if (g_shared_debugger_refcount > 0) 376 { 377 g_shared_debugger_refcount--; 378 if (g_shared_debugger_refcount == 0) 379 { 380 lldb_private::WillTerminate(); 381 lldb_private::Terminate(); 382 383 // Clear our master list of debugger objects 384 Mutex::Locker locker (GetDebuggerListMutex ()); 385 GetDebuggerList().clear(); 386 } 387 } 388 } 389 390 void 391 Debugger::SettingsInitialize () 392 { 393 Target::SettingsInitialize (); 394 } 395 396 void 397 Debugger::SettingsTerminate () 398 { 399 Target::SettingsTerminate (); 400 } 401 402 bool 403 Debugger::LoadPlugin (const FileSpec& spec, Error& error) 404 { 405 lldb::DynamicLibrarySP dynlib_sp(new lldb_private::DynamicLibrary(spec)); 406 if (!dynlib_sp || dynlib_sp->IsValid() == false) 407 { 408 if (spec.Exists()) 409 error.SetErrorString("this file does not represent a loadable dylib"); 410 else 411 error.SetErrorString("no such file"); 412 return false; 413 } 414 lldb::DebuggerSP debugger_sp(shared_from_this()); 415 lldb::SBDebugger debugger_sb(debugger_sp); 416 // This calls the bool lldb::PluginInitialize(lldb::SBDebugger debugger) function. 417 // TODO: mangle this differently for your system - on OSX, the first underscore needs to be removed and the second one stays 418 LLDBCommandPluginInit init_func = dynlib_sp->GetSymbol<LLDBCommandPluginInit>("_ZN4lldb16PluginInitializeENS_10SBDebuggerE"); 419 if (!init_func) 420 { 421 error.SetErrorString("cannot find the initialization function lldb::PluginInitialize(lldb::SBDebugger)"); 422 return false; 423 } 424 if (init_func(debugger_sb)) 425 { 426 m_loaded_plugins.push_back(dynlib_sp); 427 return true; 428 } 429 error.SetErrorString("dylib refused to be loaded"); 430 return false; 431 } 432 433 static FileSpec::EnumerateDirectoryResult 434 LoadPluginCallback 435 ( 436 void *baton, 437 FileSpec::FileType file_type, 438 const FileSpec &file_spec 439 ) 440 { 441 Error error; 442 443 static ConstString g_dylibext("dylib"); 444 static ConstString g_solibext("so"); 445 446 if (!baton) 447 return FileSpec::eEnumerateDirectoryResultQuit; 448 449 Debugger *debugger = (Debugger*)baton; 450 451 // If we have a regular file, a symbolic link or unknown file type, try 452 // and process the file. We must handle unknown as sometimes the directory 453 // enumeration might be enumerating a file system that doesn't have correct 454 // file type information. 455 if (file_type == FileSpec::eFileTypeRegular || 456 file_type == FileSpec::eFileTypeSymbolicLink || 457 file_type == FileSpec::eFileTypeUnknown ) 458 { 459 FileSpec plugin_file_spec (file_spec); 460 plugin_file_spec.ResolvePath (); 461 462 if (plugin_file_spec.GetFileNameExtension() != g_dylibext && 463 plugin_file_spec.GetFileNameExtension() != g_solibext) 464 { 465 return FileSpec::eEnumerateDirectoryResultNext; 466 } 467 468 Error plugin_load_error; 469 debugger->LoadPlugin (plugin_file_spec, plugin_load_error); 470 471 return FileSpec::eEnumerateDirectoryResultNext; 472 } 473 474 else if (file_type == FileSpec::eFileTypeUnknown || 475 file_type == FileSpec::eFileTypeDirectory || 476 file_type == FileSpec::eFileTypeSymbolicLink ) 477 { 478 // Try and recurse into anything that a directory or symbolic link. 479 // We must also do this for unknown as sometimes the directory enumeration 480 // might be enurating a file system that doesn't have correct file type 481 // information. 482 return FileSpec::eEnumerateDirectoryResultEnter; 483 } 484 485 return FileSpec::eEnumerateDirectoryResultNext; 486 } 487 488 void 489 Debugger::InstanceInitialize () 490 { 491 FileSpec dir_spec; 492 const bool find_directories = true; 493 const bool find_files = true; 494 const bool find_other = true; 495 char dir_path[PATH_MAX]; 496 if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec)) 497 { 498 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) 499 { 500 FileSpec::EnumerateDirectory (dir_path, 501 find_directories, 502 find_files, 503 find_other, 504 LoadPluginCallback, 505 this); 506 } 507 } 508 509 if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec)) 510 { 511 if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) 512 { 513 FileSpec::EnumerateDirectory (dir_path, 514 find_directories, 515 find_files, 516 find_other, 517 LoadPluginCallback, 518 this); 519 } 520 } 521 522 PluginManager::DebuggerInitialize (*this); 523 } 524 525 DebuggerSP 526 Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton) 527 { 528 DebuggerSP debugger_sp (new Debugger(log_callback, baton)); 529 if (g_shared_debugger_refcount > 0) 530 { 531 Mutex::Locker locker (GetDebuggerListMutex ()); 532 GetDebuggerList().push_back(debugger_sp); 533 } 534 debugger_sp->InstanceInitialize (); 535 return debugger_sp; 536 } 537 538 void 539 Debugger::Destroy (DebuggerSP &debugger_sp) 540 { 541 if (debugger_sp.get() == NULL) 542 return; 543 544 debugger_sp->Clear(); 545 546 if (g_shared_debugger_refcount > 0) 547 { 548 Mutex::Locker locker (GetDebuggerListMutex ()); 549 DebuggerList &debugger_list = GetDebuggerList (); 550 DebuggerList::iterator pos, end = debugger_list.end(); 551 for (pos = debugger_list.begin (); pos != end; ++pos) 552 { 553 if ((*pos).get() == debugger_sp.get()) 554 { 555 debugger_list.erase (pos); 556 return; 557 } 558 } 559 } 560 } 561 562 DebuggerSP 563 Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name) 564 { 565 DebuggerSP debugger_sp; 566 if (g_shared_debugger_refcount > 0) 567 { 568 Mutex::Locker locker (GetDebuggerListMutex ()); 569 DebuggerList &debugger_list = GetDebuggerList(); 570 DebuggerList::iterator pos, end = debugger_list.end(); 571 572 for (pos = debugger_list.begin(); pos != end; ++pos) 573 { 574 if ((*pos).get()->m_instance_name == instance_name) 575 { 576 debugger_sp = *pos; 577 break; 578 } 579 } 580 } 581 return debugger_sp; 582 } 583 584 TargetSP 585 Debugger::FindTargetWithProcessID (lldb::pid_t pid) 586 { 587 TargetSP target_sp; 588 if (g_shared_debugger_refcount > 0) 589 { 590 Mutex::Locker locker (GetDebuggerListMutex ()); 591 DebuggerList &debugger_list = GetDebuggerList(); 592 DebuggerList::iterator pos, end = debugger_list.end(); 593 for (pos = debugger_list.begin(); pos != end; ++pos) 594 { 595 target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid); 596 if (target_sp) 597 break; 598 } 599 } 600 return target_sp; 601 } 602 603 TargetSP 604 Debugger::FindTargetWithProcess (Process *process) 605 { 606 TargetSP target_sp; 607 if (g_shared_debugger_refcount > 0) 608 { 609 Mutex::Locker locker (GetDebuggerListMutex ()); 610 DebuggerList &debugger_list = GetDebuggerList(); 611 DebuggerList::iterator pos, end = debugger_list.end(); 612 for (pos = debugger_list.begin(); pos != end; ++pos) 613 { 614 target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process); 615 if (target_sp) 616 break; 617 } 618 } 619 return target_sp; 620 } 621 622 Debugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) : 623 UserID (g_unique_id++), 624 Properties(OptionValuePropertiesSP(new OptionValueProperties())), 625 m_input_comm("debugger.input"), 626 m_input_file (), 627 m_output_file (), 628 m_error_file (), 629 m_terminal_state (), 630 m_target_list (*this), 631 m_platform_list (), 632 m_listener ("lldb.Debugger"), 633 m_source_manager_ap(), 634 m_source_file_cache(), 635 m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)), 636 m_input_reader_stack (), 637 m_input_reader_data (), 638 m_instance_name() 639 { 640 char instance_cstr[256]; 641 snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID()); 642 m_instance_name.SetCString(instance_cstr); 643 if (log_callback) 644 m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 645 m_command_interpreter_ap->Initialize (); 646 // Always add our default platform to the platform list 647 PlatformSP default_platform_sp (Platform::GetDefaultPlatform()); 648 assert (default_platform_sp.get()); 649 m_platform_list.Append (default_platform_sp, true); 650 651 m_collection_sp->Initialize (g_properties); 652 m_collection_sp->AppendProperty (ConstString("target"), 653 ConstString("Settings specify to debugging targets."), 654 true, 655 Target::GetGlobalProperties()->GetValueProperties()); 656 if (m_command_interpreter_ap.get()) 657 { 658 m_collection_sp->AppendProperty (ConstString("interpreter"), 659 ConstString("Settings specify to the debugger's command interpreter."), 660 true, 661 m_command_interpreter_ap->GetValueProperties()); 662 } 663 OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth); 664 term_width->SetMinimumValue(10); 665 term_width->SetMaximumValue(1024); 666 667 // Turn off use-color if this is a dumb terminal. 668 const char *term = getenv ("TERM"); 669 if (term && !strcmp (term, "dumb")) 670 SetUseColor (false); 671 } 672 673 Debugger::~Debugger () 674 { 675 Clear(); 676 } 677 678 void 679 Debugger::Clear() 680 { 681 CleanUpInputReaders(); 682 m_listener.Clear(); 683 int num_targets = m_target_list.GetNumTargets(); 684 for (int i = 0; i < num_targets; i++) 685 { 686 TargetSP target_sp (m_target_list.GetTargetAtIndex (i)); 687 if (target_sp) 688 { 689 ProcessSP process_sp (target_sp->GetProcessSP()); 690 if (process_sp) 691 process_sp->Finalize(); 692 target_sp->Destroy(); 693 } 694 } 695 BroadcasterManager::Clear (); 696 697 // Close the input file _before_ we close the input read communications class 698 // as it does NOT own the input file, our m_input_file does. 699 m_terminal_state.Clear(); 700 GetInputFile().Close (); 701 // Now that we have closed m_input_file, we can now tell our input communication 702 // class to close down. Its read thread should quickly exit after we close 703 // the input file handle above. 704 m_input_comm.Clear (); 705 } 706 707 bool 708 Debugger::GetCloseInputOnEOF () const 709 { 710 return m_input_comm.GetCloseOnEOF(); 711 } 712 713 void 714 Debugger::SetCloseInputOnEOF (bool b) 715 { 716 m_input_comm.SetCloseOnEOF(b); 717 } 718 719 bool 720 Debugger::GetAsyncExecution () 721 { 722 return !m_command_interpreter_ap->GetSynchronous(); 723 } 724 725 void 726 Debugger::SetAsyncExecution (bool async_execution) 727 { 728 m_command_interpreter_ap->SetSynchronous (!async_execution); 729 } 730 731 732 void 733 Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership) 734 { 735 File &in_file = GetInputFile(); 736 in_file.SetStream (fh, tranfer_ownership); 737 if (in_file.IsValid() == false) 738 in_file.SetStream (stdin, true); 739 740 // Disconnect from any old connection if we had one 741 m_input_comm.Disconnect (); 742 // Pass false as the second argument to ConnectionFileDescriptor below because 743 // our "in_file" above will already take ownership if requested and we don't 744 // want to objects trying to own and close a file descriptor. 745 m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), false)); 746 m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this); 747 748 // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState. 749 SaveInputTerminalState (); 750 751 Error error; 752 if (m_input_comm.StartReadThread (&error) == false) 753 { 754 File &err_file = GetErrorFile(); 755 756 err_file.Printf ("error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error"); 757 exit(1); 758 } 759 } 760 761 void 762 Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership) 763 { 764 File &out_file = GetOutputFile(); 765 out_file.SetStream (fh, tranfer_ownership); 766 if (out_file.IsValid() == false) 767 out_file.SetStream (stdout, false); 768 769 // do not create the ScriptInterpreter just for setting the output file handle 770 // as the constructor will know how to do the right thing on its own 771 const bool can_create = false; 772 ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create); 773 if (script_interpreter) 774 script_interpreter->ResetOutputFileHandle (fh); 775 } 776 777 void 778 Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership) 779 { 780 File &err_file = GetErrorFile(); 781 err_file.SetStream (fh, tranfer_ownership); 782 if (err_file.IsValid() == false) 783 err_file.SetStream (stderr, false); 784 } 785 786 void 787 Debugger::SaveInputTerminalState () 788 { 789 File &in_file = GetInputFile(); 790 if (in_file.GetDescriptor() != File::kInvalidDescriptor) 791 m_terminal_state.Save(in_file.GetDescriptor(), true); 792 } 793 794 void 795 Debugger::RestoreInputTerminalState () 796 { 797 m_terminal_state.Restore(); 798 } 799 800 ExecutionContext 801 Debugger::GetSelectedExecutionContext () 802 { 803 ExecutionContext exe_ctx; 804 TargetSP target_sp(GetSelectedTarget()); 805 exe_ctx.SetTargetSP (target_sp); 806 807 if (target_sp) 808 { 809 ProcessSP process_sp (target_sp->GetProcessSP()); 810 exe_ctx.SetProcessSP (process_sp); 811 if (process_sp && process_sp->IsRunning() == false) 812 { 813 ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread()); 814 if (thread_sp) 815 { 816 exe_ctx.SetThreadSP (thread_sp); 817 exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame()); 818 if (exe_ctx.GetFramePtr() == NULL) 819 exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0)); 820 } 821 } 822 } 823 return exe_ctx; 824 825 } 826 827 InputReaderSP 828 Debugger::GetCurrentInputReader () 829 { 830 InputReaderSP reader_sp; 831 832 if (!m_input_reader_stack.IsEmpty()) 833 { 834 // Clear any finished readers from the stack 835 while (CheckIfTopInputReaderIsDone()) ; 836 837 if (!m_input_reader_stack.IsEmpty()) 838 reader_sp = m_input_reader_stack.Top(); 839 } 840 841 return reader_sp; 842 } 843 844 void 845 Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len) 846 { 847 if (bytes_len > 0) 848 ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len); 849 else 850 ((Debugger *)baton)->DispatchInputEndOfFile (); 851 } 852 853 854 void 855 Debugger::DispatchInput (const char *bytes, size_t bytes_len) 856 { 857 if (bytes == NULL || bytes_len == 0) 858 return; 859 860 WriteToDefaultReader (bytes, bytes_len); 861 } 862 863 void 864 Debugger::DispatchInputInterrupt () 865 { 866 m_input_reader_data.clear(); 867 868 InputReaderSP reader_sp (GetCurrentInputReader ()); 869 if (reader_sp) 870 { 871 reader_sp->Notify (eInputReaderInterrupt); 872 873 // If notifying the reader of the interrupt finished the reader, we should pop it off the stack. 874 while (CheckIfTopInputReaderIsDone ()) ; 875 } 876 } 877 878 void 879 Debugger::DispatchInputEndOfFile () 880 { 881 m_input_reader_data.clear(); 882 883 InputReaderSP reader_sp (GetCurrentInputReader ()); 884 if (reader_sp) 885 { 886 reader_sp->Notify (eInputReaderEndOfFile); 887 888 // If notifying the reader of the end-of-file finished the reader, we should pop it off the stack. 889 while (CheckIfTopInputReaderIsDone ()) ; 890 } 891 } 892 893 void 894 Debugger::CleanUpInputReaders () 895 { 896 m_input_reader_data.clear(); 897 898 // The bottom input reader should be the main debugger input reader. We do not want to close that one here. 899 while (m_input_reader_stack.GetSize() > 1) 900 { 901 InputReaderSP reader_sp (GetCurrentInputReader ()); 902 if (reader_sp) 903 { 904 reader_sp->Notify (eInputReaderEndOfFile); 905 reader_sp->SetIsDone (true); 906 } 907 } 908 } 909 910 void 911 Debugger::NotifyTopInputReader (InputReaderAction notification) 912 { 913 InputReaderSP reader_sp (GetCurrentInputReader()); 914 if (reader_sp) 915 { 916 reader_sp->Notify (notification); 917 918 // Flush out any input readers that are done. 919 while (CheckIfTopInputReaderIsDone ()) 920 /* Do nothing. */; 921 } 922 } 923 924 bool 925 Debugger::InputReaderIsTopReader (const InputReaderSP& reader_sp) 926 { 927 InputReaderSP top_reader_sp (GetCurrentInputReader()); 928 929 return (reader_sp.get() == top_reader_sp.get()); 930 } 931 932 933 void 934 Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len) 935 { 936 if (bytes && bytes_len) 937 m_input_reader_data.append (bytes, bytes_len); 938 939 if (m_input_reader_data.empty()) 940 return; 941 942 while (!m_input_reader_stack.IsEmpty() && !m_input_reader_data.empty()) 943 { 944 // Get the input reader from the top of the stack 945 InputReaderSP reader_sp (GetCurrentInputReader ()); 946 if (!reader_sp) 947 break; 948 949 size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(), 950 m_input_reader_data.size()); 951 if (bytes_handled) 952 { 953 m_input_reader_data.erase (0, bytes_handled); 954 } 955 else 956 { 957 // No bytes were handled, we might not have reached our 958 // granularity, just return and wait for more data 959 break; 960 } 961 } 962 963 // Flush out any input readers that are done. 964 while (CheckIfTopInputReaderIsDone ()) 965 /* Do nothing. */; 966 967 } 968 969 void 970 Debugger::PushInputReader (const InputReaderSP& reader_sp) 971 { 972 if (!reader_sp) 973 return; 974 975 // Deactivate the old top reader 976 InputReaderSP top_reader_sp (GetCurrentInputReader ()); 977 978 if (top_reader_sp) 979 top_reader_sp->Notify (eInputReaderDeactivate); 980 981 m_input_reader_stack.Push (reader_sp); 982 reader_sp->Notify (eInputReaderActivate); 983 ActivateInputReader (reader_sp); 984 } 985 986 bool 987 Debugger::PopInputReader (const InputReaderSP& pop_reader_sp) 988 { 989 bool result = false; 990 991 // The reader on the stop of the stack is done, so let the next 992 // read on the stack referesh its prompt and if there is one... 993 if (!m_input_reader_stack.IsEmpty()) 994 { 995 // Cannot call GetCurrentInputReader here, as that would cause an infinite loop. 996 InputReaderSP reader_sp(m_input_reader_stack.Top()); 997 998 if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get()) 999 { 1000 m_input_reader_stack.Pop (); 1001 reader_sp->Notify (eInputReaderDeactivate); 1002 reader_sp->Notify (eInputReaderDone); 1003 result = true; 1004 1005 if (!m_input_reader_stack.IsEmpty()) 1006 { 1007 reader_sp = m_input_reader_stack.Top(); 1008 if (reader_sp) 1009 { 1010 ActivateInputReader (reader_sp); 1011 reader_sp->Notify (eInputReaderReactivate); 1012 } 1013 } 1014 } 1015 } 1016 return result; 1017 } 1018 1019 bool 1020 Debugger::CheckIfTopInputReaderIsDone () 1021 { 1022 bool result = false; 1023 if (!m_input_reader_stack.IsEmpty()) 1024 { 1025 // Cannot call GetCurrentInputReader here, as that would cause an infinite loop. 1026 InputReaderSP reader_sp(m_input_reader_stack.Top()); 1027 1028 if (reader_sp && reader_sp->IsDone()) 1029 { 1030 result = true; 1031 PopInputReader (reader_sp); 1032 } 1033 } 1034 return result; 1035 } 1036 1037 void 1038 Debugger::ActivateInputReader (const InputReaderSP &reader_sp) 1039 { 1040 int input_fd = m_input_file.GetFile().GetDescriptor(); 1041 1042 if (input_fd >= 0) 1043 { 1044 Terminal tty(input_fd); 1045 1046 tty.SetEcho(reader_sp->GetEcho()); 1047 1048 switch (reader_sp->GetGranularity()) 1049 { 1050 case eInputReaderGranularityByte: 1051 case eInputReaderGranularityWord: 1052 tty.SetCanonical (false); 1053 break; 1054 1055 case eInputReaderGranularityLine: 1056 case eInputReaderGranularityAll: 1057 tty.SetCanonical (true); 1058 break; 1059 1060 default: 1061 break; 1062 } 1063 } 1064 } 1065 1066 StreamSP 1067 Debugger::GetAsyncOutputStream () 1068 { 1069 return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(), 1070 CommandInterpreter::eBroadcastBitAsynchronousOutputData)); 1071 } 1072 1073 StreamSP 1074 Debugger::GetAsyncErrorStream () 1075 { 1076 return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(), 1077 CommandInterpreter::eBroadcastBitAsynchronousErrorData)); 1078 } 1079 1080 size_t 1081 Debugger::GetNumDebuggers() 1082 { 1083 if (g_shared_debugger_refcount > 0) 1084 { 1085 Mutex::Locker locker (GetDebuggerListMutex ()); 1086 return GetDebuggerList().size(); 1087 } 1088 return 0; 1089 } 1090 1091 lldb::DebuggerSP 1092 Debugger::GetDebuggerAtIndex (size_t index) 1093 { 1094 DebuggerSP debugger_sp; 1095 1096 if (g_shared_debugger_refcount > 0) 1097 { 1098 Mutex::Locker locker (GetDebuggerListMutex ()); 1099 DebuggerList &debugger_list = GetDebuggerList(); 1100 1101 if (index < debugger_list.size()) 1102 debugger_sp = debugger_list[index]; 1103 } 1104 1105 return debugger_sp; 1106 } 1107 1108 DebuggerSP 1109 Debugger::FindDebuggerWithID (lldb::user_id_t id) 1110 { 1111 DebuggerSP debugger_sp; 1112 1113 if (g_shared_debugger_refcount > 0) 1114 { 1115 Mutex::Locker locker (GetDebuggerListMutex ()); 1116 DebuggerList &debugger_list = GetDebuggerList(); 1117 DebuggerList::iterator pos, end = debugger_list.end(); 1118 for (pos = debugger_list.begin(); pos != end; ++pos) 1119 { 1120 if ((*pos).get()->GetID() == id) 1121 { 1122 debugger_sp = *pos; 1123 break; 1124 } 1125 } 1126 } 1127 return debugger_sp; 1128 } 1129 1130 static void 1131 TestPromptFormats (StackFrame *frame) 1132 { 1133 if (frame == NULL) 1134 return; 1135 1136 StreamString s; 1137 const char *prompt_format = 1138 "{addr = '${addr}'\n}" 1139 "{process.id = '${process.id}'\n}" 1140 "{process.name = '${process.name}'\n}" 1141 "{process.file.basename = '${process.file.basename}'\n}" 1142 "{process.file.fullpath = '${process.file.fullpath}'\n}" 1143 "{thread.id = '${thread.id}'\n}" 1144 "{thread.index = '${thread.index}'\n}" 1145 "{thread.name = '${thread.name}'\n}" 1146 "{thread.queue = '${thread.queue}'\n}" 1147 "{thread.stop-reason = '${thread.stop-reason}'\n}" 1148 "{target.arch = '${target.arch}'\n}" 1149 "{module.file.basename = '${module.file.basename}'\n}" 1150 "{module.file.fullpath = '${module.file.fullpath}'\n}" 1151 "{file.basename = '${file.basename}'\n}" 1152 "{file.fullpath = '${file.fullpath}'\n}" 1153 "{frame.index = '${frame.index}'\n}" 1154 "{frame.pc = '${frame.pc}'\n}" 1155 "{frame.sp = '${frame.sp}'\n}" 1156 "{frame.fp = '${frame.fp}'\n}" 1157 "{frame.flags = '${frame.flags}'\n}" 1158 "{frame.reg.rdi = '${frame.reg.rdi}'\n}" 1159 "{frame.reg.rip = '${frame.reg.rip}'\n}" 1160 "{frame.reg.rsp = '${frame.reg.rsp}'\n}" 1161 "{frame.reg.rbp = '${frame.reg.rbp}'\n}" 1162 "{frame.reg.rflags = '${frame.reg.rflags}'\n}" 1163 "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}" 1164 "{frame.reg.carp = '${frame.reg.carp}'\n}" 1165 "{function.id = '${function.id}'\n}" 1166 "{function.name = '${function.name}'\n}" 1167 "{function.name-with-args = '${function.name-with-args}'\n}" 1168 "{function.addr-offset = '${function.addr-offset}'\n}" 1169 "{function.line-offset = '${function.line-offset}'\n}" 1170 "{function.pc-offset = '${function.pc-offset}'\n}" 1171 "{line.file.basename = '${line.file.basename}'\n}" 1172 "{line.file.fullpath = '${line.file.fullpath}'\n}" 1173 "{line.number = '${line.number}'\n}" 1174 "{line.start-addr = '${line.start-addr}'\n}" 1175 "{line.end-addr = '${line.end-addr}'\n}" 1176 ; 1177 1178 SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything)); 1179 ExecutionContext exe_ctx; 1180 frame->CalculateExecutionContext(exe_ctx); 1181 if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s)) 1182 { 1183 printf("%s\n", s.GetData()); 1184 } 1185 else 1186 { 1187 printf ("what we got: %s\n", s.GetData()); 1188 } 1189 } 1190 1191 static bool 1192 ScanFormatDescriptor (const char* var_name_begin, 1193 const char* var_name_end, 1194 const char** var_name_final, 1195 const char** percent_position, 1196 Format* custom_format, 1197 ValueObject::ValueObjectRepresentationStyle* val_obj_display) 1198 { 1199 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 1200 *percent_position = ::strchr(var_name_begin,'%'); 1201 if (!*percent_position || *percent_position > var_name_end) 1202 { 1203 if (log) 1204 log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping"); 1205 *var_name_final = var_name_end; 1206 } 1207 else 1208 { 1209 *var_name_final = *percent_position; 1210 std::string format_name(*var_name_final+1, var_name_end-*var_name_final-1); 1211 if (log) 1212 log->Printf("[ScanFormatDescriptor] parsing %s as a format descriptor", format_name.c_str()); 1213 if ( !FormatManager::GetFormatFromCString(format_name.c_str(), 1214 true, 1215 *custom_format) ) 1216 { 1217 if (log) 1218 log->Printf("[ScanFormatDescriptor] %s is an unknown format", format_name.c_str()); 1219 1220 switch (format_name.front()) 1221 { 1222 case '@': // if this is an @ sign, print ObjC description 1223 *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific; 1224 break; 1225 case 'V': // if this is a V, print the value using the default format 1226 *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1227 break; 1228 case 'L': // if this is an L, print the location of the value 1229 *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation; 1230 break; 1231 case 'S': // if this is an S, print the summary after all 1232 *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary; 1233 break; 1234 case '#': // if this is a '#', print the number of children 1235 *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount; 1236 break; 1237 case 'T': // if this is a 'T', print the type 1238 *val_obj_display = ValueObject::eValueObjectRepresentationStyleType; 1239 break; 1240 case 'N': // if this is a 'N', print the name 1241 *val_obj_display = ValueObject::eValueObjectRepresentationStyleName; 1242 break; 1243 case '>': // if this is a '>', print the name 1244 *val_obj_display = ValueObject::eValueObjectRepresentationStyleExpressionPath; 1245 break; 1246 default: 1247 if (log) 1248 log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name.c_str()); 1249 break; 1250 } 1251 } 1252 // a good custom format tells us to print the value using it 1253 else 1254 { 1255 if (log) 1256 log->Printf("[ScanFormatDescriptor] will display value for this VO"); 1257 *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1258 } 1259 } 1260 if (log) 1261 log->Printf("[ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d", 1262 *custom_format, 1263 *val_obj_display); 1264 return true; 1265 } 1266 1267 static bool 1268 ScanBracketedRange (const char* var_name_begin, 1269 const char* var_name_end, 1270 const char* var_name_final, 1271 const char** open_bracket_position, 1272 const char** separator_position, 1273 const char** close_bracket_position, 1274 const char** var_name_final_if_array_range, 1275 int64_t* index_lower, 1276 int64_t* index_higher) 1277 { 1278 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 1279 *open_bracket_position = ::strchr(var_name_begin,'['); 1280 if (*open_bracket_position && *open_bracket_position < var_name_final) 1281 { 1282 *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield 1283 *close_bracket_position = ::strchr(*open_bracket_position,']'); 1284 // as usual, we assume that [] will come before % 1285 //printf("trying to expand a []\n"); 1286 *var_name_final_if_array_range = *open_bracket_position; 1287 if (*close_bracket_position - *open_bracket_position == 1) 1288 { 1289 if (log) 1290 log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data"); 1291 *index_lower = 0; 1292 } 1293 else if (*separator_position == NULL || *separator_position > var_name_end) 1294 { 1295 char *end = NULL; 1296 *index_lower = ::strtoul (*open_bracket_position+1, &end, 0); 1297 *index_higher = *index_lower; 1298 if (log) 1299 log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower); 1300 } 1301 else if (*close_bracket_position && *close_bracket_position < var_name_end) 1302 { 1303 char *end = NULL; 1304 *index_lower = ::strtoul (*open_bracket_position+1, &end, 0); 1305 *index_higher = ::strtoul (*separator_position+1, &end, 0); 1306 if (log) 1307 log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher); 1308 } 1309 else 1310 { 1311 if (log) 1312 log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it"); 1313 return false; 1314 } 1315 if (*index_lower > *index_higher && *index_higher > 0) 1316 { 1317 if (log) 1318 log->Printf("[ScanBracketedRange] swapping indices"); 1319 int64_t temp = *index_lower; 1320 *index_lower = *index_higher; 1321 *index_higher = temp; 1322 } 1323 } 1324 else if (log) 1325 log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely"); 1326 return true; 1327 } 1328 1329 static ValueObjectSP 1330 ExpandIndexedExpression (ValueObject* valobj, 1331 size_t index, 1332 StackFrame* frame, 1333 bool deref_pointer) 1334 { 1335 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 1336 const char* ptr_deref_format = "[%d]"; 1337 std::string ptr_deref_buffer(10,0); 1338 ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index); 1339 if (log) 1340 log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str()); 1341 const char* first_unparsed; 1342 ValueObject::GetValueForExpressionPathOptions options; 1343 ValueObject::ExpressionPathEndResultType final_value_type; 1344 ValueObject::ExpressionPathScanEndReason reason_to_stop; 1345 ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing); 1346 ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(), 1347 &first_unparsed, 1348 &reason_to_stop, 1349 &final_value_type, 1350 options, 1351 &what_next); 1352 if (!item) 1353 { 1354 if (log) 1355 log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d," 1356 " final_value_type %d", 1357 first_unparsed, reason_to_stop, final_value_type); 1358 } 1359 else 1360 { 1361 if (log) 1362 log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d," 1363 " final_value_type %d", 1364 first_unparsed, reason_to_stop, final_value_type); 1365 } 1366 return item; 1367 } 1368 1369 static bool 1370 FormatPromptRecurse 1371 ( 1372 const char *format, 1373 const SymbolContext *sc, 1374 const ExecutionContext *exe_ctx, 1375 const Address *addr, 1376 Stream &s, 1377 const char **end, 1378 ValueObject* valobj 1379 ) 1380 { 1381 ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers 1382 bool success = true; 1383 const char *p; 1384 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 1385 1386 for (p = format; *p != '\0'; ++p) 1387 { 1388 if (realvalobj) 1389 { 1390 valobj = realvalobj; 1391 realvalobj = NULL; 1392 } 1393 size_t non_special_chars = ::strcspn (p, "${}\\"); 1394 if (non_special_chars > 0) 1395 { 1396 if (success) 1397 s.Write (p, non_special_chars); 1398 p += non_special_chars; 1399 } 1400 1401 if (*p == '\0') 1402 { 1403 break; 1404 } 1405 else if (*p == '{') 1406 { 1407 // Start a new scope that must have everything it needs if it is to 1408 // to make it into the final output stream "s". If you want to make 1409 // a format that only prints out the function or symbol name if there 1410 // is one in the symbol context you can use: 1411 // "{function =${function.name}}" 1412 // The first '{' starts a new scope that end with the matching '}' at 1413 // the end of the string. The contents "function =${function.name}" 1414 // will then be evaluated and only be output if there is a function 1415 // or symbol with a valid name. 1416 StreamString sub_strm; 1417 1418 ++p; // Skip the '{' 1419 1420 if (FormatPromptRecurse (p, sc, exe_ctx, addr, sub_strm, &p, valobj)) 1421 { 1422 // The stream had all it needed 1423 s.Write(sub_strm.GetData(), sub_strm.GetSize()); 1424 } 1425 if (*p != '}') 1426 { 1427 success = false; 1428 break; 1429 } 1430 } 1431 else if (*p == '}') 1432 { 1433 // End of a enclosing scope 1434 break; 1435 } 1436 else if (*p == '$') 1437 { 1438 // We have a prompt variable to print 1439 ++p; 1440 if (*p == '{') 1441 { 1442 ++p; 1443 const char *var_name_begin = p; 1444 const char *var_name_end = ::strchr (p, '}'); 1445 1446 if (var_name_end && var_name_begin < var_name_end) 1447 { 1448 // if we have already failed to parse, skip this variable 1449 if (success) 1450 { 1451 const char *cstr = NULL; 1452 Address format_addr; 1453 bool calculate_format_addr_function_offset = false; 1454 // Set reg_kind and reg_num to invalid values 1455 RegisterKind reg_kind = kNumRegisterKinds; 1456 uint32_t reg_num = LLDB_INVALID_REGNUM; 1457 FileSpec format_file_spec; 1458 const RegisterInfo *reg_info = NULL; 1459 RegisterContext *reg_ctx = NULL; 1460 bool do_deref_pointer = false; 1461 ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString; 1462 ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain; 1463 1464 // Each variable must set success to true below... 1465 bool var_success = false; 1466 switch (var_name_begin[0]) 1467 { 1468 case '*': 1469 case 'v': 1470 case 's': 1471 { 1472 if (!valobj) 1473 break; 1474 1475 if (log) 1476 log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin); 1477 1478 // check for *var and *svar 1479 if (*var_name_begin == '*') 1480 { 1481 do_deref_pointer = true; 1482 var_name_begin++; 1483 if (log) 1484 log->Printf("[Debugger::FormatPrompt] found a deref, new string is: %s",var_name_begin); 1485 } 1486 1487 if (*var_name_begin == 's') 1488 { 1489 if (!valobj->IsSynthetic()) 1490 valobj = valobj->GetSyntheticValue().get(); 1491 if (!valobj) 1492 break; 1493 var_name_begin++; 1494 if (log) 1495 log->Printf("[Debugger::FormatPrompt] found a synthetic, new string is: %s",var_name_begin); 1496 } 1497 1498 // should be a 'v' by now 1499 if (*var_name_begin != 'v') 1500 break; 1501 1502 if (log) 1503 log->Printf("[Debugger::FormatPrompt] string I am working with: %s",var_name_begin); 1504 1505 ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ? 1506 ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing); 1507 ValueObject::GetValueForExpressionPathOptions options; 1508 options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren(); 1509 ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary; 1510 ValueObject* target = NULL; 1511 Format custom_format = eFormatInvalid; 1512 const char* var_name_final = NULL; 1513 const char* var_name_final_if_array_range = NULL; 1514 const char* close_bracket_position = NULL; 1515 int64_t index_lower = -1; 1516 int64_t index_higher = -1; 1517 bool is_array_range = false; 1518 const char* first_unparsed; 1519 bool was_plain_var = false; 1520 bool was_var_format = false; 1521 bool was_var_indexed = false; 1522 1523 if (!valobj) break; 1524 // simplest case ${var}, just print valobj's value 1525 if (::strncmp (var_name_begin, "var}", strlen("var}")) == 0) 1526 { 1527 was_plain_var = true; 1528 target = valobj; 1529 val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1530 } 1531 else if (::strncmp(var_name_begin,"var%",strlen("var%")) == 0) 1532 { 1533 was_var_format = true; 1534 // this is a variable with some custom format applied to it 1535 const char* percent_position; 1536 target = valobj; 1537 val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1538 ScanFormatDescriptor (var_name_begin, 1539 var_name_end, 1540 &var_name_final, 1541 &percent_position, 1542 &custom_format, 1543 &val_obj_display); 1544 } 1545 // this is ${var.something} or multiple .something nested 1546 else if (::strncmp (var_name_begin, "var", strlen("var")) == 0) 1547 { 1548 if (::strncmp(var_name_begin, "var[", strlen("var[")) == 0) 1549 was_var_indexed = true; 1550 const char* percent_position; 1551 ScanFormatDescriptor (var_name_begin, 1552 var_name_end, 1553 &var_name_final, 1554 &percent_position, 1555 &custom_format, 1556 &val_obj_display); 1557 1558 const char* open_bracket_position; 1559 const char* separator_position; 1560 ScanBracketedRange (var_name_begin, 1561 var_name_end, 1562 var_name_final, 1563 &open_bracket_position, 1564 &separator_position, 1565 &close_bracket_position, 1566 &var_name_final_if_array_range, 1567 &index_lower, 1568 &index_higher); 1569 1570 Error error; 1571 1572 std::string expr_path(var_name_final-var_name_begin-1,0); 1573 memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3); 1574 1575 if (log) 1576 log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str()); 1577 1578 target = valobj->GetValueForExpressionPath(expr_path.c_str(), 1579 &first_unparsed, 1580 &reason_to_stop, 1581 &final_value_type, 1582 options, 1583 &what_next).get(); 1584 1585 if (!target) 1586 { 1587 if (log) 1588 log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d," 1589 " final_value_type %d", 1590 first_unparsed, reason_to_stop, final_value_type); 1591 break; 1592 } 1593 else 1594 { 1595 if (log) 1596 log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d," 1597 " final_value_type %d", 1598 first_unparsed, reason_to_stop, final_value_type); 1599 } 1600 } 1601 else 1602 break; 1603 1604 is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange || 1605 final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange); 1606 1607 do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference); 1608 1609 if (do_deref_pointer && !is_array_range) 1610 { 1611 // I have not deref-ed yet, let's do it 1612 // this happens when we are not going through GetValueForVariableExpressionPath 1613 // to get to the target ValueObject 1614 Error error; 1615 target = target->Dereference(error).get(); 1616 if (error.Fail()) 1617 { 1618 if (log) 1619 log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \ 1620 break; 1621 } 1622 do_deref_pointer = false; 1623 } 1624 1625 // <rdar://problem/11338654> 1626 // we do not want to use the summary for a bitfield of type T:n 1627 // if we were originally dealing with just a T - that would get 1628 // us into an endless recursion 1629 if (target->IsBitfield() && was_var_indexed) 1630 { 1631 // TODO: check for a (T:n)-specific summary - we should still obey that 1632 StreamString bitfield_name; 1633 bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize()); 1634 lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false)); 1635 if (!DataVisualization::GetSummaryForType(type_sp)) 1636 val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1637 } 1638 1639 // TODO use flags for these 1640 const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL); 1641 bool is_array = (type_info_flags & ClangASTType::eTypeIsArray) != 0; 1642 bool is_pointer = (type_info_flags & ClangASTType::eTypeIsPointer) != 0; 1643 bool is_aggregate = target->GetClangType().IsAggregateType(); 1644 1645 if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions 1646 { 1647 StreamString str_temp; 1648 if (log) 1649 log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range"); 1650 1651 if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format)) 1652 { 1653 // try to use the special cases 1654 var_success = target->DumpPrintableRepresentation(str_temp, 1655 val_obj_display, 1656 custom_format); 1657 if (log) 1658 log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't"); 1659 1660 // should not happen 1661 if (var_success) 1662 s << str_temp.GetData(); 1663 var_success = true; 1664 break; 1665 } 1666 else 1667 { 1668 if (was_plain_var) // if ${var} 1669 { 1670 s << target->GetTypeName() << " @ " << target->GetLocationAsCString(); 1671 } 1672 else if (is_pointer) // if pointer, value is the address stored 1673 { 1674 target->DumpPrintableRepresentation (s, 1675 val_obj_display, 1676 custom_format, 1677 ValueObject::ePrintableRepresentationSpecialCasesDisable); 1678 } 1679 var_success = true; 1680 break; 1681 } 1682 } 1683 1684 // if directly trying to print ${var}, and this is an aggregate, display a nice 1685 // type @ location message 1686 if (is_aggregate && was_plain_var) 1687 { 1688 s << target->GetTypeName() << " @ " << target->GetLocationAsCString(); 1689 var_success = true; 1690 break; 1691 } 1692 1693 // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it 1694 if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue))) 1695 { 1696 s << "<invalid use of aggregate type>"; 1697 var_success = true; 1698 break; 1699 } 1700 1701 if (!is_array_range) 1702 { 1703 if (log) 1704 log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output"); 1705 var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format); 1706 } 1707 else 1708 { 1709 if (log) 1710 log->Printf("[Debugger::FormatPrompt] checking if I can handle as array"); 1711 if (!is_array && !is_pointer) 1712 break; 1713 if (log) 1714 log->Printf("[Debugger::FormatPrompt] handle as array"); 1715 const char* special_directions = NULL; 1716 StreamString special_directions_writer; 1717 if (close_bracket_position && (var_name_end-close_bracket_position > 1)) 1718 { 1719 ConstString additional_data; 1720 additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1); 1721 special_directions_writer.Printf("${%svar%s}", 1722 do_deref_pointer ? "*" : "", 1723 additional_data.GetCString()); 1724 special_directions = special_directions_writer.GetData(); 1725 } 1726 1727 // let us display items index_lower thru index_higher of this array 1728 s.PutChar('['); 1729 var_success = true; 1730 1731 if (index_higher < 0) 1732 index_higher = valobj->GetNumChildren() - 1; 1733 1734 uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); 1735 1736 for (;index_lower<=index_higher;index_lower++) 1737 { 1738 ValueObject* item = ExpandIndexedExpression (target, 1739 index_lower, 1740 exe_ctx->GetFramePtr(), 1741 false).get(); 1742 1743 if (!item) 1744 { 1745 if (log) 1746 log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower); 1747 } 1748 else 1749 { 1750 if (log) 1751 log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions); 1752 } 1753 1754 if (!special_directions) 1755 var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format); 1756 else 1757 var_success &= FormatPromptRecurse(special_directions, sc, exe_ctx, addr, s, NULL, item); 1758 1759 if (--max_num_children == 0) 1760 { 1761 s.PutCString(", ..."); 1762 break; 1763 } 1764 1765 if (index_lower < index_higher) 1766 s.PutChar(','); 1767 } 1768 s.PutChar(']'); 1769 } 1770 } 1771 break; 1772 case 'a': 1773 if (::strncmp (var_name_begin, "addr}", strlen("addr}")) == 0) 1774 { 1775 if (addr && addr->IsValid()) 1776 { 1777 var_success = true; 1778 format_addr = *addr; 1779 } 1780 } 1781 break; 1782 1783 case 'p': 1784 if (::strncmp (var_name_begin, "process.", strlen("process.")) == 0) 1785 { 1786 if (exe_ctx) 1787 { 1788 Process *process = exe_ctx->GetProcessPtr(); 1789 if (process) 1790 { 1791 var_name_begin += ::strlen ("process."); 1792 if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 1793 { 1794 s.Printf("%" PRIu64, process->GetID()); 1795 var_success = true; 1796 } 1797 else if ((::strncmp (var_name_begin, "name}", strlen("name}")) == 0) || 1798 (::strncmp (var_name_begin, "file.basename}", strlen("file.basename}")) == 0) || 1799 (::strncmp (var_name_begin, "file.fullpath}", strlen("file.fullpath}")) == 0)) 1800 { 1801 Module *exe_module = process->GetTarget().GetExecutableModulePointer(); 1802 if (exe_module) 1803 { 1804 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f') 1805 { 1806 format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename(); 1807 var_success = format_file_spec; 1808 } 1809 else 1810 { 1811 format_file_spec = exe_module->GetFileSpec(); 1812 var_success = format_file_spec; 1813 } 1814 } 1815 } 1816 else if (::strncmp(var_name_begin, "script:", strlen("script:")) == 0) 1817 { 1818 var_name_begin += ::strlen("script:"); 1819 std::string script_name(var_name_begin,var_name_end); 1820 ScriptInterpreter* script_interpreter = process->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 1821 if (script_interpreter) 1822 { 1823 std::string script_output; 1824 Error script_error; 1825 if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), process,script_output,script_error) && script_error.Success()) 1826 { 1827 s.Printf("%s", script_output.c_str()); 1828 var_success = true; 1829 } 1830 else 1831 s.Printf("<error: %s>",script_error.AsCString()); 1832 } 1833 } 1834 } 1835 } 1836 } 1837 break; 1838 1839 case 't': 1840 if (::strncmp (var_name_begin, "thread.", strlen("thread.")) == 0) 1841 { 1842 if (exe_ctx) 1843 { 1844 Thread *thread = exe_ctx->GetThreadPtr(); 1845 if (thread) 1846 { 1847 var_name_begin += ::strlen ("thread."); 1848 if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 1849 { 1850 s.Printf("0x%4.4" PRIx64, thread->GetID()); 1851 var_success = true; 1852 } 1853 else if (::strncmp (var_name_begin, "protocol_id}", strlen("protocol_id}")) == 0) 1854 { 1855 s.Printf("0x%4.4" PRIx64, thread->GetProtocolID()); 1856 var_success = true; 1857 } 1858 else if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0) 1859 { 1860 s.Printf("%u", thread->GetIndexID()); 1861 var_success = true; 1862 } 1863 else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0) 1864 { 1865 cstr = thread->GetName(); 1866 var_success = cstr && cstr[0]; 1867 if (var_success) 1868 s.PutCString(cstr); 1869 } 1870 else if (::strncmp (var_name_begin, "queue}", strlen("queue}")) == 0) 1871 { 1872 cstr = thread->GetQueueName(); 1873 var_success = cstr && cstr[0]; 1874 if (var_success) 1875 s.PutCString(cstr); 1876 } 1877 else if (::strncmp (var_name_begin, "stop-reason}", strlen("stop-reason}")) == 0) 1878 { 1879 StopInfoSP stop_info_sp = thread->GetStopInfo (); 1880 if (stop_info_sp && stop_info_sp->IsValid()) 1881 { 1882 cstr = stop_info_sp->GetDescription(); 1883 if (cstr && cstr[0]) 1884 { 1885 s.PutCString(cstr); 1886 var_success = true; 1887 } 1888 } 1889 } 1890 else if (::strncmp (var_name_begin, "return-value}", strlen("return-value}")) == 0) 1891 { 1892 StopInfoSP stop_info_sp = thread->GetStopInfo (); 1893 if (stop_info_sp && stop_info_sp->IsValid()) 1894 { 1895 ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); 1896 if (return_valobj_sp) 1897 { 1898 ValueObject::DumpValueObject (s, return_valobj_sp.get()); 1899 var_success = true; 1900 } 1901 } 1902 } 1903 else if (::strncmp(var_name_begin, "script:", strlen("script:")) == 0) 1904 { 1905 var_name_begin += ::strlen("script:"); 1906 std::string script_name(var_name_begin,var_name_end); 1907 ScriptInterpreter* script_interpreter = thread->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 1908 if (script_interpreter) 1909 { 1910 std::string script_output; 1911 Error script_error; 1912 if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), thread,script_output,script_error) && script_error.Success()) 1913 { 1914 s.Printf("%s", script_output.c_str()); 1915 var_success = true; 1916 } 1917 else 1918 s.Printf("<error: %s>",script_error.AsCString()); 1919 } 1920 } 1921 } 1922 } 1923 } 1924 else if (::strncmp (var_name_begin, "target.", strlen("target.")) == 0) 1925 { 1926 // TODO: hookup properties 1927 // if (!target_properties_sp) 1928 // { 1929 // Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 1930 // if (target) 1931 // target_properties_sp = target->GetProperties(); 1932 // } 1933 // 1934 // if (target_properties_sp) 1935 // { 1936 // var_name_begin += ::strlen ("target."); 1937 // const char *end_property = strchr(var_name_begin, '}'); 1938 // if (end_property) 1939 // { 1940 // ConstString property_name(var_name_begin, end_property - var_name_begin); 1941 // std::string property_value (target_properties_sp->GetPropertyValue(property_name)); 1942 // if (!property_value.empty()) 1943 // { 1944 // s.PutCString (property_value.c_str()); 1945 // var_success = true; 1946 // } 1947 // } 1948 // } 1949 Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 1950 if (target) 1951 { 1952 var_name_begin += ::strlen ("target."); 1953 if (::strncmp (var_name_begin, "arch}", strlen("arch}")) == 0) 1954 { 1955 ArchSpec arch (target->GetArchitecture ()); 1956 if (arch.IsValid()) 1957 { 1958 s.PutCString (arch.GetArchitectureName()); 1959 var_success = true; 1960 } 1961 } 1962 else if (::strncmp(var_name_begin, "script:", strlen("script:")) == 0) 1963 { 1964 var_name_begin += ::strlen("script:"); 1965 std::string script_name(var_name_begin,var_name_end); 1966 ScriptInterpreter* script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 1967 if (script_interpreter) 1968 { 1969 std::string script_output; 1970 Error script_error; 1971 if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), target,script_output,script_error) && script_error.Success()) 1972 { 1973 s.Printf("%s", script_output.c_str()); 1974 var_success = true; 1975 } 1976 else 1977 s.Printf("<error: %s>",script_error.AsCString()); 1978 } 1979 } 1980 } 1981 } 1982 break; 1983 1984 1985 case 'm': 1986 if (::strncmp (var_name_begin, "module.", strlen("module.")) == 0) 1987 { 1988 if (sc && sc->module_sp.get()) 1989 { 1990 Module *module = sc->module_sp.get(); 1991 var_name_begin += ::strlen ("module."); 1992 1993 if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 1994 { 1995 if (module->GetFileSpec()) 1996 { 1997 var_name_begin += ::strlen ("file."); 1998 1999 if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 2000 { 2001 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename(); 2002 var_success = format_file_spec; 2003 } 2004 else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 2005 { 2006 format_file_spec = module->GetFileSpec(); 2007 var_success = format_file_spec; 2008 } 2009 } 2010 } 2011 } 2012 } 2013 break; 2014 2015 2016 case 'f': 2017 if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 2018 { 2019 if (sc && sc->comp_unit != NULL) 2020 { 2021 var_name_begin += ::strlen ("file."); 2022 2023 if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 2024 { 2025 format_file_spec.GetFilename() = sc->comp_unit->GetFilename(); 2026 var_success = format_file_spec; 2027 } 2028 else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 2029 { 2030 format_file_spec = *sc->comp_unit; 2031 var_success = format_file_spec; 2032 } 2033 } 2034 } 2035 else if (::strncmp (var_name_begin, "frame.", strlen("frame.")) == 0) 2036 { 2037 if (exe_ctx) 2038 { 2039 StackFrame *frame = exe_ctx->GetFramePtr(); 2040 if (frame) 2041 { 2042 var_name_begin += ::strlen ("frame."); 2043 if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0) 2044 { 2045 s.Printf("%u", frame->GetFrameIndex()); 2046 var_success = true; 2047 } 2048 else if (::strncmp (var_name_begin, "pc}", strlen("pc}")) == 0) 2049 { 2050 reg_kind = eRegisterKindGeneric; 2051 reg_num = LLDB_REGNUM_GENERIC_PC; 2052 var_success = true; 2053 } 2054 else if (::strncmp (var_name_begin, "sp}", strlen("sp}")) == 0) 2055 { 2056 reg_kind = eRegisterKindGeneric; 2057 reg_num = LLDB_REGNUM_GENERIC_SP; 2058 var_success = true; 2059 } 2060 else if (::strncmp (var_name_begin, "fp}", strlen("fp}")) == 0) 2061 { 2062 reg_kind = eRegisterKindGeneric; 2063 reg_num = LLDB_REGNUM_GENERIC_FP; 2064 var_success = true; 2065 } 2066 else if (::strncmp (var_name_begin, "flags}", strlen("flags}")) == 0) 2067 { 2068 reg_kind = eRegisterKindGeneric; 2069 reg_num = LLDB_REGNUM_GENERIC_FLAGS; 2070 var_success = true; 2071 } 2072 else if (::strncmp (var_name_begin, "reg.", strlen ("reg.")) == 0) 2073 { 2074 reg_ctx = frame->GetRegisterContext().get(); 2075 if (reg_ctx) 2076 { 2077 var_name_begin += ::strlen ("reg."); 2078 if (var_name_begin < var_name_end) 2079 { 2080 std::string reg_name (var_name_begin, var_name_end); 2081 reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str()); 2082 if (reg_info) 2083 var_success = true; 2084 } 2085 } 2086 } 2087 else if (::strncmp(var_name_begin, "script:", strlen("script:")) == 0) 2088 { 2089 var_name_begin += ::strlen("script:"); 2090 std::string script_name(var_name_begin,var_name_end); 2091 ScriptInterpreter* script_interpreter = frame->GetThread()->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 2092 if (script_interpreter) 2093 { 2094 std::string script_output; 2095 Error script_error; 2096 if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), frame,script_output,script_error) && script_error.Success()) 2097 { 2098 s.Printf("%s", script_output.c_str()); 2099 var_success = true; 2100 } 2101 else 2102 s.Printf("<error: %s>",script_error.AsCString()); 2103 } 2104 } 2105 } 2106 } 2107 } 2108 else if (::strncmp (var_name_begin, "function.", strlen("function.")) == 0) 2109 { 2110 if (sc && (sc->function != NULL || sc->symbol != NULL)) 2111 { 2112 var_name_begin += ::strlen ("function."); 2113 if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 2114 { 2115 if (sc->function) 2116 s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID()); 2117 else 2118 s.Printf("symbol[%u]", sc->symbol->GetID()); 2119 2120 var_success = true; 2121 } 2122 else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0) 2123 { 2124 if (sc->function) 2125 cstr = sc->function->GetName().AsCString (NULL); 2126 else if (sc->symbol) 2127 cstr = sc->symbol->GetName().AsCString (NULL); 2128 if (cstr) 2129 { 2130 s.PutCString(cstr); 2131 2132 if (sc->block) 2133 { 2134 Block *inline_block = sc->block->GetContainingInlinedBlock (); 2135 if (inline_block) 2136 { 2137 const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo(); 2138 if (inline_info) 2139 { 2140 s.PutCString(" [inlined] "); 2141 inline_info->GetName().Dump(&s); 2142 } 2143 } 2144 } 2145 var_success = true; 2146 } 2147 } 2148 else if (::strncmp (var_name_begin, "name-with-args}", strlen("name-with-args}")) == 0) 2149 { 2150 // Print the function name with arguments in it 2151 2152 if (sc->function) 2153 { 2154 var_success = true; 2155 ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL; 2156 cstr = sc->function->GetName().AsCString (NULL); 2157 if (cstr) 2158 { 2159 const InlineFunctionInfo *inline_info = NULL; 2160 VariableListSP variable_list_sp; 2161 bool get_function_vars = true; 2162 if (sc->block) 2163 { 2164 Block *inline_block = sc->block->GetContainingInlinedBlock (); 2165 2166 if (inline_block) 2167 { 2168 get_function_vars = false; 2169 inline_info = sc->block->GetInlinedFunctionInfo(); 2170 if (inline_info) 2171 variable_list_sp = inline_block->GetBlockVariableList (true); 2172 } 2173 } 2174 2175 if (get_function_vars) 2176 { 2177 variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true); 2178 } 2179 2180 if (inline_info) 2181 { 2182 s.PutCString (cstr); 2183 s.PutCString (" [inlined] "); 2184 cstr = inline_info->GetName().GetCString(); 2185 } 2186 2187 VariableList args; 2188 if (variable_list_sp) 2189 variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args); 2190 if (args.GetSize() > 0) 2191 { 2192 const char *open_paren = strchr (cstr, '('); 2193 const char *close_paren = NULL; 2194 if (open_paren) 2195 { 2196 if (strncmp(open_paren, "(anonymous namespace)", strlen("(anonymous namespace)")) == 0) 2197 { 2198 open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '('); 2199 if (open_paren) 2200 close_paren = strchr (open_paren, ')'); 2201 } 2202 else 2203 close_paren = strchr (open_paren, ')'); 2204 } 2205 2206 if (open_paren) 2207 s.Write(cstr, open_paren - cstr + 1); 2208 else 2209 { 2210 s.PutCString (cstr); 2211 s.PutChar ('('); 2212 } 2213 const size_t num_args = args.GetSize(); 2214 for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) 2215 { 2216 VariableSP var_sp (args.GetVariableAtIndex (arg_idx)); 2217 ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp)); 2218 const char *var_name = var_value_sp->GetName().GetCString(); 2219 const char *var_value = var_value_sp->GetValueAsCString(); 2220 if (arg_idx > 0) 2221 s.PutCString (", "); 2222 if (var_value_sp->GetError().Success()) 2223 { 2224 if (var_value) 2225 s.Printf ("%s=%s", var_name, var_value); 2226 else 2227 s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString()); 2228 } 2229 else 2230 s.Printf ("%s=<unavailable>", var_name); 2231 } 2232 2233 if (close_paren) 2234 s.PutCString (close_paren); 2235 else 2236 s.PutChar(')'); 2237 2238 } 2239 else 2240 { 2241 s.PutCString(cstr); 2242 } 2243 } 2244 } 2245 else if (sc->symbol) 2246 { 2247 cstr = sc->symbol->GetName().AsCString (NULL); 2248 if (cstr) 2249 { 2250 s.PutCString(cstr); 2251 var_success = true; 2252 } 2253 } 2254 } 2255 else if (::strncmp (var_name_begin, "addr-offset}", strlen("addr-offset}")) == 0) 2256 { 2257 var_success = addr != NULL; 2258 if (var_success) 2259 { 2260 format_addr = *addr; 2261 calculate_format_addr_function_offset = true; 2262 } 2263 } 2264 else if (::strncmp (var_name_begin, "line-offset}", strlen("line-offset}")) == 0) 2265 { 2266 var_success = sc->line_entry.range.GetBaseAddress().IsValid(); 2267 if (var_success) 2268 { 2269 format_addr = sc->line_entry.range.GetBaseAddress(); 2270 calculate_format_addr_function_offset = true; 2271 } 2272 } 2273 else if (::strncmp (var_name_begin, "pc-offset}", strlen("pc-offset}")) == 0) 2274 { 2275 StackFrame *frame = exe_ctx->GetFramePtr(); 2276 var_success = frame != NULL; 2277 if (var_success) 2278 { 2279 format_addr = frame->GetFrameCodeAddress(); 2280 calculate_format_addr_function_offset = true; 2281 } 2282 } 2283 } 2284 } 2285 break; 2286 2287 case 'l': 2288 if (::strncmp (var_name_begin, "line.", strlen("line.")) == 0) 2289 { 2290 if (sc && sc->line_entry.IsValid()) 2291 { 2292 var_name_begin += ::strlen ("line."); 2293 if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 2294 { 2295 var_name_begin += ::strlen ("file."); 2296 2297 if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 2298 { 2299 format_file_spec.GetFilename() = sc->line_entry.file.GetFilename(); 2300 var_success = format_file_spec; 2301 } 2302 else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 2303 { 2304 format_file_spec = sc->line_entry.file; 2305 var_success = format_file_spec; 2306 } 2307 } 2308 else if (::strncmp (var_name_begin, "number}", strlen("number}")) == 0) 2309 { 2310 var_success = true; 2311 s.Printf("%u", sc->line_entry.line); 2312 } 2313 else if ((::strncmp (var_name_begin, "start-addr}", strlen("start-addr}")) == 0) || 2314 (::strncmp (var_name_begin, "end-addr}", strlen("end-addr}")) == 0)) 2315 { 2316 var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid(); 2317 if (var_success) 2318 { 2319 format_addr = sc->line_entry.range.GetBaseAddress(); 2320 if (var_name_begin[0] == 'e') 2321 format_addr.Slide (sc->line_entry.range.GetByteSize()); 2322 } 2323 } 2324 } 2325 } 2326 break; 2327 } 2328 2329 if (var_success) 2330 { 2331 // If format addr is valid, then we need to print an address 2332 if (reg_num != LLDB_INVALID_REGNUM) 2333 { 2334 StackFrame *frame = exe_ctx->GetFramePtr(); 2335 // We have a register value to display... 2336 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric) 2337 { 2338 format_addr = frame->GetFrameCodeAddress(); 2339 } 2340 else 2341 { 2342 if (reg_ctx == NULL) 2343 reg_ctx = frame->GetRegisterContext().get(); 2344 2345 if (reg_ctx) 2346 { 2347 if (reg_kind != kNumRegisterKinds) 2348 reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num); 2349 reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num); 2350 var_success = reg_info != NULL; 2351 } 2352 } 2353 } 2354 2355 if (reg_info != NULL) 2356 { 2357 RegisterValue reg_value; 2358 var_success = reg_ctx->ReadRegister (reg_info, reg_value); 2359 if (var_success) 2360 { 2361 reg_value.Dump(&s, reg_info, false, false, eFormatDefault); 2362 } 2363 } 2364 2365 if (format_file_spec) 2366 { 2367 s << format_file_spec; 2368 } 2369 2370 // If format addr is valid, then we need to print an address 2371 if (format_addr.IsValid()) 2372 { 2373 var_success = false; 2374 2375 if (calculate_format_addr_function_offset) 2376 { 2377 Address func_addr; 2378 2379 if (sc) 2380 { 2381 if (sc->function) 2382 { 2383 func_addr = sc->function->GetAddressRange().GetBaseAddress(); 2384 if (sc->block) 2385 { 2386 // Check to make sure we aren't in an inline 2387 // function. If we are, use the inline block 2388 // range that contains "format_addr" since 2389 // blocks can be discontiguous. 2390 Block *inline_block = sc->block->GetContainingInlinedBlock (); 2391 AddressRange inline_range; 2392 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range)) 2393 func_addr = inline_range.GetBaseAddress(); 2394 } 2395 } 2396 else if (sc->symbol && sc->symbol->ValueIsAddress()) 2397 func_addr = sc->symbol->GetAddress(); 2398 } 2399 2400 if (func_addr.IsValid()) 2401 { 2402 if (func_addr.GetSection() == format_addr.GetSection()) 2403 { 2404 addr_t func_file_addr = func_addr.GetFileAddress(); 2405 addr_t addr_file_addr = format_addr.GetFileAddress(); 2406 if (addr_file_addr > func_file_addr) 2407 s.Printf(" + %" PRIu64, addr_file_addr - func_file_addr); 2408 else if (addr_file_addr < func_file_addr) 2409 s.Printf(" - %" PRIu64, func_file_addr - addr_file_addr); 2410 var_success = true; 2411 } 2412 else 2413 { 2414 Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 2415 if (target) 2416 { 2417 addr_t func_load_addr = func_addr.GetLoadAddress (target); 2418 addr_t addr_load_addr = format_addr.GetLoadAddress (target); 2419 if (addr_load_addr > func_load_addr) 2420 s.Printf(" + %" PRIu64, addr_load_addr - func_load_addr); 2421 else if (addr_load_addr < func_load_addr) 2422 s.Printf(" - %" PRIu64, func_load_addr - addr_load_addr); 2423 var_success = true; 2424 } 2425 } 2426 } 2427 } 2428 else 2429 { 2430 Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 2431 addr_t vaddr = LLDB_INVALID_ADDRESS; 2432 if (exe_ctx && !target->GetSectionLoadList().IsEmpty()) 2433 vaddr = format_addr.GetLoadAddress (target); 2434 if (vaddr == LLDB_INVALID_ADDRESS) 2435 vaddr = format_addr.GetFileAddress (); 2436 2437 if (vaddr != LLDB_INVALID_ADDRESS) 2438 { 2439 int addr_width = target->GetArchitecture().GetAddressByteSize() * 2; 2440 if (addr_width == 0) 2441 addr_width = 16; 2442 s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr); 2443 var_success = true; 2444 } 2445 } 2446 } 2447 } 2448 2449 if (var_success == false) 2450 success = false; 2451 } 2452 p = var_name_end; 2453 } 2454 else 2455 break; 2456 } 2457 else 2458 { 2459 // We got a dollar sign with no '{' after it, it must just be a dollar sign 2460 s.PutChar(*p); 2461 } 2462 } 2463 else if (*p == '\\') 2464 { 2465 ++p; // skip the slash 2466 switch (*p) 2467 { 2468 case 'a': s.PutChar ('\a'); break; 2469 case 'b': s.PutChar ('\b'); break; 2470 case 'f': s.PutChar ('\f'); break; 2471 case 'n': s.PutChar ('\n'); break; 2472 case 'r': s.PutChar ('\r'); break; 2473 case 't': s.PutChar ('\t'); break; 2474 case 'v': s.PutChar ('\v'); break; 2475 case '\'': s.PutChar ('\''); break; 2476 case '\\': s.PutChar ('\\'); break; 2477 case '0': 2478 // 1 to 3 octal chars 2479 { 2480 // Make a string that can hold onto the initial zero char, 2481 // up to 3 octal digits, and a terminating NULL. 2482 char oct_str[5] = { 0, 0, 0, 0, 0 }; 2483 2484 int i; 2485 for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i) 2486 oct_str[i] = p[i]; 2487 2488 // We don't want to consume the last octal character since 2489 // the main for loop will do this for us, so we advance p by 2490 // one less than i (even if i is zero) 2491 p += i - 1; 2492 unsigned long octal_value = ::strtoul (oct_str, NULL, 8); 2493 if (octal_value <= UINT8_MAX) 2494 { 2495 s.PutChar((char)octal_value); 2496 } 2497 } 2498 break; 2499 2500 case 'x': 2501 // hex number in the format 2502 if (isxdigit(p[1])) 2503 { 2504 ++p; // Skip the 'x' 2505 2506 // Make a string that can hold onto two hex chars plus a 2507 // NULL terminator 2508 char hex_str[3] = { 0,0,0 }; 2509 hex_str[0] = *p; 2510 if (isxdigit(p[1])) 2511 { 2512 ++p; // Skip the first of the two hex chars 2513 hex_str[1] = *p; 2514 } 2515 2516 unsigned long hex_value = strtoul (hex_str, NULL, 16); 2517 if (hex_value <= UINT8_MAX) 2518 s.PutChar ((char)hex_value); 2519 } 2520 else 2521 { 2522 s.PutChar('x'); 2523 } 2524 break; 2525 2526 default: 2527 // Just desensitize any other character by just printing what 2528 // came after the '\' 2529 s << *p; 2530 break; 2531 2532 } 2533 2534 } 2535 } 2536 if (end) 2537 *end = p; 2538 return success; 2539 } 2540 2541 bool 2542 Debugger::FormatPrompt 2543 ( 2544 const char *format, 2545 const SymbolContext *sc, 2546 const ExecutionContext *exe_ctx, 2547 const Address *addr, 2548 Stream &s, 2549 ValueObject* valobj 2550 ) 2551 { 2552 bool use_color = exe_ctx ? exe_ctx->GetTargetRef().GetDebugger().GetUseColor() : true; 2553 std::string format_str = lldb_utility::ansi::FormatAnsiTerminalCodes (format, use_color); 2554 if (format_str.length()) 2555 format = format_str.c_str(); 2556 return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, valobj); 2557 } 2558 2559 void 2560 Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton) 2561 { 2562 // For simplicity's sake, I am not going to deal with how to close down any 2563 // open logging streams, I just redirect everything from here on out to the 2564 // callback. 2565 m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 2566 } 2567 2568 bool 2569 Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream) 2570 { 2571 Log::Callbacks log_callbacks; 2572 2573 StreamSP log_stream_sp; 2574 if (m_log_callback_stream_sp) 2575 { 2576 log_stream_sp = m_log_callback_stream_sp; 2577 // For now when using the callback mode you always get thread & timestamp. 2578 log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; 2579 } 2580 else if (log_file == NULL || *log_file == '\0') 2581 { 2582 log_stream_sp.reset(new StreamFile(GetOutputFile().GetDescriptor(), false)); 2583 } 2584 else 2585 { 2586 LogStreamMap::iterator pos = m_log_streams.find(log_file); 2587 if (pos != m_log_streams.end()) 2588 log_stream_sp = pos->second.lock(); 2589 if (!log_stream_sp) 2590 { 2591 log_stream_sp.reset (new StreamFile (log_file)); 2592 m_log_streams[log_file] = log_stream_sp; 2593 } 2594 } 2595 assert (log_stream_sp.get()); 2596 2597 if (log_options == 0) 2598 log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE; 2599 2600 if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks)) 2601 { 2602 log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream); 2603 return true; 2604 } 2605 else 2606 { 2607 LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel)); 2608 if (log_channel_sp) 2609 { 2610 if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories)) 2611 { 2612 return true; 2613 } 2614 else 2615 { 2616 error_stream.Printf ("Invalid log channel '%s'.\n", channel); 2617 return false; 2618 } 2619 } 2620 else 2621 { 2622 error_stream.Printf ("Invalid log channel '%s'.\n", channel); 2623 return false; 2624 } 2625 } 2626 return false; 2627 } 2628 2629 SourceManager & 2630 Debugger::GetSourceManager () 2631 { 2632 if (m_source_manager_ap.get() == NULL) 2633 m_source_manager_ap.reset (new SourceManager (shared_from_this())); 2634 return *m_source_manager_ap; 2635 } 2636 2637 2638