From 9743898fa2f1716dbf10a2cd64b6a04d78e115c5 Mon Sep 17 00:00:00 2001 From: Mikhail Yevchenko Date: Mon, 7 Sep 2026 17:02:26 +0000 Subject: [PATCH] Add local Debian package + plain binary build task Adds packaging/local-build.sh and packaging/extract-binaries.sh, reused by a new VS Code task, to populate gitignored dist/ and bin/ directories with the same build.sh/test.sh/run.sh scripts the Gitea and GitHub workflows run. --- .gitignore | 1 + HANDOFF.md | 58 +++++++++++++++++++++++++++++++++++ packaging/extract-binaries.sh | 20 ++++++++++++ packaging/local-build.sh | 23 ++++++++++++++ 4 files changed, 102 insertions(+) create mode 100644 HANDOFF.md create mode 100755 packaging/extract-binaries.sh create mode 100755 packaging/local-build.sh diff --git a/.gitignore b/.gitignore index 0b807b5..b574eaf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /.vscode/ /dist/ +/bin/ /distro.zip \ No newline at end of file diff --git a/HANDOFF.md b/HANDOFF.md new file mode 100644 index 0000000..5073367 --- /dev/null +++ b/HANDOFF.md @@ -0,0 +1,58 @@ +# Devcontainer handoff — 2026-09-07 + +## Goal and constraints +Continue the uncommitted g15stats mixed-vendor GPU feature and startup heap-corruption fix inside the Debian 13 devcontainer. + +- Host workspace: `/home/m/Private/Projects/G15Daemon`; container workspace: `/work`. +- User permits temporary artifacts ONLY under `/tmp`. Do not use `/var/tmp`, install host packages, modify host configuration/services, or clean unrelated resources. +- Do not commit or push until requested. Preserve untracked source files, especially `gpu.h` and `tests/`. +- Do not connect to the host daemon, claim USB devices, or change keyboard services merely to run automated tests. Physical LCD validation remains pending. +- User requested real Dev Container CLI validation, not synthetic container fixtures. + +## Git state +Parent `main` / `origin/main`: `9b6443a` (all five projects integrated into Gitea builds). +`g15stats` `master` / `origin/master`: `076641c` (Debian packaging). +Parent points at that published stats commit. GPU feature and crash fix are NOT committed. + +Modified stats files: `Makefile.am`, `README`, `README.rst`, `debian/changelog`, `debian/g15stats.1`, `g15stats.c`. +New source: `gpu.h`, `tests/`. +Also currently untracked, generated host build state: `.deps/`, `Makefile`, `config.h`, `config.log`, `config.status`, `libtool`, `stamp-h1`. Do NOT blindly add all files or run destructive clean commands. Use a clean source copy in `/tmp` rather than reusing those host-generated files. + +## Implemented feature +- AMD amdgpu sysfs and optional NVIDIA nvidia-smi collection; mixed vendors collected together. +- Auto detects supported GPUs in PCI order; two summary columns at once, additional pairs rotate. Explicit PCI selection and off mode supported. +- Utilization, used/total VRAM with units, temperature; missing metrics N/A. +- Background cached collection with bounded NVIDIA subprocess lifecycle. +- Live-tested host adapters: NVIDIA `0000:01:00.0`, AMD `0000:11:00.0`. +- Intel/nouveau/radeon not supported. Containers may not expose host GPU tooling/sysfs adequately; missing metrics in a container do not establish a collector failure. + +## Critical bug found and fixed +User ran the earlier binary: printed both GPUs, then `malloc(): invalid size (unsorted)`. +The bitmap-only g15stats canvas allocation was 1060 bytes, while installed TTF-enabled libg15render initialization wrote an 8-byte FreeType pointer at offset 1064. GDB and Valgrind confirmed heap corruption BEFORE GPU threads started. +Current source uses its own bitmap-only canvas initializer rather than ABI-dependent renderer initialization. Do not revert this fix or treat the old binary/package as safe. + +Latest corrected host executable: `/tmp/g15stats-fix-c0WM5a/g15stats`. +Evidence: `/tmp/g15stats-fix-c0WM5a/QA.md`, `dependencies.txt`, `SHA256SUMS`, source and test copies. +Full application tested ~20 seconds with real CPU/GPU statistics but substituted daemon transport. ASan/UBSan passed; delivered binary Valgrind zero errors; four test groups passed. Physical daemon/LCD interaction NOT verified. +Earlier package builds and rendering tests did not catch this startup bug. Earlier `.deb` files under recovery directories predate the fix and must not be distributed. + +## Rendering +Actual libg15render framebuffer images inspected at native 160x43 and nearest-neighbor enlargement. Tests include one/two GPU, off, N/A, extreme values, pagination, independent glyph checks and canvas clearing. Suspected clipping was investigated; no justified production layout correction was found. Tiny font appearance is not equivalent to missing pixels. +Older reports/renders moved into `/tmp/g15-session-recovery.yJQQcO1I/`. Treat earlier PASS reports as scoped, not evidence that the unfixed full application was safe. + +## Entering the devcontainer +Existing `.devcontainer/devcontainer.json` uses Compose service `dev`, workspace `/work`, and host initialization to regenerate ignored selective USB mappings. `.devcontainer/compose.yaml` builds from `packaging/Dockerfile` and keeps the container alive. +Previously created devcontainer/build images and network were removed at user's request. Reopening will therefore recreate Docker resources; do not silently claim they still exist or start them just to write this handoff. +User can choose Reopen in Container, or run `devcontainer up --workspace-folder /home/m/Private/Projects/G15Daemon`. +Then run `devcontainer exec --workspace-folder /home/m/Private/Projects/G15Daemon bash`. +Read this document at `/work/HANDOFF.md` in the new session. +Host `/tmp` is NOT mounted in the container. Previous QA reports and binary paths above will not automatically be accessible inside it. Rebuild current sources in container `/tmp`; do not add a broad host /tmp mount without asking. + +## Next steps +1. Inspect source diff, new tests, Debian quilt patch and build scripts. Read quality-control instructions if available in new environment. +2. Build from a clean `/tmp` source copy including untracked `gpu.h` and tests, excluding generated host build state and `.git`. +3. Rerun all tests including full startup regression against the actual container renderer ABI, and fresh Debian source/binary package builds. Rebuild standalone source artifacts and lint packages. +4. Existing outer release builder rejects dirty submodules; do not bypass that silently or commit merely to run it. Use a temporary source-package build for this work until commits are authorized. +5. Explain remaining physical LCD validation limitations. On request, commit stats first, update parent pointer second; push stats before parent so gitlinks remain fetchable. + +No container was started for this handoff. This handoff itself is untracked parent documentation. diff --git a/packaging/extract-binaries.sh b/packaging/extract-binaries.sh new file mode 100755 index 0000000..4ced888 --- /dev/null +++ b/packaging/extract-binaries.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# Extracts plain executables and shared libraries from built .deb artifacts. +set -euo pipefail +src=$(realpath "${1:?artifact directory required}") +out=$(realpath "${2:?output binary directory required}") +extract=$(mktemp -d) +trap 'rm -rf "$extract"' EXIT +shopt -s nullglob +debs=("$src"/*.deb) +[[ ${#debs[@]} -gt 0 ]] || { echo 'No .deb files found to extract' >&2; exit 1; } +for deb in "${debs[@]}"; do + dpkg-deb -x "$deb" "$extract" +done +mkdir -p "$out" +for dir in "$extract/usr/bin" "$extract/usr/sbin"; do + [[ -d $dir ]] || continue + find "$dir" -mindepth 1 -maxdepth 1 -type f -exec cp {} "$out/" \; +done +[[ -d $extract/usr/lib ]] && find "$extract/usr/lib" -mindepth 2 -maxdepth 2 -type f -name '*.so*' -exec cp {} "$out/" \; +true diff --git a/packaging/local-build.sh b/packaging/local-build.sh new file mode 100755 index 0000000..584df63 --- /dev/null +++ b/packaging/local-build.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# Populates repo-local dist/ (Debian packages) and bin/ (plain executables), +# reusing the same scripts the Gitea and GitHub workflows run: build.sh and +# test.sh directly when already inside the disposable packaging container +# (e.g. this devcontainer), otherwise run.sh to build that container via Docker. +set -euo pipefail +root=$(cd -- "$(dirname -- "$0")/.." && pwd) +dist="$root/dist" +bindir="$root/bin" +work=$(mktemp -d) +trap 'rm -rf "$work"' EXIT +if [[ -f /.dockerenv && $EUID == 0 ]]; then + apt-get update + bash "$root/packaging/build.sh" "$work" + bash "$root/packaging/test.sh" "$work" +else + bash "$root/packaging/run.sh" "$work" +fi +rm -rf "$dist" "$bindir" +mkdir -p "$dist" "$bindir" +cp "$work"/* "$dist/" +bash "$root/packaging/extract-binaries.sh" "$dist" "$bindir" +echo "PASS: Debian packages in $dist, plain executables/libraries in $bindir"