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
2 changes: 1 addition & 1 deletion .github/scripts/install-libkdumpfile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#
sudo apt update
sudo apt install autoconf automake liblzo2-dev libsnappy1v5 libtool pkg-config zlib1g-dev
sudo apt install python3.6-dev python3.7-dev python3.8-dev
sudo apt install python3.8-dev

git clone https://github.com/ptesarik/libkdumpfile.git

Expand Down
24 changes: 13 additions & 11 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ jobs:
# Verify the build and installation of SDB.
#
install:
runs-on: ubuntu-18.04
runs-on: ubuntu-20.04
strategy:
matrix:
python-version: [3.6, 3.7, 3.8]
python-version: [3.8]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v1
Expand All @@ -31,12 +31,12 @@ jobs:
# the "drgn" from source (there's no package currently available).
#
pylint:
runs-on: ubuntu-18.04
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v1
with:
python-version: '3.6'
python-version: '3.8'
- run: ./.github/scripts/install-drgn.sh
- run: python3 -m pip install pylint pytest
- run: pylint -d duplicate-code -d invalid-name sdb
Expand All @@ -52,10 +52,12 @@ jobs:
# can open kdump-compressed crash dumps for the integration tests.
#
pytest:
runs-on: ubuntu-18.04
runs-on: ubuntu-20.04
strategy:
matrix:
python-version: [3.6, 3.7, 3.8]
python-version: [3.8]
env:
AWS_DEFAULT_REGION: 'us-west-2'
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v1
Expand All @@ -73,12 +75,12 @@ jobs:
# Verify "yapf" runs successfully.
#
yapf:
runs-on: ubuntu-18.04
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v1
with:
python-version: '3.6'
python-version: '3.8'
- run: python3 -m pip install yapf
- run: yapf --diff --style google --recursive sdb
- run: yapf --diff --style google --recursive tests
Expand All @@ -98,12 +100,12 @@ jobs:
# pytest doesn't provide stubs on typeshed.
#
mypy:
runs-on: ubuntu-18.04
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v1
with:
python-version: '3.6'
python-version: '3.8'
- run: ./.github/scripts/install-drgn.sh
- run: python3 -m pip install mypy==0.730
- run: python3 -m mypy --strict --show-error-codes -p sdb
Expand All @@ -112,7 +114,7 @@ jobs:
# Verify that "shfmt" ran successfully against our shell scripts.
#
shfmt:
runs-on: ubuntu-18.04
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: delphix/actions/shfmt@master
37 changes: 17 additions & 20 deletions sdb/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

from sdb.target import type_canonicalize_name, type_canonical_name, type_canonicalize, get_prog
from sdb.error import CommandError, SymbolNotFoundError
import sdb.target as target
from sdb import target

