diff options
Diffstat (limited to 'lldb/source/Core/Debugger.cpp')
-rw-r--r-- | lldb/source/Core/Debugger.cpp | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 4a159145c6e..bb982f3e4db 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -15,6 +15,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/Type.h" +#include "llvm/ADT/StringRef.h" #include "lldb/lldb-private.h" #include "lldb/Core/ConnectionFileDescriptor.h" @@ -26,6 +27,7 @@ #include "lldb/Core/StreamCallback.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/StreamString.h" +#include "lldb/Core/StructuredData.h" #include "lldb/Core/Timer.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectVariable.h" @@ -105,6 +107,8 @@ g_language_enumerators[] = FILE_AND_LINE\ "{, name = '${thread.name}'}"\ "{, queue = '${thread.queue}'}"\ + "{, activity = '${thread.info.activity.name}'}" \ + "{, ${thread.info.trace_messages} messages}" \ "{, stop reason = ${thread.stop-reason}}"\ "{\\nReturn value: ${thread.return-value}}"\ "\\n" @@ -1430,6 +1434,96 @@ IsTokenWithFormat(const char *var_name_begin, const char *var, std::string &form return false; } +// Find information for the "thread.info.*" specifiers in a format string +static bool +FormatThreadExtendedInfoRecurse +( + const char *var_name_begin, + StructuredData::ObjectSP thread_info_dictionary, + const SymbolContext *sc, + const ExecutionContext *exe_ctx, + Stream &s +) +{ + bool var_success = false; + std::string token_format; + + llvm::StringRef var_name(var_name_begin); + size_t percent_idx = var_name.find('%'); + size_t close_curly_idx = var_name.find('}'); + llvm::StringRef path = var_name; + llvm::StringRef formatter = var_name; + + // 'path' will be the dot separated list of objects to transverse up until we hit + // a close curly brace, a percent sign, or an end of string. + if (percent_idx != llvm::StringRef::npos || close_curly_idx != llvm::StringRef::npos) + { + if (percent_idx != llvm::StringRef::npos && close_curly_idx != llvm::StringRef::npos) + { + if (percent_idx < close_curly_idx) + { + path = var_name.slice(0, percent_idx); + formatter = var_name.substr (percent_idx); + } + else + { + path = var_name.slice(0, close_curly_idx); + formatter = var_name.substr (close_curly_idx); + } + } + else if (percent_idx != llvm::StringRef::npos) + { + path = var_name.slice(0, percent_idx); + formatter = var_name.substr (percent_idx); + } + else if (close_curly_idx != llvm::StringRef::npos) + { + path = var_name.slice(0, close_curly_idx); + formatter = var_name.substr (close_curly_idx); + } + } + + StructuredData::ObjectSP value = thread_info_dictionary->GetObjectForDotSeparatedPath (path); + + if (value.get()) + { + if (value->GetType() == StructuredData::Type::eTypeInteger) + { + if (IsTokenWithFormat (formatter.str().c_str(), "", token_format, "0x%4.4" PRIx64, exe_ctx, sc)) + { + s.Printf(token_format.c_str(), value->GetAsInteger()->GetValue()); + var_success = true; + } + } + else if (value->GetType() == StructuredData::Type::eTypeFloat) + { + s.Printf ("%f", value->GetAsFloat()->GetValue()); + var_success = true; + } + else if (value->GetType() == StructuredData::Type::eTypeString) + { + s.Printf("%s", value->GetAsString()->GetValue().c_str()); + var_success = true; + } + else if (value->GetType() == StructuredData::Type::eTypeArray) + { + if (value->GetAsArray()->GetSize() > 0) + { + s.Printf ("%zu", value->GetAsArray()->GetSize()); + var_success = true; + } + } + else if (value->GetType() == StructuredData::Type::eTypeDictionary) + { + s.Printf ("%zu", value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize()); + var_success = true; + } + } + + return var_success; +} + + static bool FormatPromptRecurse ( @@ -1969,6 +2063,15 @@ FormatPromptRecurse if (RunScriptFormatKeyword (s, script_interpreter, thread, script_name)) var_success = true; } + else if (IsToken (var_name_begin, "info.")) + { + var_name_begin += ::strlen("info."); + StructuredData::ObjectSP object_sp = thread->GetExtendedInfo(); + if (object_sp && object_sp->GetType() == StructuredData::Type::eTypeDictionary) + { + var_success = FormatThreadExtendedInfoRecurse (var_name_begin, object_sp, sc, exe_ctx, s); + } + } } } } |