LIKE-DBG turns kernel debugging into a single tmux window
Fully dockerized Linux kernel debugging environment for Linux and MacOS
At a glance
- What is it?
- LIKE-DBG is a containerized Linux kernel debugging lab that builds or adopts a kernel and rootfs, boots it under QEMU, and drops you into a pwndbg or GEF session wired into one tmux window. The host needs only Docker, tmux, Python and uv, and it runs on macOS as well as Linux by picking the accelerator the host can provide.
- Who is it for?
- Adopt LIKE-DBG if you are learning kernel internals or working through CTF challenges and want the whole toolchain reproducible from one command, since the container images, kernel build and debugger session are all pinned by the project. Skip it if you cannot run Docker, or if you need to debug a kernel on real hardware, since everything here is a QEMU guest.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 10 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One command from nothing to a GDB prompt
LIKE-DBG, which stands for Linux Kernel Debugger, is a fully containerized Linux kernel debugging and exploitation lab.
The promise is stated without hedging. It builds or adopts a kernel and root filesystem, boots them under QEMU, and drops you into an interactive GDB session with pwndbg or GEF, wiring every piece into a single tmux window. The stated point is to remove the boring setup so your time goes to the kernel rather than the scaffolding.
The entry command is short:
uv run ./start_kgdbAnd the run is a loop you stay inside. Build or adopt a kernel and rootfs, boot it under QEMU as the Debuggee, attach GDB as the Debugger, then edit, deliver, run, crash, root-cause and repeat.
The host requirements are the part that makes it usable. Every step runs inside Docker, so the only things you install on the host are Docker, tmux, Python and uv. Cross-compilation and initramfs work happen inside containers using a `zig cc` musl toolchain, so no host cross-toolchain is needed. You run as a non-root user in the `docker` group.
That is a genuine reduction in friction. A kernel debugging setup normally means a buildroot, a matching toolchain, a matching GDB, a QEMU invocation with the right machine type, and a debugging serial port, all of which have to agree with each other. Here, the agreement is somebody else's problem.
The project is Python, MIT licensed, and the version history shows a long gap followed by a stable release. v0.1.0 was tagged Baby Steps in October 2022 and v0.1.1 a bug fix release in September 2023, and then v1.0.0 Stable came on 2026-10-13, the same day as the last push.
Bring your own kernel or let it build one
There are two ways to get a kernel, and they correspond to two different jobs.
The first is to build your own. You choose a version, a debug profile and a compiler, and LIKE-DBG downloads, configures and builds it once, then caches it. The documentation calls this the daily driver for kernel study and exploit development.
The second is to bring a CTF or foreign kernel. You hand it a challenge's `bzImage` or `Image`, plus `vmlinux` and `initramfs` if you have them, and it boots that verbatim under GDB. The point of this path is that you are analysing an artifact someone else produced, so the kernel must be exactly the one in the challenge, not something you compiled.
The caching is what makes the build-your-own path practical. The first run builds the container images and a kernel, which the documentation says takes a while, and later runs reuse the cache and start in seconds.
Architecture support covers x86_64 and arm64, and the host is auto-detected. On Apple Silicon, arm64 guests boot with native HVF acceleration. x86_64 on a Mac, and Linux without KVM, fall back to in-container TCG, which is the slow software emulation path. Linux with KVM uses it. Storage, acceleration and networking are chosen per host and recorded per run, so the configuration of a session is not guesswork afterwards.
There is also a worked example bundled with the project. `modules/lk01/` ships a small, deliberately vulnerable training driver plus a crash proof of concept, wired for the full build, load and exploit loop, with a guided walkthrough document that takes you from build to a use-after-free to a crash report.
Debug profiles decide what hardening is actually on
The configuration system is a layered TOML stack with project defaults, personal local overrides, named scenarios and the command line, resolving to named profiles that map onto kernel config fragments and runtime defaults.
The profiles named in the documentation are `exploit-dev`, `hardened`, `kasan`, `ubsan` and `lockdep`, and more besides.
The detail that matters most is a warning about the default. The `exploit-dev` profile is the default, and it only turns KASLR off. SMEP, SMAP and KPTI stay on unless you switch profiles or toggle them yourself.
That is an unusual and defensible choice. The usual expectation for a profile called exploit-dev is that it strips every mitigation, and someone who assumes that and starts writing a kernel exploit against the default will hit SMEP or SMAP behaviour they did not plan for. The documentation is explicit so the surprise lands on the reading, not on the debugging session.
There is also a verification step after the build. Post-build `.config` verification catches a profile that did not take, which is the kind of silent failure that otherwise eats an afternoon.
The configuration documentation is a single reference page covering the TOML config stack, the debug profiles and every knob, which is a sensible place to look before changing anything.
The debugger and the crash reporting are the parts you live in
The debugger choice is deliberate. Kernel runs default to pwndbg for its kernel command set, which covers the KASLR base, slab, `current`, task and module walking and symbol lookup. GEF is a one-line switch if you prefer it.
The crash intelligence is the other thing you live in. There is a byte-exact serial console sink, a parser for panics, oopses and KASAN and UBSAN reports, and an auto-break that traps GDB at the fault with a symbolized backtrace. The `--analyze-crash` flag regenerates a report offline, which matters when you want to re-read a crash without rebooting the guest.
The exploit development loop is where the project goes beyond debugging. `--run` and `--upload` deliver an exploit to the live guest over a 9p share or SSH. A single flag-less `.c` file is auto-compiled static-musl against the target architecture, and anything else is delivered as-is, which is the documented boundary between the convenience path and the escape hatch.
Custom modules are supported too. You can build out-of-tree modules against the running kernel and load them on command with `--insmod` and `--rmmod`, and their symbols auto-load in GDB, so a module you just compiled is immediately debuggable.
Together these are the pieces that turn a debugging setup into a development loop: compile on the host side, ship it in, watch it crash, and get a symbolised backtrace without leaving the tmux window.
Concurrent sessions and recorded artifacts
Two operational details make the tool usable for more than one thing at a time.
Each boot gets its own tmux session named for what it is debugging, its own host ports and its own copy-on-write rootfs overlay. The consequence is that two challenges can be debugged side by side, and `--run` and `--insmod` always land in the guest whose pane you typed them from. The copy-on-write overlay is the detail that matters most here, since it means the two guests do not share a filesystem state.
Session naming is also what makes the tmux workflow usable. Each boot renames its session after what it is debugging, with examples given as `LIKE-DBG-pawnyable-lk01` and `LIKE-DBG-6_6_30-exploit-dev`, so a session you left running never blocks the next one.
The quickstart shows the tmux invocation, and the detail about the exact-match form is the sort of thing that saves real time:
# 1. Install dependencies
uv sync
# 2. Start the project tmux server (loads the shipped .tmux.conf)
tmux -L likedbg -f .tmux.conf new -s LIKE-DBG
# 3. Inside that tmux session: build-or-reuse a kernel, boot it, attach the debugger
uv run ./start_kgdbTo come back to a specific session:
tmux -L likedbg attach -t =LIKE-DBG-6_6_30-exploit-devThe `=` is tmux's exact-match form, and without it a `-2` session can win, which is the kind of ambiguity that sends you to the wrong guest.
The second operational feature is the run record. Every session writes a timestamped `artifacts/runs/<id>/` directory with the resolved settings, the host profile, command records, logs and pane transcripts. For a workflow where you are reproducing a crash or writing up a finding, that record is the difference between a reproducible result and a memory.
The project is written to be read and to be built from source
The Python lives in `src/likedbg/` and the documentation says it is meant to be readable, which is an unusual thing for a project to state about its own source.
The dependency list is short and mostly infrastructure. loguru and tqdm for output, pydantic for the configuration models, the docker SDK for driving the container layer, requests for network calls and platformdirs for paths.
The tooling is strict in a way that suggests the author intends contributors. Ruff runs with a line length of 120 targeting Python 3.12, selecting a broad rule set covering pycodestyle, pyflakes, isort, comprehensions, path handling, tidy imports, performance, naming, pyupgrade and bugbear, with E501 ignored so long lines are not a fight. Isort is forced to single-line imports. Mypy runs in strict mode against the `src/likedbg` files only, with the src directory as the mypy path and explicit package bases.
The version is single-sourced from `likedbg.__version__`, and the comment in the project file explains why: it is kept in one place so a release bump cannot ship a package whose `--version` disagrees with its metadata.
The justfile holds the developer commands, and the comment on the image build order is worth reading:
# Rebuild all container images from current dockerfiles (run after editing a dockerfile/script)
build-images:
uv run ./start_kgdb --build-imagesThe comment above it explains that the images must be built in dependency order, base first, because the others are FROM it, and that skipping this after a source change leaves a stale image in the pipeline, for example an old rootfs.sh that fails on virtiofs, which silently produces wrong or no artifacts.
The repository carries seven separate Dockerfiles, one per role: base, a compiler for macOS, the debugger image, a second debugger variant, the kernel builder, the musl toolchain and the rootfs, with a hadolint configuration for linting them. There is a pre-commit config, a CHANGELOG, a code of conduct and a contributing guide.
Editorial conclusion
Adopt LIKE-DBG if you are learning kernel internals or working through CTF challenges and want the whole toolchain reproducible from one command, since the container images, kernel build and debugger session are all pinned by the project. Skip it if you cannot run Docker, or if you need to debug a kernel on real hardware, since everything here is a QEMU guest. Verify first that your host has Docker, tmux, Python 3.12 and uv, that you understand the default exploit-dev profile only turns KASLR off while SMEP, SMAP and KPTI stay enabled, and that you pick a debug profile matching what you are trying to learn rather than assuming the default is a soft target.
Frequently asked questions
What are the requirements for LIKE-DBG?
Docker, tmux, Python 3.12 or newer, and uv. You run as a non-root user in the docker group, and cross-compilation and initramfs work happen inside containers with a zig cc musl toolchain, so no host cross-toolchain is needed.
Does the exploit-dev profile disable all kernel mitigations?
No. The exploit-dev profile is the default and it only turns KASLR off. SMEP, SMAP and KPTI stay on unless you switch profiles or toggle them yourself, and post-build .config verification catches a profile that did not take.
Can I debug a kernel from a CTF challenge with LIKE-DBG?
Yes. You hand it the challenge's bzImage or Image, plus vmlinux and initramfs if you have them, and it boots that kernel verbatim under GDB. The repository also bundles a deliberately vulnerable training driver in modules/lk01/ with a crash proof of concept and a walkthrough.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/0xricksanchez-like-dbg)Was this useful?