From 03793fae84b917af22adf02842475795b96329bd Mon Sep 17 00:00:00 2001 From: "Daniel A. Wozniak" Date: Sun, 22 Oct 2023 22:23:52 -0700 Subject: [PATCH] Fix up pre-commit config --- .pre-commit-config.yaml | 2 +- pyproject.toml | 6 ++++ setup.cfg | 59 ++++++++++++++++++++++++++++++++++ setup.py | 7 +++-- src/relenv_gdb/build.py | 66 +++++++++++++++++++++++++-------------- src/relenv_gdb/dbg.py | 17 ++++++++-- src/relenv_gdb/gdbinit.py | 23 +++++++++----- src/relenv_gdb/inject.py | 25 ++++++++------- 8 files changed, 154 insertions(+), 51 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d45acb0..ad51fd4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,7 +18,7 @@ repos: - id: check-copyright-headers name: Check python modules for appropriate copyright headers files: ^.*\.py$ - exclude: setup\.py + exclude: (setup\.py|libpython\.py) entry: python .pre-commit-hooks/copyright_headers.py language: system # <---- Local Hooks ------------------------------------------------------------------------------------------------ diff --git a/pyproject.toml b/pyproject.toml index c78af6e..132b443 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,3 +6,9 @@ requires = [ ] build-backend = "build" backend-path = ["src/relenv_gdb"] + +[tool.isort] +skip = "src/relenv_gdb/libpython.py" + +[tool.black] +force_exclude = "libpython.py" diff --git a/setup.cfg b/setup.cfg index 5ce4575..caef65f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -29,3 +29,62 @@ where=src [options.entry_points] console_scripts = relenv-gdb = relenv_gdb.gdbinit:main + +[flake8] +max-line-length = 120 +exclude = + # No need to traverse our git directory + .git, + # Nox virtualenvs are also not important + .nox, + # There's no value in checking cache directories + __pycache__, + # Package build stuff + build, + dist, + # The conf file is mostly autogenerated, ignore it + docs/conf.py, + # Also ignore setup.py, it's mostly a shim + setup.py, + # Ignore our custom pre-commit hooks + .pre-commit-hooks + src/relenv_gdb/libpython.py + +ignore = + # D104 Missing docstring in public package + D104, + # D107 Missing docstring in __init__ + D107, + # D200 One-line docstring should fit on one line with quotes + D200, + # D401 First line should be in imperative mood; try rephrasing + D401, + # F403 'from import *' used; unable to detect undefined names + F403, + # F405 '*' may be undefined, or defined from star imports: * + F405 + # line break before binary operator, black does this with pathlib.Path objects + W503 + +per-file-ignores = + # F401 imported but unused + __init__.py: F401 + # D100 Missing docstring in public module + # D103 Missing docstring in public function + noxfile.py: D100,D102,D103,D107,D212,E501 + # D100 Missing docstring in public module + docs/source/conf.py: D100 + # D102 Missing docstring in public method + # D103 Missing docstring in public function + # D107 Missing docstring in __init__ + relenv/build/common.py: D102,D103,D107 + # D100 Missing docstring in public module + # D101 Missing docstring in public class + # D102 Missing docstring in public method + # D103 Missing docstring in public function + # D105 Missing docstring in magic method + # D107 Missing docstring in __init__ + # D205 1 blank line required between summary line and description + # D415 First line should end with a period, question mark, or exclamation poin + # W503 line break before binary operator (black causes this) + tests/*.py: D100,D101,D102,D103,D105,D107,D205,D415,W503 diff --git a/setup.py b/setup.py index e4fe71f..376eb70 100644 --- a/setup.py +++ b/setup.py @@ -1,9 +1,10 @@ -from setuptools import setup, Distribution - +# Copyright 2023 VMware, Inc. +# SPDX-License-Identifier: Apache-2.0 +# +from setuptools import Distribution, setup class BinaryDistribution(Distribution): - def has_ext_modules(self): return True diff --git a/src/relenv_gdb/build.py b/src/relenv_gdb/build.py index 5006d52..ea98b4e 100644 --- a/src/relenv_gdb/build.py +++ b/src/relenv_gdb/build.py @@ -1,23 +1,29 @@ +# Copyright 2023 VMware, Inc. +# SPDX-License-Identifier: Apache-2.0 +# +""" +Build our python wheel. +""" import contextlib +import os import pathlib +import shutil import subprocess import tempfile -import os -import shutil - -from setuptools import build_meta as _orig -from setuptools.build_meta import * +import relenv.buildenv import relenv.common import relenv.create -import relenv.buildenv - +from setuptools.build_meta import * _build_wheel = build_wheel @contextlib.contextmanager def pushd(path): + """ + A pushd context manager. + """ orig = os.getcwd() try: os.chdir(path) @@ -27,7 +33,7 @@ def pushd(path): def build_gdb(prefix): - + """Compile and install gdb to the prefix.""" src = prefix / "src" src.mkdir() @@ -42,17 +48,26 @@ def build_gdb(prefix): dir_name = archive_name.split(".tar")[0] os.environ.update(relenv.buildenv.buildenv(prefix)) - os.environ["CFLAGS"] = f"{os.environ['CFLAGS']} -I{os.environ['RELENV_PATH']}/include/ncursesw" - os.environ["CPPFLAGS"] = f"{os.environ['CPPFLAGS']} -I{os.environ['RELENV_PATH']}/include/ncursesw" + os.environ[ + "CFLAGS" + ] = f"{os.environ['CFLAGS']} -I{os.environ['RELENV_PATH']}/include/ncursesw" + os.environ[ + "CPPFLAGS" + ] = f"{os.environ['CPPFLAGS']} -I{os.environ['RELENV_PATH']}/include/ncursesw" import pprint + pprint.pprint(dict(os.environ)) with pushd(src / dir_name): - subprocess.run(["./configure", f"--prefix={os.environ['RELENV_PATH']}/lib/python3.10/site-packages/relenv_gdb/gdb"]) + subprocess.run( + [ + "./configure", + f"--prefix={os.environ['RELENV_PATH']}/lib/python3.10/site-packages/relenv_gdb/gdb", + ] + ) subprocess.run(["make"]) subprocess.run(["make", "install"]) - url = "https://ftp.gnu.org/gnu/gdb/gdb-13.2.tar.xz" relenv.common.download_url( url, @@ -61,27 +76,28 @@ def build_gdb(prefix): archive_name = str(src / pathlib.Path(url).name) relenv.common.extract_archive(str(src), archive_name) dir_name = archive_name.split(".tar")[0] - #os.environ["LDFLAGS"] = f"{os.environ['LDFLAGS']} '-Wl,-rpath=$$ORIGIN/../lib'" + # os.environ["LDFLAGS"] = f"{os.environ['LDFLAGS']} '-Wl,-rpath=$$ORIGIN/../lib'" with pushd(src / dir_name): - subprocess.run([ - "./configure", - f"--prefix={os.environ['RELENV_PATH']}/lib/python3.10/site-packages/relenv_gdb/gdb", - f"--with-python={os.environ['RELENV_PATH']}/bin/python3", - "--with-lzma", - ]) + subprocess.run( + [ + "./configure", + f"--prefix={os.environ['RELENV_PATH']}/lib/python3.10/site-packages/relenv_gdb/gdb", + f"--with-python={os.environ['RELENV_PATH']}/bin/python3", + "--with-lzma", + ] + ) subprocess.run(["make"]) subprocess.run(["patchelf", "--add-rpath", "$ORIGIN/../lib", "gdb/gdb"]) subprocess.run(["make", "install"]) relenv.relocate.main(os.environ["RELENV_PATH"]) shutil.copytree( f"{os.environ['RELENV_PATH']}/lib/python3.10/site-packages/relenv_gdb/gdb", - "src/relenv_gdb/gdb" + "src/relenv_gdb/gdb", ) -def build_wheel(wheel_directory, - metadata_directory=None, config_settings=None): - """PEP 517 wheel creation hook""" +def build_wheel(wheel_directory, metadata_directory=None, config_settings=None): + """PEP 517 wheel creation hook.""" static_build_dir = os.environ.get("PY_STATIC_BUILD_DIR", "") if static_build_dir: relenvdir = (pathlib.Path(static_build_dir) / "gdb").resolve() @@ -97,6 +113,8 @@ def build_wheel(wheel_directory, relenv.create.create(str(relenvdir)) build_gdb(relenvdir) try: - return _build_wheel(wheel_directory, metadata_directory, config_settings) + return _build_wheel( + wheel_directory, metadata_directory, config_settings + ) finally: shutil.rmtree("src/relenv_gdb/gdb") diff --git a/src/relenv_gdb/dbg.py b/src/relenv_gdb/dbg.py index 67138a5..bf23673 100755 --- a/src/relenv_gdb/dbg.py +++ b/src/relenv_gdb/dbg.py @@ -1,13 +1,15 @@ +# Copyright 2023 VMware, Inc. +# SPDX-License-Identifier: Apache-2.0 """ Use gdb to pull python stack traces for every thread in a parent process and all of it's children. """ import os -import sys -import psutil -import subprocess import pprint +import subprocess +import sys import tempfile +import psutil CMD_TPL = """ set pagination off @@ -32,11 +34,17 @@ def append_line(path, line): + """ + Append a line of text to the file. + """ with open(path, "a") as fp: fp.write(line + "\n") def debug(proc, output): + """ + Debug a process. + """ print(f"Debugging {proc.pid} {' '.join(proc.cmdline())}") fd, path = tempfile.mkstemp() with open(path, "w") as fp: @@ -50,6 +58,9 @@ def debug(proc, output): def main(): + """ + The dbg program entry point. + """ try: pid = int(sys.argv[1]) except (IndexError, ValueError): diff --git a/src/relenv_gdb/gdbinit.py b/src/relenv_gdb/gdbinit.py index 37aaa8f..ff57dcf 100644 --- a/src/relenv_gdb/gdbinit.py +++ b/src/relenv_gdb/gdbinit.py @@ -1,27 +1,34 @@ +# Copyright 2023 VMware, Inc. +# SPDX-License-Identifier: Apache-2.0 +# +""" +Localize gdb startup to the current relenv. +""" +import os import pathlib -import subprocess import sys -import os -real_gdb_bin = pathlib.Path(__file__).parent / "gdb"/ "bin"/ "gdb" -data_directory = pathlib.Path(__file__).parent / "gdb"/ "share" /"gdb" +real_gdb_bin = pathlib.Path(__file__).parent / "gdb" / "bin" / "gdb" +data_directory = pathlib.Path(__file__).parent / "gdb" / "share" / "gdb" + def main(): + """Wrap gdb startup.""" if hasattr(sys, "RELENV"): os.environ["PYTHONHOME"] = f"{sys.RELENV}" if os.execve in os.supports_fd: with open(real_gdb_bin, "rb") as fp: sys.stdout.flush() sys.stderr.flush() - args = [sys.argv[0], f"--data-directory={data_directory}"] + sys.argv[1:] + args = [sys.argv[0], f"--data-directory={data_directory}"] + sys.argv[ + 1: + ] os.execve(fp.fileno(), args, os.environ) else: cmd = real_gdb_bin args = [real_gdb_bin, f"--data-directory={data_directory}"] + sys.argv[1:] os.execve(cmd, args, os.environ) else: - sys.stderr.write( - "Not running in a relenv environment." - ) + sys.stderr.write("Not running in a relenv environment.") sys.stderr.flush() sys.exit(1) diff --git a/src/relenv_gdb/inject.py b/src/relenv_gdb/inject.py index 516acf6..8281871 100644 --- a/src/relenv_gdb/inject.py +++ b/src/relenv_gdb/inject.py @@ -1,5 +1,7 @@ +# Copyright 2023 VMware, Inc. +# SPDX-License-Identifier: Apache-2.0 """ -Inject python code into a running process +Inject python code into a running process. Usage: python3 ./inject.py mycode.py @@ -12,17 +14,11 @@ """ import os -import sys -import psutil import subprocess -import pprint +import sys import tempfile - -def append_line(path, line): - with open(path, "a") as fp: - fp.write(line + "\n") - +import psutil INJ_TPL = """ set pagination off @@ -44,13 +40,17 @@ def append_line(path, line): gdb.set_convenience_variable("SCRIPT", fp.read()) """ -def main2(): + +def main(): + """ + The inject program entrypoint. + """ try: pid = int(sys.argv[1]) except (IndexError, ValueError): pid = -1 try: - parent = psutil.Process(pid) + psutil.Process(pid) except (ValueError, psutil.NoSuchProcess): print("Please provide a valid pid as the first argument") sys.exit(1) @@ -75,5 +75,6 @@ def main2(): os.close(s_fd) os.remove(s_path) + if __name__ == "__main__": - main2() + main()