Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,7 @@ jobs:
# comes with Ubuntu is 0.75 which has a couple of bugs triggered
# by our codebase (they've been resolved on trunk though so we
# may want to change this soon).
# [2] We supply --allow-untyped-calls because even though drgn has
# stubs on typeshed now, there are still some untyped functions
# (mainly in the helper API).
# [3] We supply --ignore-missing-imports to the tests package because
# [2] We supply --ignore-missing-imports to the tests package because
# pytest doesn't provide stubs on typeshed.
#
mypy:
Expand All @@ -109,7 +106,7 @@ jobs:
python-version: '3.6'
- run: ./.github/scripts/install-drgn.sh
- run: python3 -m pip install mypy==0.730
- run: python3 -m mypy --strict --allow-untyped-calls --show-error-codes -p sdb
- run: python3 -m mypy --strict --show-error-codes -p sdb
- run: python3 -m mypy --strict --ignore-missing-imports --show-error-codes -p tests
#
# Verify that "shfmt" ran successfully against our shell scripts.
Expand Down
6 changes: 3 additions & 3 deletions sdb/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -643,13 +643,13 @@ def _call(self, objs: Iterable[drgn.Object]) -> Iterable[drgn.Object]:
the types as we go.
"""
assert self.input_type is not None
type_ = target.get_type(self.input_type)
expected_type = type_canonicalize_name(self.input_type)
for obj in objs:
if obj.type_ != type_:
if type_canonical_name(obj.type_) != expected_type:
raise CommandError(
self.name,
'expected input of type {}, but received {}'.format(
type_, obj.type_))
expected_type, type_canonical_name(obj.type_)))

yield from self.walk(obj)

Expand Down
44 changes: 40 additions & 4 deletions sdb/commands/internal/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,46 @@ def get_valid_type_by_name(cmd: sdb.Command, tname: str) -> drgn.Type:
"""
Given a type name in string form (`tname`) without any C keyword
prefixes (e.g. 'struct', 'enum', 'class', 'union'), return the
corresponding drgn.Type object.
corresponding drgn.Type object. If `tname` starts with a C keyword
we just return the type as is.

This function is used primarily by commands that accept a type
name as an argument and exist only to save keystrokes for the
user.
"""
if tname in ['struct', 'enum', 'union', 'class']:
TYPE_KEYWORDS = ['struct', 'enum', 'union', 'class']

tokens = tname.split()
if len(tokens) > 2:
#
# drgn fails in all kinds of ways when we pass it an
# invalid type that consists of more than 2 text tokens.
#
raise sdb.CommandError(cmd.name,
f"input '{tname}' is not a valid type name")

if len(tokens) == 2:
if tokens[0] not in TYPE_KEYWORDS or tokens[1] in TYPE_KEYWORDS:
#
# For the same reason mentioned in the above comment
# we also ensure that someone may not invalid two-token
# input that has the following errors:
# 1] Doesn't start with a type keyword - e.g "bogus type"
# 2] Has a type keyword as its type name (also see
# comment below) - e.g. struct struct
#
raise sdb.CommandError(cmd.name,
f"input '{tname}' is not a valid type name")
try:
return sdb.get_type(tname)
except LookupError as err:
raise sdb.CommandError(cmd.name,
f"couldn't find type '{tname}'") from err
except SyntaxError as err:
raise sdb.CommandError(
cmd.name, f"input '{tname}' is not a valid type name") from err

if tname in TYPE_KEYWORDS:
#
# Note: We have to do this because currently in drgn
# prog.type('struct') returns a different error than
Expand Down Expand Up @@ -82,9 +115,12 @@ def get_valid_type_by_name(cmd: sdb.Command, tname: str) -> drgn.Type:
# it is a structure, an enum, or a union.
#
pass
for prefix in ["struct ", "enum ", "union "]:
except SyntaxError as err:
raise sdb.CommandError(
cmd.name, f"input '{tname}' is not a valid type name") from err
for prefix in TYPE_KEYWORDS:
try:
return sdb.get_type(f"{prefix}{tname}")
return sdb.get_type(f"{prefix} {tname}")
except LookupError:
pass
raise sdb.CommandError(
Expand Down
9 changes: 4 additions & 5 deletions sdb/commands/ptype.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,15 @@ class PType(sdb.Command):

Print enums and unions:

sdb> ptype zfs_case v_t thread_union
sdb> ptype zfs_case 'struct v' thread_union
enum zfs_case {
ZFS_CASE_SENSITIVE = 0,
ZFS_CASE_INSENSITIVE = 1,
ZFS_CASE_MIXED = 2,
}
typedef union {
iv_t e;
uint8_t b[8];
} v_t
struct v {
uint8_t b[16];
}
union thread_union {
struct task_struct task;
unsigned long stack[2048];
Expand Down
1 change: 1 addition & 0 deletions tests/integration/data/regression_output/core/ptype $abc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sdb: ptype: input '$abc' is not a valid type name
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sdb: ptype: input 'a b c' is not a valid type name
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sdb: ptype: input 'bogus union' is not a valid type name
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sdb: ptype: couldn't find type 'struct bogus'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sdb: ptype: input 'struct union' is not a valid type name
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sdb: ptype: skip keyword 'struct' or quote your type "struct <typename>"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sdb: ptype: input 'union struct struct' is not a valid type name
1 change: 1 addition & 0 deletions tests/integration/data/regression_output/core/ptype 2abc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sdb: ptype: input '2abc' is not a valid type name
1 change: 1 addition & 0 deletions tests/integration/data/regression_output/core/ptype @
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sdb: ptype: input '@' is not a valid type name
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ enum zfs_case {
ZFS_CASE_INSENSITIVE = 1,
ZFS_CASE_MIXED = 2,
}
typedef union {
iv_t e;
uint8_t b[8];
} v_t
struct v {
uint8_t b[16];
}
union thread_union {
struct task_struct task;
unsigned long stack[2048];
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sdb: cpu_counter_sum: invalid memory access: could not read memory from kdump: Cannot get page I/O address: PDPT table not present: pgd[0] = 0x0: 0x8
sdb: cpu_counter_sum: invalid memory access: could not read memory from kdump: Cannot get page I/O address: PDPT table not present: p4d[0] = 0x0: 0x8
12 changes: 11 additions & 1 deletion tests/integration/test_core_generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@
# ptype
"ptype spa_t",
"ptype spa vdev",
"ptype zfs_case v_t thread_union",
"ptype zfs_case 'struct v' thread_union",
"ptype 'struct spa'",

# sizeof
Expand Down Expand Up @@ -181,8 +181,18 @@

# ptype - bogus type
"ptype bogus_t",
"ptype 'struct bogus'",
"ptype 'a b c'",
# ptype - freestanding C keyword
"ptype struct spa",
"ptype 'struct'",
"ptype 'struct union'",
"ptype 'bogus union'",
"ptype 'union struct struct'",
# ptype - invalid characters
"ptype @",
"ptype 2abc",
"ptype $abc",

# pretty printer passed incorrect type
"spa | range_tree",
Expand Down