[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