#
# The register_command is used by the Command class when its
Expand All @@ -45,17 +45,13 @@ def register_command(name: str, class_: Type["Command"]) -> None:
Register the specified command name and command class, such that the
command will be available from the SDB REPL.
"""
# pylint: disable=global-statement
global all_commands
all_commands[name] = class_


def get_registered_commands() -> Dict[str, Type["Command"]]:
"""
Return a dictionary of command names to command classes.
"""
# pylint: disable=global-statement
global all_commands
return all_commands


Expand Down Expand Up @@ -108,11 +104,12 @@ def help(cls, name: str) -> None:
#
if i == 0:
line = line.replace('usage: ', '')
print(" {}".format(line))
print(f" {line}")

if len(cls.names) > 1:
aliases = ", ".join(cls.names)
print("ALIASES")
print(" {}".format(", ".join(cls.names)))
print(f" {aliases}")
print()

indent = " "
Expand Down Expand Up @@ -168,7 +165,7 @@ def help(cls, name: str) -> None:
f" case it will consume no objects as input; instead it"
f" will locate all objects of type '{cls.output_type}',"
f" and emit them as output.")
types = list()
types = []
for (_, method) in inspect.getmembers(cls, inspect.isroutine):
if hasattr(method, "input_typename_handled"):
types.append(method.input_typename_handled)
Expand Down Expand Up @@ -203,7 +200,7 @@ def help(cls, name: str) -> None:
#
for line in inspect.getdoc( # type: ignore[union-attr]
cls).splitlines()[2:]:
print("{}".format(line))
print(f"{line}")
print()

#
Expand Down Expand Up @@ -588,12 +585,11 @@ class Walk(Command):
def _help_message(input_type: drgn.Type = None) -> str:
msg = ""
if input_type is not None:
msg = msg + "no walker found for input of type {}\n".format(
input_type)
msg = msg + "The following types have walkers:\n"
msg = msg + "\t%-20s %-20s\n" % ("WALKER", "TYPE")
msg += f"no walker found for input of type {input_type}\n"
msg += "The following types have walkers:\n"
msg += f"\t{'WALKER':-20s} {'TYPE':-20s}\n"
for type_, class_ in Walker.allWalkers.items():
msg = msg + "\t%-20s %-20s\n" % (class_.names[0], type_)
msg += f"\t{class_.names[0]:-20s} {type_:-20s}\n"
return msg

def _call(self, objs: Iterable[drgn.Object]) -> Iterable[drgn.Object]:
Expand Down Expand Up @@ -645,11 +641,12 @@ def _call(self, objs: Iterable[drgn.Object]) -> Iterable[drgn.Object]:
assert self.input_type is not None
expected_type = type_canonicalize_name(self.input_type)
for obj in objs:
if type_canonical_name(obj.type_) != expected_type:
canonical_type = type_canonical_name(obj.type_)
if canonical_type != expected_type:
raise CommandError(
self.name,
'expected input of type {}, but received {}'.format(
expected_type, type_canonical_name(obj.type_)))
f'expected input of type {expected_type}, but received {canonical_type}'
)

yield from self.walk(obj)

Expand Down Expand Up @@ -724,7 +721,7 @@ def caller(self, objs: Iterable[drgn.Object]) -> Iterable[drgn.Object]:
out_type = None
if self.output_type is not None:
out_type = target.get_type(self.output_type)
baked = dict()
baked = {}
for (_, method) in inspect.getmembers(self, inspect.ismethod):
if not hasattr(method, "input_typename_handled"):
continue
Expand Down Expand Up @@ -762,8 +759,8 @@ def caller(self, objs: Iterable[drgn.Object]) -> Iterable[drgn.Object]:
pass

# error
raise CommandError(
self.name, 'no handler for input of type {}'.format(i.type_))
raise CommandError(self.name,
f'no handler for input of type {i.type_}')

def _call(self,
objs: Iterable[drgn.Object]) -> Optional[Iterable[drgn.Object]]:
Expand Down
8 changes: 4 additions & 4 deletions sdb/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@
import importlib
import os

for path in glob.glob("{}/*.py".format(os.path.dirname(__file__))):
for path in glob.glob(f"{os.path.dirname(__file__)}/*.py"):
if path != __file__:
module = os.path.splitext(os.path.basename(path))[0]
importlib.import_module("sdb.commands.{}".format(module))
importlib.import_module(f"sdb.commands.{module}")

for path in glob.glob("{}/*/__init__.py".format(os.path.dirname(__file__))):
for path in glob.glob(f"{os.path.dirname(__file__)}/*/__init__.py"):
module = os.path.basename(os.path.dirname(path))
importlib.import_module("sdb.commands.{}".format(module))
importlib.import_module(f"sdb.commands.{module}")
1 change: 0 additions & 1 deletion sdb/commands/exit.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@


class Exit(sdb.Command):

"Exit the application"

names = ["exit", "quit"]
Expand Down
10 changes: 5 additions & 5 deletions sdb/commands/filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ def _call_one(self, obj: drgn.Object) -> Iterable[drgn.Object]:
if not isinstance(lhs, drgn.Object):
raise sdb.CommandInvalidInputError(
self.name,
"left hand side has unsupported type ({})".format(
type(lhs).__name__))
f"left hand side has unsupported type ({type(lhs).__name__})"
)

if isinstance(rhs, str):
lhs = lhs.string_().decode("utf-8")
Expand All @@ -127,10 +127,10 @@ def _call_one(self, obj: drgn.Object) -> Iterable[drgn.Object]:
else:
raise sdb.CommandInvalidInputError(
self.name,
"right hand side has unsupported type ({})".format(
type(rhs).__name__))
f"right hand side has unsupported type ({type(rhs).__name__})"
)

if eval("lhs {} rhs".format(self.compare), {'__builtins__': None}, {
if eval(f"lhs {self.compare} rhs", {'__builtins__': None}, {
'lhs': lhs,
'rhs': rhs
}):
Expand Down
4 changes: 2 additions & 2 deletions sdb/commands/internal/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import importlib
import os

for path in glob.glob("{}/*.py".format(os.path.dirname(__file__))):
for path in glob.glob(f"{os.path.dirname(__file__)}/*.py"):
if path != __file__:
module = os.path.splitext(os.path.basename(path))[0]
importlib.import_module("sdb.commands.internal.{}".format(module))
importlib.import_module(f"sdb.commands.internal.{module}")
8 changes: 4 additions & 4 deletions sdb/commands/linux/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@
import importlib
import os

for path in glob.glob("{}/*.py".format(os.path.dirname(__file__))):
for path in glob.glob(f"{os.path.dirname(__file__)}/*.py"):
if path != __file__:
module = os.path.splitext(os.path.basename(path))[0]
importlib.import_module("sdb.commands.linux.{}".format(module))
importlib.import_module(f"sdb.commands.linux.{module}")

for path in glob.glob("{}/*/__init__.py".format(os.path.dirname(__file__))):
for path in glob.glob(f"{os.path.dirname(__file__)}/*/__init__.py"):
module = os.path.basename(os.path.dirname(path))
importlib.import_module("sdb.commands.linux.{}".format(module))
importlib.import_module(f"sdb.commands.linux.{module}")
2 changes: 1 addition & 1 deletion sdb/commands/linux/dmesg.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@ def pretty_print(self, objs: Iterable[drgn.Object]) -> None:
message = drgn.cast("char *", obj) + obj.type_.type.size
text = message.string_().decode('utf-8', 'ignore')

print("[{:5d}.{:06d}]: {:s}".format(secs, usecs, text))
print(f"[{secs:5d}.{usecs:06d}]: {text}")
4 changes: 2 additions & 2 deletions sdb/commands/linux/internal/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import importlib
import os

for path in glob.glob("{}/*.py".format(os.path.dirname(__file__))):
for path in glob.glob(f"{os.path.dirname(__file__)}/*.py"):
if path != __file__:
module = os.path.splitext(os.path.basename(path))[0]
importlib.import_module("sdb.commands.linux.internal.{}".format(module))
importlib.import_module(f"sdb.commands.linux.internal.{module}")
6 changes: 3 additions & 3 deletions sdb/commands/linux/slabs.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def no_input(self) -> Iterable[drgn.Object]:
# that will be the input of the next command in the pipeline.
#
if self.args.s and not self.islast:
if self.args.s not in Slabs.FIELDS.keys():
if Slabs.FIELDS[self.args.s] is None:
raise sdb.CommandInvalidInputError(
self.name, f"'{self.args.s}' is not a valid field")
yield from sorted(
Expand Down Expand Up @@ -154,8 +154,8 @@ def __pp_parse_args(self) -> Tuple[str, List[str], Dict[str, Any]]:

for field in fields:
if field not in self.FIELDS:
raise sdb.CommandError(
self.name, "'{:s}' is not a valid field".format(field))
raise sdb.CommandError(self.name,
f"'{field}' is not a valid field")

sort_field = ""
if self.args.s:
Expand Down
15 changes: 7 additions & 8 deletions sdb/commands/member.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,7 @@ def _parse_member_tokens(
if not tokens[1].isdigit():
raise sdb.CommandError(
self.name,
"incorrect index: '{}' is not a number".format(
tokens[1]))
f"incorrect index: '{tokens[1]}' is not a number")
is_index = True
idx = tokens[1]
sep = MemberExprSep.ARRAY
Expand All @@ -191,8 +190,7 @@ def _parse_member_tokens(

if not is_index and not identifier.isidentifier():
raise sdb.CommandError(
self.name,
"{} is not an acceptable identifier".format(identifier))
self.name, f"{identifier} is not an acceptable identifier")

if not is_index:
assert idx == ""
Expand Down Expand Up @@ -238,8 +236,8 @@ def _validate_type_dereference(self, obj: drgn.Object,
if kind == drgn.TypeKind.STRUCT and sep != MemberExprSep.DOT:
raise sdb.CommandError(
self.name,
"'{}' is a struct - use the dot(.) notation for member access".
format(obj.type_))
f"'{obj.type_}' is a struct - use the dot(.) notation for member access"
)

if kind == drgn.TypeKind.POINTER:
assert sep in [
Expand All @@ -249,8 +247,9 @@ def _validate_type_dereference(self, obj: drgn.Object,

if kind == drgn.TypeKind.ARRAY and sep != MemberExprSep.ARRAY:
raise sdb.CommandError(
self.name, "'{}' is an array - cannot use '{}' notation".format(
obj.type_, sep.value))
self.name,
f"'{obj.type_}' is an array - cannot use '{sep.value}' notation"
)

def _validate_array_index(self, type_: drgn.Type, idx: int) -> None:
"""
Expand Down
3 changes: 1 addition & 2 deletions sdb/commands/pretty_print.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ def _call(self, objs: Iterable[drgn.Object]) -> None:

