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 e3b3da3bd186a293964e1ddf7851ee0536631cbd
Author: xuxingliang <[email protected]>
AuthorDate: Tue Oct 1 10:30:32 2024 +0800

    tools/gdb: support string type in offset_of
    
    1. Support any type of value as pointer address in container_of
    2. Support string as type in offset_of
    3. Make sure type is a pointer in container_of, and not a pointer in
       offset_of
    
    Signed-off-by: xuxingliang <[email protected]>
---
 tools/gdb/nuttxgdb/utils.py | 47 ++++++++++++++++++++++++++++++++++++---------
 1 file changed, 38 insertions(+), 9 deletions(-)

diff --git a/tools/gdb/nuttxgdb/utils.py b/tools/gdb/nuttxgdb/utils.py
index 8cc68c0808..12016bb9da 100644
--- a/tools/gdb/nuttxgdb/utils.py
+++ b/tools/gdb/nuttxgdb/utils.py
@@ -86,24 +86,53 @@ def get_long_type():
     return long_type
 
 
-def offset_of(typeobj: gdb.Type, field: str) -> Union[int, None]:
+def offset_of(typeobj: Union[gdb.Type, str], field: str) -> Union[int, None]:
     """Return the offset of a field in a structure"""
+    if type(typeobj) is str:
+        typeobj = gdb.lookup_type(typeobj)
+
+    if typeobj.code is gdb.TYPE_CODE_PTR:
+        typeobj = typeobj.target()
+
     for f in typeobj.fields():
         if f.name == field:
-            return f.bitpos // 8 if f.bitpos is not None else None
+            if f.bitpos is None:
+                break
+            return f.bitpos // 8
 
-    return None
+    raise gdb.GdbError(f"Field {field} not found in type {typeobj}")
 
 
 def container_of(
-    ptr: gdb.Value, typeobj: Union[gdb.Type, str], member: str
+    ptr: Union[gdb.Value, int], typeobj: Union[gdb.Type, str], member: str
 ) -> gdb.Value:
-    """Return pointer to containing data structure"""
+    """
+    Return a pointer to the containing data structure.
+
+    Args:
+        ptr: Pointer to the member.
+        t: Type of the container.
+        member: Name of the member in the container.
+
+    Returns:
+        gdb.Value of the container.
+
+    Example:
+        struct foo {
+            int a;
+            int b;
+        };
+        struct foo *ptr = container_of(&ptr->b, "struct foo", "b");
+    """
+
     if isinstance(typeobj, str):
-        typeobj = lookup_type(typeobj)
-    return gdb.Value(int(ptr.dereference().address) - offset_of(typeobj, 
member)).cast(
-        typeobj.pointer()
-    )
+        typeobj = gdb.lookup_type(typeobj).pointer()
+
+    if typeobj.code is not gdb.TYPE_CODE_PTR:
+        typeobj = typeobj.pointer()
+
+    addr = gdb.Value(ptr).cast(long_type)
+    return gdb.Value(addr - offset_of(typeobj, member)).cast(typeobj)
 
 
 class ContainerOf(gdb.Function):

Reply via email to