[Lldb-commits] [lldb] Colorize output when searching for symbols in lldb (PR #69422)
José Lira Junior via lldb-commits
lldb-commits at lists.llvm.org
Wed Nov 22 12:59:06 PST 2023
https://github.com/junior-jl updated https://github.com/llvm/llvm-project/pull/69422
>From 8e5e67ff640aa0ff14b1a0bd0110b88c539ccfe8 Mon Sep 17 00:00:00 2001
From: taalhaataahir0102 <23100293 at lums.edu.pk>
Date: Wed, 11 Oct 2023 14:27:15 +0500
Subject: [PATCH 1/3] colorization
---
lldb/include/lldb/Core/Address.h | 6 +
lldb/include/lldb/Symbol/Symbol.h | 3 +
lldb/include/lldb/Symbol/SymbolContext.h | 11 +
lldb/source/Commands/CommandObjectTarget.cpp | 97 ++++-
lldb/source/Core/Address.cpp | 428 +++++++++++++++++++
lldb/source/Symbol/Symbol.cpp | 68 +++
lldb/source/Symbol/SymbolContext.cpp | 248 +++++++++++
7 files changed, 859 insertions(+), 2 deletions(-)
diff --git a/lldb/include/lldb/Core/Address.h b/lldb/include/lldb/Core/Address.h
index b19e694427546f8b..4151817813c7e352 100644
--- a/lldb/include/lldb/Core/Address.h
+++ b/lldb/include/lldb/Core/Address.h
@@ -249,6 +249,12 @@ class Address {
uint32_t addr_byte_size = UINT32_MAX,
bool all_ranges = false) const;
+
+ bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,const char* name,
+ DumpStyle fallback_style = DumpStyleInvalid,
+ uint32_t addr_byte_size = UINT32_MAX,
+ bool all_ranges = false) const;
+
AddressClass GetAddressClass() const;
/// Get the file address.
diff --git a/lldb/include/lldb/Symbol/Symbol.h b/lldb/include/lldb/Symbol/Symbol.h
index 44a2d560010fe403..a9e91fbac055a924 100644
--- a/lldb/include/lldb/Symbol/Symbol.h
+++ b/lldb/include/lldb/Symbol/Symbol.h
@@ -177,6 +177,9 @@ class Symbol : public SymbolContextScope {
void GetDescription(Stream *s, lldb::DescriptionLevel level,
Target *target) const;
+ void GetDescription(Stream *s, lldb::DescriptionLevel level,
+ Target *target, const char* name) const;
+
bool IsSynthetic() const { return m_is_synthetic; }
bool IsSyntheticWithAutoGeneratedName() const;
diff --git a/lldb/include/lldb/Symbol/SymbolContext.h b/lldb/include/lldb/Symbol/SymbolContext.h
index b0f5ffead2a16569..947c39eec96e53a9 100644
--- a/lldb/include/lldb/Symbol/SymbolContext.h
+++ b/lldb/include/lldb/Symbol/SymbolContext.h
@@ -153,6 +153,14 @@ class SymbolContext {
bool show_function_arguments,
bool show_function_name) const;
+ bool DumpStopContext(Stream *s, ExecutionContextScope *exe_scope,
+ const Address &so_addr, bool show_fullpaths,
+ bool show_module, bool show_inlined_frames,
+ bool show_function_arguments,
+ bool show_function_name,
+ const char* name) const;
+
+
/// Get the address range contained within a symbol context.
///
/// Address range priority is as follows:
@@ -220,6 +228,9 @@ class SymbolContext {
void GetDescription(Stream *s, lldb::DescriptionLevel level,
Target *target) const;
+ void GetDescription(Stream *s, lldb::DescriptionLevel level,
+ Target *target, const char* name) const;
+
uint32_t GetResolvedMask() const;
lldb::LanguageType GetLanguage() const;
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index 33330ef0926d61f0..aa59e3680a37872c 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -1513,6 +1513,98 @@ static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
return false;
}
+//===========================================================================================
+static void PrintRed(Stream &strm, const char *text, const char *name) {
+ const char *red_start = "\033[31m"; // Set text color to red
+ const char *reset_color = "\033[0m"; // Reset text color to default
+
+ // Escape1(ansi.red)
+
+ const char *match = text;
+ size_t name_len = strlen(name);
+
+ while ((match = strstr(match, name))) {
+ size_t prefix_len = match - text;
+
+ strm.Write(text, prefix_len);
+ strm.PutCString(red_start);
+ strm.Write(match, name_len);
+ strm.PutCString(reset_color);
+
+ text = match + name_len;
+ match = text;
+ }
+
+ strm.PutCString(text); // Print any remaining text
+}
+
+
+// static void PrintRed(Stream &strm, const char *text, const char *name) {
+// const char *red_start = "\033[31m"; // Set text color to red
+// const char *reset_color = "\033[0m"; // Reset text color to default
+
+// const char *match = text;
+
+// // Split the name into parts using the delimiter '|'
+// std::vector<std::string> name_parts;
+// const char *delimiter = "|"; // Delimiter for splitting the name
+// const char *token = strtok(const_cast<char *>(name), delimiter);
+// while (token) {
+// name_parts.push_back(token);
+// token = strtok(nullptr, delimiter);
+// }
+
+// // Initialize a variable to keep track of the current position in the text
+// size_t current_pos = 0;
+
+// // Iterate through each name part and apply colorization
+// for (const std::string &part : name_parts) {
+// match = text + current_pos;
+// match = strstr(match, part.c_str());
+
+// if (match) {
+// size_t prefix_len = match - (text + current_pos);
+// current_pos += prefix_len;
+
+// strm.Write(text + current_pos, prefix_len);
+// strm.PutCString(red_start);
+// strm.Write(match, part.length());
+// strm.PutCString(reset_color);
+
+// current_pos += part.length();
+// }
+// }
+
+// // Print any remaining text
+// if (current_pos < strlen(text)) {
+// strm.PutCString(text + current_pos);
+// }
+// }
+
+static void DumpAddress(ExecutionContextScope *exe_scope,
+ const Address &so_addr, bool verbose, bool all_ranges,
+ Stream &strm, const char *name) {
+ strm.IndentMore();
+ strm.Indent(" Address: ");
+ so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress, name);
+ strm.PutCString(" (");
+ so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset, name);
+ strm.PutCString(")\n");
+ strm.Indent(" Summary: ");
+ const uint32_t save_indent = strm.GetIndentLevel();
+ strm.SetIndentLevel(save_indent + 13);
+ so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription, name);
+ strm.SetIndentLevel(save_indent);
+ // Print out detailed address information when verbose is enabled
+ if (verbose) {
+ strm.EOL();
+ so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext, name,
+ Address::DumpStyleInvalid, UINT32_MAX, all_ranges);
+ }
+ strm.IndentLess();
+}
+
+//===========================================================================================
static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
Stream &strm, Module *module,
const char *name, bool name_is_regex,
@@ -1550,12 +1642,13 @@ static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
if (symbol->ValueIsAddress()) {
DumpAddress(
interpreter.GetExecutionContext().GetBestExecutionContextScope(),
- symbol->GetAddressRef(), verbose, all_ranges, strm);
+ symbol->GetAddressRef(), verbose, all_ranges, strm, name);
strm.EOL();
} else {
strm.IndentMore();
strm.Indent(" Name: ");
- strm.PutCString(symbol->GetDisplayName().GetStringRef());
+ // strm.PutCString(symbol->GetDisplayName().GetStringRef());
+ PrintRed(strm, symbol->GetDisplayName().GetStringRef().str().c_str(), name);
strm.EOL();
strm.Indent(" Value: ");
strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetRawValue());
diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp
index 189d50fe962a651c..4a4a9ca01f39e721 100644
--- a/lldb/source/Core/Address.cpp
+++ b/lldb/source/Core/Address.cpp
@@ -802,6 +802,434 @@ bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
return true;
}
+
+//==================================================================================
+static void PrintRed(Stream *strm, const char *text, const char *name) {
+ const char *red_start = "\033[31m"; // Set text color to red
+ const char *reset_color = "\033[0m"; // Reset text color to default
+
+ const char *match = text;
+ size_t name_len = strlen(name);
+
+ while ((match = strstr(match, name))) {
+ size_t prefix_len = match - text;
+
+ strm->Write(text, prefix_len);
+ strm->PutCString(red_start);
+ strm->Write(match, name_len);
+ strm->PutCString(reset_color);
+
+ text = match + name_len;
+ match = text;
+ }
+
+ strm->PutCString(text); // Print any remaining text
+}
+
+
+bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, const char* name,
+ DumpStyle fallback_style, uint32_t addr_size,
+ bool all_ranges) const {
+ // If the section was nullptr, only load address is going to work unless we
+ // are trying to deref a pointer
+ SectionSP section_sp(GetSection());
+ if (!section_sp && style != DumpStyleResolvedPointerDescription)
+ style = DumpStyleLoadAddress;
+
+ ExecutionContext exe_ctx(exe_scope);
+ Target *target = exe_ctx.GetTargetPtr();
+ // If addr_byte_size is UINT32_MAX, then determine the correct address byte
+ // size for the process or default to the size of addr_t
+ if (addr_size == UINT32_MAX) {
+ if (target)
+ addr_size = target->GetArchitecture().GetAddressByteSize();
+ else
+ addr_size = sizeof(addr_t);
+ }
+
+ Address so_addr;
+ switch (style) {
+ case DumpStyleInvalid:
+ return false;
+
+ case DumpStyleSectionNameOffset:
+ if (section_sp) {
+ section_sp->DumpName(s->AsRawOstream());
+ s->Printf(" + %" PRIu64, m_offset);
+ } else {
+ DumpAddress(s->AsRawOstream(), m_offset, addr_size);
+ }
+ break;
+
+ case DumpStyleSectionPointerOffset:
+ s->Printf("(Section *)%p + ", static_cast<void *>(section_sp.get()));
+ DumpAddress(s->AsRawOstream(), m_offset, addr_size);
+ break;
+
+ case DumpStyleModuleWithFileAddress:
+ if (section_sp) {
+ ModuleSP module_sp = section_sp->GetModule();
+ if (module_sp)
+ s->Printf("%s[", module_sp->GetFileSpec().GetFilename().AsCString(
+ "<Unknown>"));
+ else
+ s->Printf("%s[", "<Unknown>");
+ }
+ [[fallthrough]];
+ case DumpStyleFileAddress: {
+ addr_t file_addr = GetFileAddress();
+ if (file_addr == LLDB_INVALID_ADDRESS) {
+ if (fallback_style != DumpStyleInvalid)
+ return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
+ return false;
+ }
+ DumpAddress(s->AsRawOstream(), file_addr, addr_size);
+ if (style == DumpStyleModuleWithFileAddress && section_sp)
+ s->PutChar(']');
+ } break;
+
+ case DumpStyleLoadAddress: {
+ addr_t load_addr = GetLoadAddress(target);
+
+ /*
+ * MIPS:
+ * Display address in compressed form for MIPS16 or microMIPS
+ * if the address belongs to AddressClass::eCodeAlternateISA.
+ */
+ if (target) {
+ const llvm::Triple::ArchType llvm_arch =
+ target->GetArchitecture().GetMachine();
+ if (llvm_arch == llvm::Triple::mips ||
+ llvm_arch == llvm::Triple::mipsel ||
+ llvm_arch == llvm::Triple::mips64 ||
+ llvm_arch == llvm::Triple::mips64el)
+ load_addr = GetCallableLoadAddress(target);
+ }
+
+ if (load_addr == LLDB_INVALID_ADDRESS) {
+ if (fallback_style != DumpStyleInvalid)
+ return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
+ return false;
+ }
+ DumpAddress(s->AsRawOstream(), load_addr, addr_size);
+ } break;
+
+ case DumpStyleResolvedDescription:
+ case DumpStyleResolvedDescriptionNoModule:
+ case DumpStyleResolvedDescriptionNoFunctionArguments:
+ case DumpStyleNoFunctionName:
+ if (IsSectionOffset()) {
+ uint32_t pointer_size = 4;
+ ModuleSP module_sp(GetModule());
+ if (target)
+ pointer_size = target->GetArchitecture().GetAddressByteSize();
+ else if (module_sp)
+ pointer_size = module_sp->GetArchitecture().GetAddressByteSize();
+
+ bool showed_info = false;
+ if (section_sp) {
+ SectionType sect_type = section_sp->GetType();
+ switch (sect_type) {
+ case eSectionTypeData:
+ if (module_sp) {
+ if (Symtab *symtab = module_sp->GetSymtab()) {
+ const addr_t file_Addr = GetFileAddress();
+ Symbol *symbol =
+ symtab->FindSymbolContainingFileAddress(file_Addr);
+ if (symbol) {
+ const char *symbol_name = symbol->GetName().AsCString();
+ if (symbol_name) {
+ // s->printf(symbol_name)
+ PrintRed(s, symbol_name, name);
+ addr_t delta =
+ file_Addr - symbol->GetAddressRef().GetFileAddress();
+ if (delta)
+ s->Printf(" + %" PRIu64, delta);
+ showed_info = true;
+ }
+ }
+ }
+ }
+ break;
+
+ case eSectionTypeDataCString:
+ // Read the C string from memory and display it
+ showed_info = true;
+ ReadCStringFromMemory(exe_scope, *this, s);
+ break;
+
+ case eSectionTypeDataCStringPointers:
+ if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
+#if VERBOSE_OUTPUT
+ s->PutCString("(char *)");
+ so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
+ DumpStyleFileAddress);
+ s->PutCString(": ");
+#endif
+ showed_info = true;
+ ReadCStringFromMemory(exe_scope, so_addr, s);
+ }
+ break;
+
+ case eSectionTypeDataObjCMessageRefs:
+ if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
+ if (target && so_addr.IsSectionOffset()) {
+ SymbolContext func_sc;
+ target->GetImages().ResolveSymbolContextForAddress(
+ so_addr, eSymbolContextEverything, func_sc);
+ if (func_sc.function != nullptr || func_sc.symbol != nullptr) {
+ showed_info = true;
+#if VERBOSE_OUTPUT
+ s->PutCString("(objc_msgref *) -> { (func*)");
+ so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
+ DumpStyleFileAddress);
+#else
+ s->PutCString("{ ");
+#endif
+ Address cstr_addr(*this);
+ cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
+ func_sc.DumpStopContext(s, exe_scope, so_addr, true, true,
+ false, true, true);
+ if (ReadAddress(exe_scope, cstr_addr, pointer_size, so_addr)) {
+#if VERBOSE_OUTPUT
+ s->PutCString("), (char *)");
+ so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
+ DumpStyleFileAddress);
+ s->PutCString(" (");
+#else
+ s->PutCString(", ");
+#endif
+ ReadCStringFromMemory(exe_scope, so_addr, s);
+ }
+#if VERBOSE_OUTPUT
+ s->PutCString(") }");
+#else
+ s->PutCString(" }");
+#endif
+ }
+ }
+ }
+ break;
+
+ case eSectionTypeDataObjCCFStrings: {
+ Address cfstring_data_addr(*this);
+ cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() +
+ (2 * pointer_size));
+ if (ReadAddress(exe_scope, cfstring_data_addr, pointer_size,
+ so_addr)) {
+#if VERBOSE_OUTPUT
+ s->PutCString("(CFString *) ");
+ cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
+ DumpStyleFileAddress);
+ s->PutCString(" -> @");
+#else
+ s->PutChar('@');
+#endif
+ if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription))
+ showed_info = true;
+ }
+ } break;
+
+ case eSectionTypeData4:
+ // Read the 4 byte data and display it
+ showed_info = true;
+ s->PutCString("(uint32_t) ");
+ DumpUInt(exe_scope, *this, 4, s);
+ break;
+
+ case eSectionTypeData8:
+ // Read the 8 byte data and display it
+ showed_info = true;
+ s->PutCString("(uint64_t) ");
+ DumpUInt(exe_scope, *this, 8, s);
+ break;
+
+ case eSectionTypeData16:
+ // Read the 16 byte data and display it
+ showed_info = true;
+ s->PutCString("(uint128_t) ");
+ DumpUInt(exe_scope, *this, 16, s);
+ break;
+
+ case eSectionTypeDataPointers:
+ // Read the pointer data and display it
+ if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
+ s->PutCString("(void *)");
+ so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
+ DumpStyleFileAddress);
+
+ showed_info = true;
+ if (so_addr.IsSectionOffset()) {
+ SymbolContext pointer_sc;
+ if (target) {
+ target->GetImages().ResolveSymbolContextForAddress(
+ so_addr, eSymbolContextEverything, pointer_sc);
+ if (pointer_sc.function != nullptr ||
+ pointer_sc.symbol != nullptr) {
+ s->PutCString(": ");
+ pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false,
+ false, true, true, name);
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (!showed_info) {
+ if (module_sp) {
+ SymbolContext sc;
+ module_sp->ResolveSymbolContextForAddress(
+ *this, eSymbolContextEverything, sc);
+ if (sc.function || sc.symbol) {
+ bool show_stop_context = true;
+ const bool show_module = (style == DumpStyleResolvedDescription);
+ const bool show_fullpaths = false;
+ const bool show_inlined_frames = true;
+ const bool show_function_arguments =
+ (style != DumpStyleResolvedDescriptionNoFunctionArguments);
+ const bool show_function_name = (style != DumpStyleNoFunctionName);
+ if (sc.function == nullptr && sc.symbol != nullptr) {
+ // If we have just a symbol make sure it is in the right section
+ if (sc.symbol->ValueIsAddress()) {
+ if (sc.symbol->GetAddressRef().GetSection() != GetSection()) {
+ // don't show the module if the symbol is a trampoline symbol
+ show_stop_context = false;
+ }
+ }
+ }
+ if (show_stop_context) {
+ // We have a function or a symbol from the same sections as this
+ // address.
+ sc.DumpStopContext(s, exe_scope, *this, show_fullpaths,
+ show_module, show_inlined_frames,
+ show_function_arguments, show_function_name, name);
+ } else {
+ // We found a symbol but it was in a different section so it
+ // isn't the symbol we should be showing, just show the section
+ // name + offset
+ Dump(s, exe_scope, DumpStyleSectionNameOffset, name);
+ }
+ }
+ }
+ }
+ } else {
+ if (fallback_style != DumpStyleInvalid)
+ return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size, name);
+ return false;
+ }
+ break;
+
+ case DumpStyleDetailedSymbolContext:
+ if (IsSectionOffset()) {
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ SymbolContext sc;
+ module_sp->ResolveSymbolContextForAddress(
+ *this, eSymbolContextEverything | eSymbolContextVariable, sc);
+ if (sc.symbol) {
+ // If we have just a symbol make sure it is in the same section as
+ // our address. If it isn't, then we might have just found the last
+ // symbol that came before the address that we are looking up that
+ // has nothing to do with our address lookup.
+ if (sc.symbol->ValueIsAddress() &&
+ sc.symbol->GetAddressRef().GetSection() != GetSection())
+ sc.symbol = nullptr;
+ }
+ sc.GetDescription(s, eDescriptionLevelBrief, target, name);
+
+ if (sc.block) {
+ bool can_create = true;
+ bool get_parent_variables = true;
+ bool stop_if_block_is_inlined_function = false;
+ VariableList variable_list;
+ addr_t file_addr = GetFileAddress();
+ sc.block->AppendVariables(
+ can_create, get_parent_variables,
+ stop_if_block_is_inlined_function,
+ [&](Variable *var) {
+ return var && var->LocationIsValidForAddress(*this);
+ },
+ &variable_list);
+ ABISP abi =
+ ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture());
+ for (const VariableSP &var_sp : variable_list) {
+ s->Indent();
+ s->Printf(" Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\"",
+ var_sp->GetID(), var_sp->GetName().GetCString());
+ Type *type = var_sp->GetType();
+ if (type)
+ s->Printf(", type = \"%s\"", type->GetName().GetCString());
+ else
+ s->PutCString(", type = <unknown>");
+ s->PutCString(", valid ranges = ");
+ if (var_sp->GetScopeRange().IsEmpty())
+ s->PutCString("<block>");
+ else if (all_ranges) {
+ for (auto range : var_sp->GetScopeRange())
+ DumpAddressRange(s->AsRawOstream(), range.GetRangeBase(),
+ range.GetRangeEnd(), addr_size);
+ } else if (auto *range =
+ var_sp->GetScopeRange().FindEntryThatContains(
+ file_addr))
+ DumpAddressRange(s->AsRawOstream(), range->GetRangeBase(),
+ range->GetRangeEnd(), addr_size);
+ s->PutCString(", location = ");
+ var_sp->DumpLocations(s, all_ranges ? LLDB_INVALID_ADDRESS : *this);
+ s->PutCString(", decl = ");
+ var_sp->GetDeclaration().DumpStopContext(s, false);
+ s->EOL();
+ }
+ }
+ }
+ } else {
+ if (fallback_style != DumpStyleInvalid)
+ return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size, name);
+ return false;
+ }
+ break;
+
+ case DumpStyleResolvedPointerDescription: {
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process) {
+ addr_t load_addr = GetLoadAddress(target);
+ if (load_addr != LLDB_INVALID_ADDRESS) {
+ Status memory_error;
+ addr_t dereferenced_load_addr =
+ process->ReadPointerFromMemory(load_addr, memory_error);
+ if (dereferenced_load_addr != LLDB_INVALID_ADDRESS) {
+ Address dereferenced_addr;
+ if (dereferenced_addr.SetLoadAddress(dereferenced_load_addr,
+ target)) {
+ StreamString strm;
+ if (dereferenced_addr.Dump(&strm, exe_scope,
+ DumpStyleResolvedDescription,
+ DumpStyleInvalid, addr_size)) {
+ DumpAddress(s->AsRawOstream(), dereferenced_load_addr, addr_size,
+ " -> ", " ");
+ s->Write(strm.GetString().data(), strm.GetSize());
+ return true;
+ }
+ }
+ }
+ }
+ }
+ if (fallback_style != DumpStyleInvalid)
+ return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size, name);
+ return false;
+ } break;
+ }
+
+ return true;
+}
+
+
+//==================================================================================
+
bool Address::SectionWasDeleted() const {
if (GetSection())
return false;
diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp
index 26b4c4d62ad9c246..c395cbc3e049d131 100644
--- a/lldb/source/Symbol/Symbol.cpp
+++ b/lldb/source/Symbol/Symbol.cpp
@@ -224,6 +224,74 @@ bool Symbol::IsTrampoline() const { return m_type == eSymbolTypeTrampoline; }
bool Symbol::IsIndirect() const { return m_type == eSymbolTypeResolver; }
+
+//=======================================================================
+static void PrintRed(Stream *strm, const char *text, const char *name) {
+ const char *red_start = "\033[31m"; // Set text color to red
+ const char *reset_color = "\033[0m"; // Reset text color to default
+
+ const char *match = text;
+ size_t name_len = strlen(name);
+
+ while ((match = strstr(match, name))) {
+ size_t prefix_len = match - text;
+
+ strm->Write(text, prefix_len);
+ strm->PutCString(red_start);
+ strm->Write(match, name_len);
+ strm->PutCString(reset_color);
+
+ text = match + name_len;
+ match = text;
+ }
+
+ strm->PutCString(text); // Print any remaining text
+}
+
+void Symbol::GetDescription(Stream *s, lldb::DescriptionLevel level,
+ Target *target, const char* name) const {
+ s->Printf("id = {0x%8.8x}", m_uid);
+
+ if (m_addr_range.GetBaseAddress().GetSection()) {
+ if (ValueIsAddress()) {
+ const lldb::addr_t byte_size = GetByteSize();
+ if (byte_size > 0) {
+ s->PutCString(", range = ");
+ m_addr_range.Dump(s, target, Address::DumpStyleLoadAddress,
+ Address::DumpStyleFileAddress);
+ } else {
+ s->PutCString(", address = ");
+ m_addr_range.GetBaseAddress().Dump(s, target,
+ Address::DumpStyleLoadAddress,
+ Address::DumpStyleFileAddress);
+ }
+ } else
+ s->Printf(", value = 0x%16.16" PRIx64,
+ m_addr_range.GetBaseAddress().GetOffset());
+ } else {
+ if (m_size_is_sibling)
+ s->Printf(", sibling = %5" PRIu64,
+ m_addr_range.GetBaseAddress().GetOffset());
+ else
+ s->Printf(", value = 0x%16.16" PRIx64,
+ m_addr_range.GetBaseAddress().GetOffset());
+ }
+ ConstString demangled = GetMangled().GetDemangledName();
+ if (demangled){
+ // s->Printf(", name=\"%s\"", demangled.AsCString());
+ s->Printf(", name=");
+ PrintRed(s, demangled.AsCString(), name);
+ }
+ if (m_mangled.GetMangledName()){
+ // s->Printf(", mangled=\"%s\"", m_mangled.GetMangledName().AsCString());
+ s->Printf(", mangled=");
+ PrintRed(s, m_mangled.GetMangledName().AsCString(), name);
+ }
+}
+
+//========================================================================
+
+
void Symbol::GetDescription(Stream *s, lldb::DescriptionLevel level,
Target *target) const {
s->Printf("id = {0x%8.8x}", m_uid);
diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp
index 63968ec2d1506705..3a2a25edbdc2d7e2 100644
--- a/lldb/source/Symbol/SymbolContext.cpp
+++ b/lldb/source/Symbol/SymbolContext.cpp
@@ -185,6 +185,254 @@ bool SymbolContext::DumpStopContext(Stream *s, ExecutionContextScope *exe_scope,
return dumped_something;
}
+
+//===========================================================================
+static void PrintRed(Stream *strm, const char *text, const char *name) {
+ const char *red_start = "\033[31m"; // Set text color to red
+ const char *reset_color = "\033[0m"; // Reset text color to default
+
+ const char *match = text;
+ size_t name_len = strlen(name);
+
+ while ((match = strstr(match, name))) {
+ size_t prefix_len = match - text;
+
+ strm->Write(text, prefix_len);
+ strm->PutCString(red_start);
+ strm->Write(match, name_len);
+ strm->PutCString(reset_color);
+
+ text = match + name_len;
+ match = text;
+ }
+
+ strm->PutCString(text); // Print any remaining text
+}
+
+bool SymbolContext::DumpStopContext(Stream *s, ExecutionContextScope *exe_scope,
+ const Address &addr, bool show_fullpaths,
+ bool show_module, bool show_inlined_frames,
+ bool show_function_arguments,
+ bool show_function_name,
+ const char* name) const {
+ bool dumped_something = false;
+ if (show_module && module_sp) {
+ if (show_fullpaths)
+ *s << module_sp->GetFileSpec();
+ else
+ *s << module_sp->GetFileSpec().GetFilename();
+ s->PutChar('`');
+ dumped_something = true;
+ }
+
+ if (function != nullptr) {
+ SymbolContext inline_parent_sc;
+ Address inline_parent_addr;
+ if (!show_function_name) {
+ s->Printf("<");
+ dumped_something = true;
+ } else {
+ ConstString name1;
+ if (!show_function_arguments)
+ name1 = function->GetNameNoArguments();
+ if (!name1)
+ name1 = function->GetName();
+ if (name1){
+ // name.Dump(s);
+ PrintRed(s, name1.GetCString() , name);
+ }
+ }
+
+ if (addr.IsValid()) {
+ const addr_t function_offset =
+ addr.GetOffset() -
+ function->GetAddressRange().GetBaseAddress().GetOffset();
+ if (!show_function_name) {
+ // Print +offset even if offset is 0
+ dumped_something = true;
+ s->Printf("+%" PRIu64 ">", function_offset);
+ } else if (function_offset) {
+ dumped_something = true;
+ s->Printf(" + %" PRIu64, function_offset);
+ }
+ }
+
+ if (GetParentOfInlinedScope(addr, inline_parent_sc, inline_parent_addr)) {
+ dumped_something = true;
+ Block *inlined_block = block->GetContainingInlinedBlock();
+ const InlineFunctionInfo *inlined_block_info =
+ inlined_block->GetInlinedFunctionInfo();
+ s->Printf(" [inlined] %s", inlined_block_info->GetName().GetCString());
+
+ lldb_private::AddressRange block_range;
+ if (inlined_block->GetRangeContainingAddress(addr, block_range)) {
+ const addr_t inlined_function_offset =
+ addr.GetOffset() - block_range.GetBaseAddress().GetOffset();
+ if (inlined_function_offset) {
+ s->Printf(" + %" PRIu64, inlined_function_offset);
+ }
+ }
+ // "line_entry" will always be valid as GetParentOfInlinedScope(...) will
+ // fill it in correctly with the calling file and line. Previous code
+ // was extracting the calling file and line from inlined_block_info and
+ // using it right away which is not correct. On the first call to this
+ // function "line_entry" will contain the actual line table entry. On
+ // susequent calls "line_entry" will contain the calling file and line
+ // from the previous inline info.
+ if (line_entry.IsValid()) {
+ s->PutCString(" at ");
+ line_entry.DumpStopContext(s, show_fullpaths);
+ }
+
+ if (show_inlined_frames) {
+ s->EOL();
+ s->Indent();
+ const bool show_function_name = true;
+ return inline_parent_sc.DumpStopContext(
+ s, exe_scope, inline_parent_addr, show_fullpaths, show_module,
+ show_inlined_frames, show_function_arguments, show_function_name);
+ }
+ } else {
+ if (line_entry.IsValid()) {
+ dumped_something = true;
+ s->PutCString(" at ");
+ if (line_entry.DumpStopContext(s, show_fullpaths))
+ dumped_something = true;
+ }
+ }
+ } else if (symbol != nullptr) {
+ if (!show_function_name) {
+ s->Printf("<");
+ dumped_something = true;
+ } else if (symbol->GetName()) {
+ dumped_something = true;
+ if (symbol->GetType() == eSymbolTypeTrampoline)
+ s->PutCString("symbol stub for: ");
+ // symbol->GetName().Dump(s);
+ PrintRed(s, symbol->GetName().GetStringRef().str().c_str(), name);
+ }
+
+ if (addr.IsValid() && symbol->ValueIsAddress()) {
+ const addr_t symbol_offset =
+ addr.GetOffset() - symbol->GetAddressRef().GetOffset();
+ if (!show_function_name) {
+ // Print +offset even if offset is 0
+ dumped_something = true;
+ s->Printf("+%" PRIu64 ">", symbol_offset);
+ } else if (symbol_offset) {
+ dumped_something = true;
+ s->Printf(" + %" PRIu64, symbol_offset);
+ }
+ }
+ } else if (addr.IsValid()) {
+ addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress);
+ dumped_something = true;
+ }
+ return dumped_something;
+}
+
+
+void SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level,
+ Target *target, const char* name) const {
+ if (module_sp) {
+ s->Indent(" Module: file = \"");
+ module_sp->GetFileSpec().Dump(s->AsRawOstream());
+ *s << '"';
+ if (module_sp->GetArchitecture().IsValid())
+ s->Printf(", arch = \"%s\"",
+ module_sp->GetArchitecture().GetArchitectureName());
+ s->EOL();
+ }
+
+ if (comp_unit != nullptr) {
+ s->Indent("CompileUnit: ");
+ comp_unit->GetDescription(s, level);
+ s->EOL();
+ }
+
+ if (function != nullptr) {
+ s->Indent(" Function: ");
+ function->GetDescription(s, level, target);
+ s->EOL();
+
+ Type *func_type = function->GetType();
+ if (func_type) {
+ s->Indent(" FuncType: ");
+ func_type->GetDescription(s, level, false, target);
+ s->EOL();
+ }
+ }
+
+ if (block != nullptr) {
+ std::vector<Block *> blocks;
+ blocks.push_back(block);
+ Block *parent_block = block->GetParent();
+
+ while (parent_block) {
+ blocks.push_back(parent_block);
+ parent_block = parent_block->GetParent();
+ }
+ std::vector<Block *>::reverse_iterator pos;
+ std::vector<Block *>::reverse_iterator begin = blocks.rbegin();
+ std::vector<Block *>::reverse_iterator end = blocks.rend();
+ for (pos = begin; pos != end; ++pos) {
+ if (pos == begin)
+ s->Indent(" Blocks: ");
+ else
+ s->Indent(" ");
+ (*pos)->GetDescription(s, function, level, target);
+ s->EOL();
+ }
+ }
+
+ if (line_entry.IsValid()) {
+ s->Indent(" LineEntry: ");
+ line_entry.GetDescription(s, level, comp_unit, target, false);
+ s->EOL();
+ }
+
+ if (symbol != nullptr) {
+ s->Indent(" Symbol: ");
+ symbol->GetDescription(s, level, target, name);
+ s->EOL();
+ }
+
+ if (variable != nullptr) {
+ s->Indent(" Variable: ");
+
+ s->Printf("id = {0x%8.8" PRIx64 "}, ", variable->GetID());
+
+ switch (variable->GetScope()) {
+ case eValueTypeVariableGlobal:
+ s->PutCString("kind = global, ");
+ break;
+
+ case eValueTypeVariableStatic:
+ s->PutCString("kind = static, ");
+ break;
+
+ case eValueTypeVariableArgument:
+ s->PutCString("kind = argument, ");
+ break;
+
+ case eValueTypeVariableLocal:
+ s->PutCString("kind = local, ");
+ break;
+
+ case eValueTypeVariableThreadLocal:
+ s->PutCString("kind = thread local, ");
+ break;
+
+ default:
+ break;
+ }
+
+ s->Printf("name = \"%s\"\n", variable->GetName().GetCString());
+ }
+}
+
+//===========================================================================
+
void SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level,
Target *target) const {
if (module_sp) {
>From 14cf74105a358a028cd7e935b4304e16d6f901f2 Mon Sep 17 00:00:00 2001
From: taalhaataahir0102 <23100293 at lums.edu.pk>
Date: Mon, 16 Oct 2023 16:15:30 +0500
Subject: [PATCH 2/3] Comments
---
lldb/source/Commands/CommandObjectTarget.cpp | 53 ++++----------------
lldb/source/Core/Address.cpp | 7 +++
lldb/source/Symbol/Symbol.cpp | 3 ++
lldb/source/Symbol/SymbolContext.cpp | 1 +
4 files changed, 21 insertions(+), 43 deletions(-)
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index aa59e3680a37872c..2b6439ab7b10758b 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -1514,6 +1514,9 @@ static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
}
//===========================================================================================
+
+// This function will print search the string name in string text and will colorize
+// the name found inside text on the terminal.
static void PrintRed(Stream &strm, const char *text, const char *name) {
const char *red_start = "\033[31m"; // Set text color to red
const char *reset_color = "\033[0m"; // Reset text color to default
@@ -1538,49 +1541,9 @@ static void PrintRed(Stream &strm, const char *text, const char *name) {
strm.PutCString(text); // Print any remaining text
}
-
-// static void PrintRed(Stream &strm, const char *text, const char *name) {
-// const char *red_start = "\033[31m"; // Set text color to red
-// const char *reset_color = "\033[0m"; // Reset text color to default
-
-// const char *match = text;
-
-// // Split the name into parts using the delimiter '|'
-// std::vector<std::string> name_parts;
-// const char *delimiter = "|"; // Delimiter for splitting the name
-// const char *token = strtok(const_cast<char *>(name), delimiter);
-// while (token) {
-// name_parts.push_back(token);
-// token = strtok(nullptr, delimiter);
-// }
-
-// // Initialize a variable to keep track of the current position in the text
-// size_t current_pos = 0;
-
-// // Iterate through each name part and apply colorization
-// for (const std::string &part : name_parts) {
-// match = text + current_pos;
-// match = strstr(match, part.c_str());
-
-// if (match) {
-// size_t prefix_len = match - (text + current_pos);
-// current_pos += prefix_len;
-
-// strm.Write(text + current_pos, prefix_len);
-// strm.PutCString(red_start);
-// strm.Write(match, part.length());
-// strm.PutCString(reset_color);
-
-// current_pos += part.length();
-// }
-// }
-
-// // Print any remaining text
-// if (current_pos < strlen(text)) {
-// strm.PutCString(text + current_pos);
-// }
-// }
-
+// This function is responsible for printing address and summary of the symbol found.
+// The seached regex symbol is passed to this function as well so that it can be colorized
+// in the summary as well.
static void DumpAddress(ExecutionContextScope *exe_scope,
const Address &so_addr, bool verbose, bool all_ranges,
Stream &strm, const char *name) {
@@ -1593,6 +1556,8 @@ static void DumpAddress(ExecutionContextScope *exe_scope,
strm.Indent(" Summary: ");
const uint32_t save_indent = strm.GetIndentLevel();
strm.SetIndentLevel(save_indent + 13);
+ // Using the new dump function for printing the summary where we've also passed
+ // the searched symbol as an argument.
so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription, name);
strm.SetIndentLevel(save_indent);
// Print out detailed address information when verbose is enabled
@@ -1640,6 +1605,7 @@ static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
if (symbol) {
if (symbol->ValueIsAddress()) {
+ // Using the new dump function to add colors in the summary.
DumpAddress(
interpreter.GetExecutionContext().GetBestExecutionContextScope(),
symbol->GetAddressRef(), verbose, all_ranges, strm, name);
@@ -1648,6 +1614,7 @@ static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
strm.IndentMore();
strm.Indent(" Name: ");
// strm.PutCString(symbol->GetDisplayName().GetStringRef());
+ // Using the PrintRed function to colorize the searched symbol.
PrintRed(strm, symbol->GetDisplayName().GetStringRef().str().c_str(), name);
strm.EOL();
strm.Indent(" Value: ");
diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp
index 4a4a9ca01f39e721..3da35a3be311051c 100644
--- a/lldb/source/Core/Address.cpp
+++ b/lldb/source/Core/Address.cpp
@@ -804,6 +804,10 @@ bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
//==================================================================================
+
+// This function will print search the string name in string text and will colorize
+// the name found inside text on the terminal.
+
static void PrintRed(Stream *strm, const char *text, const char *name) {
const char *red_start = "\033[31m"; // Set text color to red
const char *reset_color = "\033[0m"; // Reset text color to default
@@ -826,6 +830,8 @@ static void PrintRed(Stream *strm, const char *text, const char *name) {
strm->PutCString(text); // Print any remaining text
}
+// Similar to the DumpAddress function inside CommandObjectTarget.cpp, we've reinitialized this Dump function
+// by passing the searched symbol so that it can be colorized as well in the output stream.
bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, const char* name,
DumpStyle fallback_style, uint32_t addr_size,
@@ -940,6 +946,7 @@ bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
const char *symbol_name = symbol->GetName().AsCString();
if (symbol_name) {
// s->printf(symbol_name)
+ // Using the PrintRed function to colorize the symbol.
PrintRed(s, symbol_name, name);
addr_t delta =
file_Addr - symbol->GetAddressRef().GetFileAddress();
diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp
index c395cbc3e049d131..ac99c63cc4d46ba0 100644
--- a/lldb/source/Symbol/Symbol.cpp
+++ b/lldb/source/Symbol/Symbol.cpp
@@ -248,6 +248,9 @@ static void PrintRed(Stream *strm, const char *text, const char *name) {
strm->PutCString(text); // Print any remaining text
}
+
+// This function is used to display the details of searched symbol i.e., when verbose flag is used.
+// Adding colorization in this dump function as well usin the PrintRed function.
void Symbol::GetDescription(Stream *s, lldb::DescriptionLevel level,
Target *target, const char* name) const {
s->Printf("id = {0x%8.8x}", m_uid);
diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp
index 3a2a25edbdc2d7e2..7c1db5cef75c4d2b 100644
--- a/lldb/source/Symbol/SymbolContext.cpp
+++ b/lldb/source/Symbol/SymbolContext.cpp
@@ -187,6 +187,7 @@ bool SymbolContext::DumpStopContext(Stream *s, ExecutionContextScope *exe_scope,
//===========================================================================
+// Similar to the previous modules, using PrintRed and new dump function.
static void PrintRed(Stream *strm, const char *text, const char *name) {
const char *red_start = "\033[31m"; // Set text color to red
const char *reset_color = "\033[0m"; // Reset text color to default
>From c387dae46deac35f9a28b90e1a1831c02681b021 Mon Sep 17 00:00:00 2001
From: taalhaataahir0102 <23100293 at lums.edu.pk>
Date: Mon, 16 Oct 2023 17:39:05 +0500
Subject: [PATCH 3/3] new PrintRed with | support
---
lldb/source/Commands/CommandObjectTarget.cpp | 80 ++++++++++++++++----
lldb/source/Core/Address.cpp | 77 +++++++++++++++----
lldb/source/Symbol/SymbolContext.cpp | 72 ++++++++++++++----
3 files changed, 188 insertions(+), 41 deletions(-)
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index 2b6439ab7b10758b..88905b39dec9f5d9 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -1515,32 +1515,84 @@ static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
//===========================================================================================
+#include <iostream>
+#include <sstream>
+#include <vector>
+
+// Function to split the string on "|"
+std::vector<std::string> splitString(const std::string &s, char delimiter) {
+ std::vector<std::string> tokens;
+ std::stringstream ss(s);
+ std::string item;
+
+ while (std::getline(ss, item, delimiter)) {
+ tokens.push_back(item);
+ }
+
+ return tokens;
+}
+
// This function will print search the string name in string text and will colorize
// the name found inside text on the terminal.
static void PrintRed(Stream &strm, const char *text, const char *name) {
const char *red_start = "\033[31m"; // Set text color to red
const char *reset_color = "\033[0m"; // Reset text color to default
- // Escape1(ansi.red)
+ std::vector<std::string> parts = splitString(name, '|');
- const char *match = text;
- size_t name_len = strlen(name);
-
- while ((match = strstr(match, name))) {
- size_t prefix_len = match - text;
+ size_t text_len = strlen(text);
+ size_t current_pos = 0;
- strm.Write(text, prefix_len);
- strm.PutCString(red_start);
- strm.Write(match, name_len);
- strm.PutCString(reset_color);
-
- text = match + name_len;
- match = text;
+ for (const auto &part : parts) {
+ const char *match = text;
+ size_t name_len = part.size();
+
+ while ((match = strstr(match, part.c_str()))) {
+ size_t prefix_len = match - text + current_pos;
+
+ strm.Write(text + current_pos, prefix_len);
+ strm.PutCString(red_start);
+ strm.Write(match, name_len);
+ strm.PutCString(reset_color);
+
+ // Update the current position and the match pointer
+ current_pos = (match - text) + name_len;
+ match += name_len;
+ }
}
- strm.PutCString(text); // Print any remaining text
+ // Print any remaining text
+ strm.PutCString(text + current_pos);
}
+
+
+// This function will print search the string name in string text and will colorize
+// the name found inside text on the terminal.
+// static void PrintRed(Stream &strm, const char *text, const char *name) {
+// const char *red_start = "\033[31m"; // Set text color to red
+// const char *reset_color = "\033[0m"; // Reset text color to default
+
+// // Escape1(ansi.red)
+
+// const char *match = text;
+// size_t name_len = strlen(name);
+
+// while ((match = strstr(match, name))) {
+// size_t prefix_len = match - text;
+
+// strm.Write(text, prefix_len);
+// strm.PutCString(red_start);
+// strm.Write(match, name_len);
+// strm.PutCString(reset_color);
+
+// text = match + name_len;
+// match = text;
+// }
+
+// strm.PutCString(text); // Print any remaining text
+// }
+
// This function is responsible for printing address and summary of the symbol found.
// The seached regex symbol is passed to this function as well so that it can be colorized
// in the summary as well.
diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp
index 3da35a3be311051c..611086556c709890 100644
--- a/lldb/source/Core/Address.cpp
+++ b/lldb/source/Core/Address.cpp
@@ -805,31 +805,80 @@ bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
//==================================================================================
+#include <iostream>
+#include <sstream>
+#include <vector>
+
+// Function to split the string on "|"
+static std::vector<std::string> splitString(const std::string &s, char delimiter) {
+ std::vector<std::string> tokens;
+ std::stringstream ss(s);
+ std::string item;
+
+ while (std::getline(ss, item, delimiter)) {
+ tokens.push_back(item);
+ }
+
+ return tokens;
+}
+
// This function will print search the string name in string text and will colorize
// the name found inside text on the terminal.
-
static void PrintRed(Stream *strm, const char *text, const char *name) {
const char *red_start = "\033[31m"; // Set text color to red
const char *reset_color = "\033[0m"; // Reset text color to default
- const char *match = text;
- size_t name_len = strlen(name);
-
- while ((match = strstr(match, name))) {
- size_t prefix_len = match - text;
+ std::vector<std::string> parts = splitString(name, '|');
- strm->Write(text, prefix_len);
- strm->PutCString(red_start);
- strm->Write(match, name_len);
- strm->PutCString(reset_color);
-
- text = match + name_len;
- match = text;
+ size_t text_len = strlen(text);
+ size_t current_pos = 0;
+
+ for (const auto &part : parts) {
+ const char *match = text;
+ size_t name_len = part.size();
+
+ while ((match = strstr(match, part.c_str()))) {
+ size_t prefix_len = match - text + current_pos;
+
+ strm->Write(text + current_pos, prefix_len);
+ strm->PutCString(red_start);
+ strm->Write(match, name_len);
+ strm->PutCString(reset_color);
+
+ // Update the current position and the match pointer
+ current_pos = (match - text) + name_len;
+ match += name_len;
+ }
}
- strm->PutCString(text); // Print any remaining text
+ // Print any remaining text
+ strm->PutCString(text + current_pos);
}
+
+
+// static void PrintRed(Stream *strm, const char *text, const char *name) {
+// const char *red_start = "\033[31m"; // Set text color to red
+// const char *reset_color = "\033[0m"; // Reset text color to default
+
+// const char *match = text;
+// size_t name_len = strlen(name);
+
+// while ((match = strstr(match, name))) {
+// size_t prefix_len = match - text;
+
+// strm->Write(text, prefix_len);
+// strm->PutCString(red_start);
+// strm->Write(match, name_len);
+// strm->PutCString(reset_color);
+
+// text = match + name_len;
+// match = text;
+// }
+
+// strm->PutCString(text); // Print any remaining text
+// }
+
// Similar to the DumpAddress function inside CommandObjectTarget.cpp, we've reinitialized this Dump function
// by passing the searched symbol so that it can be colorized as well in the output stream.
diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp
index 7c1db5cef75c4d2b..7b9276940be3943c 100644
--- a/lldb/source/Symbol/SymbolContext.cpp
+++ b/lldb/source/Symbol/SymbolContext.cpp
@@ -187,29 +187,75 @@ bool SymbolContext::DumpStopContext(Stream *s, ExecutionContextScope *exe_scope,
//===========================================================================
+
+#include <sstream>
+// Function to split the string on "|"
+static std::vector<std::string> splitString(const std::string &s, char delimiter) {
+ std::vector<std::string> tokens;
+ std::stringstream ss(s);
+ std::string item;
+
+ while (std::getline(ss, item, delimiter)) {
+ tokens.push_back(item);
+ }
+
+ return tokens;
+}
+
// Similar to the previous modules, using PrintRed and new dump function.
static void PrintRed(Stream *strm, const char *text, const char *name) {
const char *red_start = "\033[31m"; // Set text color to red
const char *reset_color = "\033[0m"; // Reset text color to default
- const char *match = text;
- size_t name_len = strlen(name);
-
- while ((match = strstr(match, name))) {
- size_t prefix_len = match - text;
+ std::vector<std::string> parts = splitString(name, '|');
- strm->Write(text, prefix_len);
- strm->PutCString(red_start);
- strm->Write(match, name_len);
- strm->PutCString(reset_color);
-
- text = match + name_len;
- match = text;
+ size_t text_len = strlen(text);
+ size_t current_pos = 0;
+
+ for (const auto &part : parts) {
+ const char *match = text;
+ size_t name_len = part.size();
+
+ while ((match = strstr(match, part.c_str()))) {
+ size_t prefix_len = match - text + current_pos;
+
+ strm->Write(text + current_pos, prefix_len);
+ strm->PutCString(red_start);
+ strm->Write(match, name_len);
+ strm->PutCString(reset_color);
+
+ // Update the current position and the match pointer
+ current_pos = (match - text) + name_len;
+ match += name_len;
+ }
}
- strm->PutCString(text); // Print any remaining text
+ // Print any remaining text
+ strm->PutCString(text + current_pos);
}
+// static void PrintRed(Stream *strm, const char *text, const char *name) {
+// const char *red_start = "\033[31m"; // Set text color to red
+// const char *reset_color = "\033[0m"; // Reset text color to default
+
+// const char *match = text;
+// size_t name_len = strlen(name);
+
+// while ((match = strstr(match, name))) {
+// size_t prefix_len = match - text;
+
+// strm->Write(text, prefix_len);
+// strm->PutCString(red_start);
+// strm->Write(match, name_len);
+// strm->PutCString(reset_color);
+
+// text = match + name_len;
+// match = text;
+// }
+
+// strm->PutCString(text); // Print any remaining text
+// }
+
bool SymbolContext::DumpStopContext(Stream *s, ExecutionContextScope *exe_scope,
const Address &addr, bool show_fullpaths,
bool show_module, bool show_inlined_frames,
More information about the lldb-commits
mailing list