README.md
1# `ipkdbg`: Generate gdb environments from opkg package archives
2
3`ipkdbg` automates the process of generating `gdb` environments for interactive
4debugging and coredump analysis of split-debug binaries by exploiting bitbake's
5runtime package management support outside the context of the BMC.
6
7## Use of `ipkdbg`
8
9Assuming the presence of the [appropriate integration](#theory-of-integration),
10using `ipkdbg` requires minimal fuss.
11
12```text
13SYNOPSIS
14 ipkdbg [-q] RELEASE FILE CORE [PACKAGE...]
15```
16
17It handles the following use-cases:
18
19### Core Dump Analysis
20
21After extracting a core file from the BMC an interactive `gdb` session can be
22set up against it with:
23
24```sh
25$ ipkdbg 2.11.0 - my-application.core
26...
27(gdb)
28```
29
30Where:
31
321. `ipkdbg` is the script
332. `2.11.0` is the OpenBMC version tag that locates the appropriate `opkg.conf`
343. `-` is the FILE parameter. `-` specifies it must be extracted from the core
354. `my-application.core` is a core dump generated by `/usr/bin/my-application`
36
37Note that for convenience `ipkdbg` automatically runs `bt` in the `gdb` session
38once the core has been loaded to provide a backtrace.
39
40Note that we don't need to specify any packages to install into the rootfs _if_
41the image package database is available. `ipkdbg` will perform a reverse-lookup
42to map the absolute binary path extracted from the core to the package that
43installed it. From there `opkg` will resolve all the dependencies. Additionally,
44`ipkdbg` will identify the associated debug symbol and source packages and
45install them as well.
46
47If an image package database is not available then `ipkdbg` will require that
48the necessary packages are listed on the command-line.
49
50### Scripted Backtrace Extraction
51
52For use in scripting environments to automate backtrace extraction `ipkdbg` has
53the `-q` option to quit `gdb` immediately after the backtrace is printed. The
54invocation looks like:
55
56```sh
57ipkdbg -q 2.11.0 - my-application.core
58```
59
60### Interactive debug
61
62Interactive debugging is handled by attaching `gdbserver` on the BMC to the
63running instance of `/usr/bin/my-application` on the BMC. `ipkdbg` is then used
64to generate the `gdb` environment:
65
66```sh
67$ ipkdbg 2.11.0 /usr/bin/my-application -
68...
69(gdb)
70```
71
72Where:
73
741. `ipkdbg` is the script
752. `2.11.0` is the OpenBMC version tag that locates the appropriate `opkg.conf`
763. `/usr/bin/my-application` is the absolute path of the application to debug
774. `-` is the CORE parameter. `-` specifies that there is no core file
78
79Note that we don't need to specify any packages to install into the rootfs _if_
80the image package database is available. `ipkdbg` will perform a reverse-lookup
81to map the absolute binary path provided on the command-line to the package that
82installed it. From there `opkg` will resolve all the dependencies. Additionally,
83`ipkdbg` will identify the associated debug symbol and source packages and
84install them as well.
85
86If an image package database is not available then `ipkdbg` will require that
87the necessary packages are listed on the command-line.
88
89Once the `(gdb)` prompt is reached the usual remote debugging command applies:
90
91```text
92(gdb) target remote $BMC:1234
93```
94
95### Whoops, I Forgot A Package
96
97To save exiting the `gdb` session and re-invoking `ipkdbg` to add a package to
98the rootfs environment, `ipkdbg` installs an `opkg` helper into the PATH of the
99`gdb` process. With this, you can drop to a shell from `gdb` via the `sh`
100command, and then run `opkg install ...` to install the necessary packages. Exit
101the shell subprocess to return to your `gdb` prompt with the new package
102included in the `gdb` environment.
103
104## Theory of Maintenance
105
106`ipkdbg` is intended to operate with minimal assumptions about its environment.
107The assumptions it does make are:
108
1091. It's running in a POSIX environment with access to
110 1. `coreutils`
111 2. `awk`
112 3. `tar`
113 4. `gzip`
114 5. `wget`
1152. A multi-arch capable `gdb` is installed
116
117However, `ipkdbg` also relies on `opkg` to get its job done. As `opkg` is itself
118a package manager, it tends not to be available as a package via distro package
119managers. A conflicting requirement is that we want `ipkdbg` to be able to run
120almost anywhere without fuss. To resolve these issues `ipkdbg` packages `opkg`
121binaries inside itself as a self-extracting shell-script. What you see in this
122directory is the input script ([`ipkdbg.in`](ipkdbg.in)) and build
123infrastructure ([`Makefile`](Makefile)) for generating an `ipkdbg` executable
124that packages one or more `opkg` binaries.
125
126`ipkdbg` supports multiple distros and architectures by defining a directory
127scheme to contain `opkg` binaries. This hierarchy is archived and compressed
128using `tar` and `gzip`, and the archive embedded in the `ipkdbg` shell script by
129the [`Makefile`](Makefile). The `opkg` path for a given architecture, distro and
130release combination is defined by the following directory hierarchy in terms of
131[`os-release(5)`][os-release]:
132
133[os-release]:
134 https://www.man7.org/linux/man-pages/man5/os-release.5.html#OPTIONS
135
136```sh
137$(uname -m)/${ID}/${VERSION_ID}/opkg
138```
139
140This hierarchy must be placed under a `bin/` directory alongside the
141[`Makefile`](Makefile).
142
143To avoid licensing and distribution legal issues openbmc-tools does not provide
144pre-built `opkg` binaries. You must build your own and integrate them into the
145hierarchy under `bin/` outlined above. To this end,
146[the `build-opkg` script is provided](build-opkg). It probably won't work
147without tinkering for your target distro, but it might get you 90% of the way
148there.
149
150## Maintenance in Practice
151
152Once you have built the required `opkg` binaries and integrated them into the
153hierarchy under `bin/` alongside the `Makefile`, run `make` to generate the
154final `ipkdbg` script. The output script can then be freely copied between
155machines supported by the embedded `opkg` binaries. The build system will handle
156stripping the `opkg` binaries to ensure their size is reduced as much as
157practical prior to archiving and compression. It is worth committing the
158binaries under `bin/` to ensure that the build for your output `ipkdbg` script
159is reproducible.
160
161## Theory of Integration
162
163For `ipkdbg` to do its job via `opkg` it must be possible for it to acquire an
164`opkg.conf` that describes the location of the package archive for your target
165environment. The `IPKDBG_CONF_*` variables help describe a `wget`-compatible URL
166where this configuration lives. `ipkdbg` will bootstrap by fetching this
167`opkg.conf` and then passing it as a parameter to all invocations of `opkg`,
168where these invocations of `opkg` populate a rootfs used as your `gdb` debugging
169environment.
170
171A consequence of this is you must also host `ipk` package archives whose URLs
172can be described in the acquired `opkg.conf`. You will need one complete package
173archive per BMC target environment (tag or release).
174
175The packages can be extracted from the bitbake build tree by archiving
176`tmp/deploy/ipk` once `bitbake obmc-phosphor-image && bitbake package-index` has
177exited successfully.
178
179Finally, `ipkdbg` works best when it has access to the image's installed package
180database. This can be captured from the build tree when the build is configured
181with [`INC_IPK_IMAGE_GEN = "1"`][incremental-builds] by archiving the directory
182hierarchy under `./tmp/work/*/obmc-phosphor-image/1.0-r0/temp/saved` with the
183following incantation:
184
185```sh
186tar -cJf opkg-database.tar.xz \
187 -C ./tmp/work/*/obmc-phosphor-image/1.0-r0/temp/saved/target/ \
188 info lists status
189```
190
191`ipkdbg` assumes that the appropriate `opkg-database.tar.xz` can be fetched
192using `wget` and that its URL can be generated in the same manner as that for
193`opkg.conf`.
194
195[incremental-builds]:
196 https://git.openembedded.org/openembedded-core/commit/?id=adf587e55c0f9bc74f0bef415273c937401baebb
197