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 d02dc3893ca51e86325e910c57223b8c532eb031
Author: xuxingliang <[email protected]>
AuthorDate: Mon Sep 30 01:48:15 2024 +0800

    tools/gdb: decode backtrace of crashlog
    
    Now crash log can be directly pass to addr2line tool to get all backtraces.
    
    E.g.
    (gdb) addr2line -f crash.log -p 485
    Address              Symbol                           Source
    
    Backtrace of 485
    0x402cc0ac           <up_switch_context+84>           
/home/work/ssd1/workspace/MiRTOS-X4b-Stable-Build/nuttx/include/arch/syscall.h:179
    0x40291276           <nxsig_timedwait+386>            
signal/sig_timedwait.c:365
    0x4028fc7e           <nxsig_nanosleep+106>            
signal/sig_nanosleep.c:141
    0x4028fdba           <clock_nanosleep+26>             
signal/sig_nanosleep.c:333
    0x402c3736           <usleep+62>                      
unistd/lib_usleep.c:108
    0x415018c0           <cs2p2p_mSecSleep+24>            Src/PPPP_Common.c:1139
    0x414fabde           <cs2p2p_Run_send_DRW+258>        Src/PPPP_API.c:5577
    0x414fac62           <cs2p2p_PPPP_thread_send_DRW+18> Src/PPPP_API.c:5616
    0x40446f62           <pthread_startup+10>             
pthread/pthread_create.c:59
    0x41094f4a           <pthread_start+106>              
pthread/pthread_create.c:139
    
    Signed-off-by: xuxingliang <[email protected]>
---
 tools/gdb/nuttxgdb/utils.py | 85 +++++++++++++++++++++++++++++++++++----------
 1 file changed, 67 insertions(+), 18 deletions(-)

diff --git a/tools/gdb/nuttxgdb/utils.py b/tools/gdb/nuttxgdb/utils.py
index 394a0fa84f..8cc68c0808 100644
--- a/tools/gdb/nuttxgdb/utils.py
+++ b/tools/gdb/nuttxgdb/utils.py
@@ -20,6 +20,7 @@
 #
 ############################################################################
 
+import argparse
 import importlib
 import json
 import os
@@ -42,7 +43,7 @@ def backtrace(addresses: List[Union[gdb.Value, int]]) -> 
List[Tuple[int, str, st
 
     for addr in addresses:
         if not addr:
-            break
+            continue
 
         if type(addr) is int:
             addr = gdb.Value(addr)
@@ -748,34 +749,82 @@ class Addr2Line(gdb.Command):
              addr2line "0x1234 + pointer->abc" &var var->field function_name 
var
              addr2line $pc $r1 "$r2 + var"
              addr2line [24/08/29 20:51:02] [CPU1] [209] [ap] sched_dumpstack: 
backtrace| 0: 0x402cd484 0x4028357e
+             addr2line -f crash.log
+             addr2line -f crash.log -p 123
     """
 
+    formatter = "{:<20} {:<32} {}\n"
+
     def __init__(self):
         super().__init__("addr2line", gdb.COMMAND_USER)
 
+    def print_backtrace(self, addresses, pid=None):
+        if pid:
+            gdb.write(f"\nBacktrace of {pid}\n")
+        backtraces = backtrace(addresses)
+        for addr, func, source in backtraces:
+            gdb.write(self.formatter.format(hex(addr), func, source))
+
     def invoke(self, args, from_tty):
         if not args:
             gdb.write(Addr2Line.__doc__ + "\n")
             return
 
-        addresses = []
-        for arg in shlex.split(args):
-            if is_decimal(arg):
-                addresses.append(int(arg))
-            elif is_hexadecimal(arg):
-                addresses.append(int(arg, 16))
-            else:
-                try:
-                    var = gdb.parse_and_eval(f"{arg}")
-                    addresses.append(var)
-                except gdb.error as e:
-                    gdb.write(f"Ignore {arg}: {e}\n")
+        parser = argparse.ArgumentParser(
+            description="Convert addresses or expressions to source code 
location"
+        )
+        parser.add_argument("-f", "--file", type=str, help="Crash log to 
analyze.")
+        parser.add_argument(
+            "-p",
+            "--pid",
+            type=int,
+            help="Only dump specified task backtrace from crash file.",
+        )
 
-        backtraces = backtrace(addresses)
-        formatter = "{:<20} {:<32} {}\n"
-        gdb.write(formatter.format("Address", "Symbol", "Source"))
-        for addr, func, source in backtraces:
-            gdb.write(formatter.format(hex(addr), func, source))
+        pargs = None
+        try:
+            pargs = parser.parse_args(gdb.string_to_argv(args))
+        except SystemExit:
+            pass
+
+        gdb.write(self.formatter.format("Address", "Symbol", "Source"))
+
+        if pargs and pargs.file:
+            pattern = re.compile(
+                r".*sched_dumpstack: 
backtrace\|\s*(\d+)\s*:\s*((?:(0x)?[0-9a-fA-F]+\s*)+)"
+            )
+            addresses = {}
+            with open(pargs.file, "r") as f:
+                for line in f:
+                    match = pattern.match(line)
+                    if not match:
+                        continue
+
+                    pid = match.group(1)
+                    if pargs.pid is not None and pargs.pid != int(pid):
+                        continue
+
+                    addresses.setdefault(pid, [])
+                    addresses[pid].extend(
+                        [int(addr, 16) for addr in match.group(2).split()]
+                    )
+
+            for pid, addr in addresses.items():
+                self.print_backtrace(addr, pid)
+        else:
+            addresses = []
+            for arg in shlex.split(args):
+                if is_decimal(arg):
+                    addresses.append(int(arg))
+                elif is_hexadecimal(arg):
+                    addresses.append(int(arg, 16))
+                else:
+                    try:
+                        var = gdb.parse_and_eval(f"{arg}")
+                        addresses.append(var)
+                    except gdb.error as e:
+                        gdb.write(f"Ignore {arg}: {e}\n")
+            self.print_backtrace(addresses)
 
 
 class Profile(gdb.Command):

Reply via email to