if handling_class is None:
if first_obj_type is not None:
msg = 'could not find pretty-printer for type {}\n'.format(
first_obj_type)
msg = f'could not find pretty-printer for type {first_obj_type}\n'
else:
msg = 'could not find pretty-printer\n'
msg += "The following types have pretty-printers:\n"
Expand Down
9 changes: 6 additions & 3 deletions sdb/commands/pyfilter.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,12 @@ def __init__(self,
raise sdb.CommandEvalSyntaxError(self.name, err)

def _call(self, objs: Iterable[drgn.Object]) -> Iterable[drgn.Object]:
# pylint: disable=eval-used
func = lambda obj: eval(self.code, {'__builtins__': None}, {'obj': obj})

def filter_cb(obj: drgn.Object) -> Optional[drgn.Object]:
# pylint: disable=eval-used
return eval(self.code, {'__builtins__': None}, {'obj': obj})

try:
yield from filter(func, objs)
yield from filter(filter_cb, objs)
except (TypeError, AttributeError) as err:
raise sdb.CommandError(self.name, str(err))
4 changes: 2 additions & 2 deletions sdb/commands/spl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import importlib
import os

for path in glob.glob("{}/*.py".format(os.path.dirname(__file__))):
for path in glob.glob(f"{os.path.dirname(__file__)}/*.py"):
if path != __file__:
module = os.path.splitext(os.path.basename(path))[0]
importlib.import_module("sdb.commands.spl.{}".format(module))
importlib.import_module(f"sdb.commands.spl.{module}")
Loading