This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 3a2d4584c7428c4c95c1339a3c0efd7d7a77b713
Author: xuxingliang <[email protected]>
AuthorDate: Fri Nov 8 13:31:20 2024 +0800

    gdb/utils: cache backtrace result for better performance
    
    GDB is slow to look up symbols, cache the result to speed up commands like 
memdump etc.
    
    Signed-off-by: xuxingliang <[email protected]>
---
 tools/gdb/nuttxgdb/utils.py | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/tools/gdb/nuttxgdb/utils.py b/tools/gdb/nuttxgdb/utils.py
index daa40c3e3a..cff55a7300 100644
--- a/tools/gdb/nuttxgdb/utils.py
+++ b/tools/gdb/nuttxgdb/utils.py
@@ -37,6 +37,7 @@ from .macros import fetch_macro_info, try_expand
 g_symbol_cache = {}
 g_type_cache = {}
 g_macro_ctx = None
+g_backtrace_cache = {}
 
 
 class Backtrace:
@@ -70,10 +71,21 @@ class Backtrace:
         self,
         address: List[Union[gdb.Value, int]] = [],
         formatter="{:<5} {:<36} {}\n",
+        break_null=True,
     ):
         self.formatter = formatter  # Address, Function, Source
         self._formatted = None  # Cached formatted backtrace
-        self.backtrace = [res for addr in address if (res := 
self.convert(addr))]
+        self.backtrace = []
+        for addr in address:
+            if break_null and not addr:
+                break
+            self.append(addr)
+
+    def __eq__(self, value: Backtrace) -> bool:
+        return self.backtrace == value.backtrace
+
+    def __hash__(self) -> int:
+        return hash(tuple(self.backtrace))
 
     def append(self, addr: Union[gdb.Value, int]) -> None:
         """Append an address to the backtrace"""
@@ -84,7 +96,10 @@ class Backtrace:
     def convert(self, addr: Union[gdb.Value, int]) -> Tuple[int, str, str]:
         """Convert an address to function and source"""
         if not addr:
-            return
+            return None
+
+        if int(addr) in g_backtrace_cache:
+            return g_backtrace_cache[int(addr)]
 
         if type(addr) is int:
             addr = gdb.Value(addr)
@@ -95,7 +110,9 @@ class Backtrace:
         func = addr.format_string(symbols=True, address=False)
         sym = gdb.find_pc_line(int(addr))
         source = str(sym.symtab) + ":" + str(sym.line)
-        return (int(addr), func, source)
+        result = (int(addr), func, source)
+        g_backtrace_cache[int(addr)] = result
+        return result
 
     @property
     def formatted(self):
@@ -884,7 +901,7 @@ class Addr2Line(gdb.Command):
     def print_backtrace(self, addresses, pid=None):
         if pid:
             gdb.write(f"\nBacktrace of {pid}\n")
-        backtraces = Backtrace(addresses, formatter=self.formatter)
+        backtraces = Backtrace(addresses, formatter=self.formatter, 
break_null=False)
         gdb.write(str(backtraces))
 
     def invoke(self, args, from_tty):

Reply via email to