mirror of
https://github.com/apache/nuttx.git
synced 2026-05-20 20:44:39 +08:00
nxgdb/fs: fix exception when failed to parse symbol
Parse struct fields to determine array length. Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
This commit is contained in:
@@ -30,12 +30,12 @@ from . import utils
|
||||
from .protocols import fs as p
|
||||
from .protocols.thread import Tcb
|
||||
|
||||
FSNODEFLAG_TYPE_MASK = utils.get_symbol_value("FSNODEFLAG_TYPE_MASK")
|
||||
FSNODEFLAG_TYPE_MASK = 0x0000000F
|
||||
|
||||
CONFIG_PSEUDOFS_FILE = utils.get_symbol_value("CONFIG_PSEUDOFS_FILE")
|
||||
CONFIG_PSEUDOFS_ATTRIBUTES = utils.get_symbol_value("CONFIG_PSEUDOFS_ATTRIBUTES")
|
||||
|
||||
CONFIG_FS_BACKTRACE = utils.get_symbol_value("CONFIG_FS_BACKTRACE")
|
||||
CONFIG_FS_BACKTRACE = utils.get_field_nitems("struct fd", "f_backtrace")
|
||||
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK = utils.get_field_nitems(
|
||||
"struct fdlist", "fl_prefds"
|
||||
)
|
||||
|
||||
@@ -41,6 +41,7 @@ g_symbol_cache = {}
|
||||
g_type_cache = {}
|
||||
g_macro_ctx = None
|
||||
g_backtrace_cache = {}
|
||||
TypeOrStr = Union[gdb.Type, str]
|
||||
|
||||
|
||||
class Value(gdb.Value):
|
||||
@@ -240,6 +241,42 @@ def lookup_type(name, block=None) -> gdb.Type:
|
||||
return g_type_cache[key]
|
||||
|
||||
|
||||
def get_fieldnames(t: TypeOrStr) -> List[str]:
|
||||
"""Return the field names of a type"""
|
||||
if isinstance(t, str):
|
||||
t = lookup_type(t)
|
||||
|
||||
return [f.name for f in t.fields()]
|
||||
|
||||
|
||||
def get_type_field(obj: Union[TypeOrStr, gdb.Value], field: str) -> gdb.Field:
|
||||
"""
|
||||
Get the type field descriptor from a type or string, or value object.
|
||||
"""
|
||||
|
||||
if isinstance(obj, str):
|
||||
t = lookup_type(obj)
|
||||
elif isinstance(obj, gdb.Type):
|
||||
t = obj
|
||||
elif isinstance(obj, gdb.Value):
|
||||
t = obj.type
|
||||
else:
|
||||
raise gdb.GdbError(f"Unsupported type {type(obj)}")
|
||||
|
||||
while t.code in (gdb.TYPE_CODE_PTR, gdb.TYPE_CODE_ARRAY, gdb.TYPE_CODE_TYPEDEF):
|
||||
t = t.target()
|
||||
|
||||
for f in t.fields():
|
||||
if f.name == field:
|
||||
return f
|
||||
|
||||
|
||||
def get_field_nitems(t: TypeOrStr, field: str) -> Union[int, None]:
|
||||
"""Return the array length of a field in type, or None if no such field"""
|
||||
if field := get_type_field(t, field):
|
||||
return nitems(field)
|
||||
|
||||
|
||||
long_type = lookup_type("long")
|
||||
|
||||
# Common Helper Functions
|
||||
@@ -251,7 +288,7 @@ def get_long_type():
|
||||
return long_type
|
||||
|
||||
|
||||
def offset_of(typeobj: Union[gdb.Type, str], field: str) -> Union[int, None]:
|
||||
def offset_of(typeobj: TypeOrStr, field: str) -> Union[int, None]:
|
||||
"""Return the offset of a field in a structure"""
|
||||
if type(typeobj) is str:
|
||||
typeobj = gdb.lookup_type(typeobj)
|
||||
@@ -269,7 +306,7 @@ def offset_of(typeobj: Union[gdb.Type, str], field: str) -> Union[int, None]:
|
||||
|
||||
|
||||
def container_of(
|
||||
ptr: Union[gdb.Value, int], typeobj: Union[gdb.Type, str], member: str
|
||||
ptr: Union[gdb.Value, int], typeobj: TypeOrStr, member: str
|
||||
) -> gdb.Value:
|
||||
"""
|
||||
Return a pointer to the containing data structure.
|
||||
@@ -433,26 +470,18 @@ def get_symbol_value(name, locspec="nx_start", cacheable=True):
|
||||
return value
|
||||
|
||||
|
||||
def get_field(val, key, default=None):
|
||||
"""Get a field from a gdb.Value, return default if key not found"""
|
||||
def get_field(obj: gdb.Value, field: Union[str, gdb.Field], default=None) -> gdb.Value:
|
||||
"""
|
||||
Get a field value from a gdb.Value, return default if field is not found.
|
||||
"""
|
||||
try:
|
||||
return val[key] if val else default
|
||||
return obj[field] if obj else default
|
||||
except gdb.error:
|
||||
return default
|
||||
|
||||
|
||||
def has_field(obj: Union[gdb.Type, gdb.Value], key):
|
||||
if isinstance(obj, gdb.Type):
|
||||
t = obj
|
||||
elif isinstance(obj, gdb.Value):
|
||||
t = obj.type
|
||||
else:
|
||||
raise gdb.GdbError(f"Unsupported type {type(obj)}")
|
||||
|
||||
while t.code in (gdb.TYPE_CODE_PTR, gdb.TYPE_CODE_ARRAY, gdb.TYPE_CODE_TYPEDEF):
|
||||
t = t.target()
|
||||
|
||||
return any(f.name == key for f in t.fields())
|
||||
def has_field(obj: Union[TypeOrStr, gdb.Value], field):
|
||||
return get_type_field(obj, field) is not None
|
||||
|
||||
|
||||
def get_bytes(val, size):
|
||||
@@ -522,7 +551,7 @@ def alias(name, command):
|
||||
pass
|
||||
|
||||
|
||||
def nitems(array):
|
||||
def nitems(array: Union[gdb.Field, gdb.Type]) -> int:
|
||||
array_type = array.type
|
||||
element_type = array_type.target()
|
||||
element_size = element_type.sizeof
|
||||
|
||||
Reference in New Issue
Block a user