mirror of
https://github.com/apache/nuttx.git
synced 2026-05-28 03:45:50 +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 import fs as p
|
||||||
from .protocols.thread import Tcb
|
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_FILE = utils.get_symbol_value("CONFIG_PSEUDOFS_FILE")
|
||||||
CONFIG_PSEUDOFS_ATTRIBUTES = utils.get_symbol_value("CONFIG_PSEUDOFS_ATTRIBUTES")
|
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(
|
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK = utils.get_field_nitems(
|
||||||
"struct fdlist", "fl_prefds"
|
"struct fdlist", "fl_prefds"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ g_symbol_cache = {}
|
|||||||
g_type_cache = {}
|
g_type_cache = {}
|
||||||
g_macro_ctx = None
|
g_macro_ctx = None
|
||||||
g_backtrace_cache = {}
|
g_backtrace_cache = {}
|
||||||
|
TypeOrStr = Union[gdb.Type, str]
|
||||||
|
|
||||||
|
|
||||||
class Value(gdb.Value):
|
class Value(gdb.Value):
|
||||||
@@ -240,6 +241,42 @@ def lookup_type(name, block=None) -> gdb.Type:
|
|||||||
return g_type_cache[key]
|
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")
|
long_type = lookup_type("long")
|
||||||
|
|
||||||
# Common Helper Functions
|
# Common Helper Functions
|
||||||
@@ -251,7 +288,7 @@ def get_long_type():
|
|||||||
return 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"""
|
"""Return the offset of a field in a structure"""
|
||||||
if type(typeobj) is str:
|
if type(typeobj) is str:
|
||||||
typeobj = gdb.lookup_type(typeobj)
|
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(
|
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:
|
) -> gdb.Value:
|
||||||
"""
|
"""
|
||||||
Return a pointer to the containing data structure.
|
Return a pointer to the containing data structure.
|
||||||
@@ -433,26 +470,18 @@ def get_symbol_value(name, locspec="nx_start", cacheable=True):
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def get_field(val, key, default=None):
|
def get_field(obj: gdb.Value, field: Union[str, gdb.Field], default=None) -> gdb.Value:
|
||||||
"""Get a field from a gdb.Value, return default if key not found"""
|
"""
|
||||||
|
Get a field value from a gdb.Value, return default if field is not found.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
return val[key] if val else default
|
return obj[field] if obj else default
|
||||||
except gdb.error:
|
except gdb.error:
|
||||||
return default
|
return default
|
||||||
|
|
||||||
|
|
||||||
def has_field(obj: Union[gdb.Type, gdb.Value], key):
|
def has_field(obj: Union[TypeOrStr, gdb.Value], field):
|
||||||
if isinstance(obj, gdb.Type):
|
return get_type_field(obj, field) is not None
|
||||||
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 get_bytes(val, size):
|
def get_bytes(val, size):
|
||||||
@@ -522,7 +551,7 @@ def alias(name, command):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def nitems(array):
|
def nitems(array: Union[gdb.Field, gdb.Type]) -> int:
|
||||||
array_type = array.type
|
array_type = array.type
|
||||||
element_type = array_type.target()
|
element_type = array_type.target()
|
||||||
element_size = element_type.sizeof
|
element_size = element_type.sizeof
|
||||||
|
|||||||
Reference in New Issue
Block a user