From 3fb8055d3de0c032dadf44ee2115d661b4fb6d35 Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Mon, 15 Jun 2026 09:50:32 +0400 Subject: [PATCH 1/4] chore: add `.pylintrc` to eliminate import errors --- .pylintrc | 2 ++ lldb/commands/hex_dump.py | 9 +++++++++ 2 files changed, 11 insertions(+) create mode 100644 .pylintrc create mode 100644 lldb/commands/hex_dump.py diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 0000000..c6d73d8 --- /dev/null +++ b/.pylintrc @@ -0,0 +1,2 @@ +[MASTER] +init-hook="from pylint.config import find_pylintrc; import os, sys; sys.path.append(os.path.dirname(find_pylintrc()))" diff --git a/lldb/commands/hex_dump.py b/lldb/commands/hex_dump.py new file mode 100644 index 0000000..75296fd --- /dev/null +++ b/lldb/commands/hex_dump.py @@ -0,0 +1,9 @@ +# +# dotfiles +# Copyright © 2025 Space Code. All rights reserved. +# + + +def commands(): + """Return a list of custom LLDB commands registered in the plugin""" + return [] From dcd34b8809f50390481e67be9416333af7def681 Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Mon, 15 Jun 2026 10:07:27 +0400 Subject: [PATCH 2/4] chore: add comments --- lldb/commands/hex_dump.py | 66 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/lldb/commands/hex_dump.py b/lldb/commands/hex_dump.py index 75296fd..b1c66ec 100644 --- a/lldb/commands/hex_dump.py +++ b/lldb/commands/hex_dump.py @@ -3,7 +3,69 @@ # Copyright © 2025 Space Code. All rights reserved. # +""" +This module defines the DTHexDumpCommand class, which provides a custom LLDB command +for reading memory at a specific address and displaying it in a formatted hex dump. +""" + +import lldbbase as bc + def commands(): - """Return a list of custom LLDB commands registered in the plugin""" - return [] + """ + Returns a list of custom LLDB command instances defined in this module. + The registration logic in lldbinit.py calls this function. + """ + return [DTHexDumpCommand()] + + +class DTHexDumpCommand(bc.BaseCommand): + """ + A custom LLDB command that performs a hex dump of memory at a given address. + Usage: hex_dump
[-c count] [-o offset] + """ + + def name(self): + """Returns the command name as it will be used in the LLDB console.""" + return "hex_dump" + + def description(self): + """Returns a short description of the command's functionality.""" + return "Read data from the specific address and return formatted output." + + def options(self): + """ + Defines the supported command-line options for the hex_dump command. + + Available options: + -c, --count: Number of bytes to read (default: 16). + -o, --offset: Starting offset from the provided address (default: 0). + """ + return [ + bc.CommandArgument( + short="-c", + long="--count", + arg="count", + type="string", + default="16", + help="The number of bytes to read from memory.", + ), + bc.CommandArgument( + short="-o", + long="--offset", + arg="offset", + type="string", + default="0", + help="The memory offset (in bytes) to start reading from.", + ), + ] + + def run(self, args, options): + """ + The main execution logic for the command. + + Parameters: + args: Positional arguments (the memory address). + options: Parsed command-line options (count, offset). + """ + return super().run(args, options) From 75b44888a778e805b8ded14780487471dad48758 Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Mon, 15 Jun 2026 10:40:37 +0400 Subject: [PATCH 3/4] docs: add a reference to a new command in `README.md` --- README.md | 1 + lldb/commands/{hex_dump.py => DTInspection.py} | 0 2 files changed, 1 insertion(+) rename lldb/commands/{hex_dump.py => DTInspection.py} (100%) diff --git a/README.md b/README.md index 9e27757..eb2cfd4 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ This project enhances the LLDB debugging experience with custom Python commands, | :--- | :--- | :--- | | **`alcheck`** | Highlights `UIViews` with Auto Layout issues by outlining them in red. | `[-c color] [-w width]` | | **`pdefaults`** | Dumps `NSUserDefaults` contents as a formatted key-value table. | `[-s suite] [-f filter] [-o]` | +| **`hex_dump`** | Reads memory at a specific address and returns a formatted hex dump. | `
[-c count] [-o offset]` | ### Useful Aliases & Regex Commands diff --git a/lldb/commands/hex_dump.py b/lldb/commands/DTInspection.py similarity index 100% rename from lldb/commands/hex_dump.py rename to lldb/commands/DTInspection.py From d12859948b3bf28159b42a68b43b51f5401fa06a Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Mon, 15 Jun 2026 10:48:22 +0400 Subject: [PATCH 4/4] ci: add workflows --- .github/workflows/conventional-pr.yml | 25 +++ .github/workflows/lint.yml | 32 ++++ .github/workflows/validate.yml | 26 +++ .gitignore | 220 ++++++++++++++++++++++++++ 4 files changed, 303 insertions(+) create mode 100644 .github/workflows/conventional-pr.yml create mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/validate.yml create mode 100644 .gitignore diff --git a/.github/workflows/conventional-pr.yml b/.github/workflows/conventional-pr.yml new file mode 100644 index 0000000..e3ef03a --- /dev/null +++ b/.github/workflows/conventional-pr.yml @@ -0,0 +1,25 @@ +name: conventional-pr +on: + pull_request: + branches: + - main + types: + - opened + - edited + - synchronize +permissions: + contents: read + pull-requests: read + statuses: write +jobs: + lint-pr: + runs-on: ubuntu-latest + timeout-minutes: 15 + if: ${{ !startsWith(github.event.head_commit.message, '[Release]') }} + steps: + - uses: actions/checkout@v6 + - uses: amannn/action-semantic-pull-request@v6 + with: + requireScope: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..f103dc5 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,32 @@ +name: lint + +on: + push: + branches: + - main + +concurrency: + group: lint-${{ github.head_ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + discover-typos: + name: discover-typos + runs-on: macos-26 + steps: + - uses: actions/checkout@v6 + + - name: Set up Python environment + run: | + python3 -m venv .venv + source .venv/bin/activate + pip install --upgrade pip + pip install codespell + + - name: Discover typos + run: | + source .venv/bin/activate + codespell --ignore-words-list="hart,inout,msdos,sur" --skip="./.build/*,./.git/*" \ No newline at end of file diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml new file mode 100644 index 0000000..d0cdec0 --- /dev/null +++ b/.github/workflows/validate.yml @@ -0,0 +1,26 @@ +name: validate + +on: + push: + branches: + - main + pull_request: + paths: + - "lldb/**" + +concurrency: + group: validate-${{ github.head_ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + lint: + runs-on: macos-latest + steps: + - uses: actions/checkout@v6 + + - name: Python syntax check + run: | + find . -name "*.py" -exec python3 -m py_compile {} \; \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b85f2b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,220 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[codz] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py.cover +*.lcov +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +# Pipfile.lock + +# UV +# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# uv.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +# poetry.lock +# poetry.toml + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python. +# https://pdm-project.org/en/latest/usage/project/#working-with-version-control +# pdm.lock +# pdm.toml +.pdm-python +.pdm-build/ + +# pixi +# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control. +# pixi.lock +# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one +# in the .venv directory. It is recommended not to include this directory in version control. +.pixi/* +!.pixi/config.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule* +celerybeat.pid + +# Redis +*.rdb +*.aof +*.pid + +# RabbitMQ +mnesia/ +rabbitmq/ +rabbitmq-data/ + +# ActiveMQ +activemq-data/ + +# SageMath parsed files +*.sage.py + +# Environments +.env +.envrc +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +# .idea/ + +# Abstra +# Abstra is an AI-powered process automation framework. +# Ignore directories containing user credentials, local state, and settings. +# Learn more at https://abstra.io/docs +.abstra/ + +# Visual Studio Code +# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore +# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore +# and can be added to the global gitignore or merged into this file. However, if you prefer, +# you could uncomment the following to ignore the entire vscode folder +# .vscode/ +# Temporary file for partial code execution +tempCodeRunnerFile.py + +# Ruff stuff: +.ruff_cache/ + +# PyPI configuration file +.pypirc + +# Marimo +marimo/_static/ +marimo/_lsp/ +__marimo__/ + +# Streamlit +.streamlit/secrets.toml \ No newline at end of file