[PATCH] guix build: Add '--with-debug-info'.

  • Done
  • quality assurance status badge
Details
2 participants
  • Ludovic Courtès
  • Marius Bakke
Owner
unassigned
Submitted by
Ludovic Courtès
Severity
normal
L
L
Ludovic Courtès wrote on 9 Oct 2020 18:28
(address . guix-patches@gnu.org)(name . Ludovic Courtès)(address . ludo@gnu.org)
20201009162816.4414-1-ludo@gnu.org
* guix/scripts/build.scm (transform-package-with-debug-info): New
procedure.
(%transformations): Add 'with-debug-info'.
(%transformation-options, show-transformation-options-help): Add
'--with-debug-info'.
* tests/scripts-build.scm ("options->transformation, with-debug-info"):
New test.
* doc/guix.texi (Package Transformation Options): Document
'--with-debug-info'.
(Installing Debugging Files): Introduce sections. Remove bit about
eventual "opt-out" since this is not happening. Document
'--with-debug-info' under "Rebuilding with Debugging Info".
---
doc/guix.texi | 121 ++++++++++++++++++++++++++++++++++++++--
guix/scripts/build.scm | 40 +++++++++++++
tests/scripts-build.scm | 17 ++++++
3 files changed, 173 insertions(+), 5 deletions(-)

Toggle diff (256 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index c955041c61..1885690c81 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -350,6 +350,11 @@ Defining Services
* Service Reference:: API reference.
* Shepherd Services:: A particular type of service.
+Installing Debugging Files
+
+* Separate Debug Info:: Installing 'debug' outputs.
+* Rebuilding Debug Info:: Building missing debug info.
+
Bootstrapping
* Reduced Binary Seed Bootstrap:: A Bootstrap worthy of GNU.
@@ -9338,6 +9343,37 @@ must be compatible. If @var{replacement} is somehow incompatible with
@var{package}, then the resulting package may be unusable. Use with
care!
+@cindex debugging info, rebuilding
+@item --with-debug-info=@var{package}
+Build @var{package} in a way that preserves its debugging info and graft
+it onto packages that depend on it. This is useful if @var{package}
+does not already provide debugging info as a @code{debug} output
+(@pxref{Installing Debugging Files}).
+
+For example, suppose you're experiencing a crash in Inkscape and would
+like to see what's up in GLib, a library deep down in Inkscape's
+dependency graph. GLib lacks a @code{debug} output, so debugging is
+tough. Fortunately, you rebuild GLib with debugging info and tack it on
+Inkscape:
+
+@example
+guix install inkscape --with-debug-info=glib
+@end example
+
+Only GLib needs to be recompiled so this takes a reasonable amount of
+time. @xref{Installing Debugging Files}, for more info.
+
+@quotation Note
+Under the hood, this option works by passing the @samp{#:strip-binaries?
+#f} to the build system of the package of interest (@pxref{Build
+Systems}). Most build systems support that option but some do not. In
+that case, an error is raised.
+
+Likewise, if a C/C++ package is built without @code{-g} (which is rarely
+the case), debugging info will remain unavailable even when
+@code{#:strip-binaries?} is false.
+@end quotation
+
@cindex tool chain, changing the build tool chain of a package
@item --with-c-toolchain=@var{package}=@var{toolchain}
This option changes the compilation of @var{package} and everything that
@@ -30877,6 +30913,18 @@ typically written in the ELF format, with a section containing
debugger, GDB, to map binary code to source code; it is required to
debug a compiled program in good conditions.
+This chapter explains how to use separate debug info when packages
+provide it, and how to rebuild packages with debug info when it's
+missing.
+
+@menu
+* Separate Debug Info:: Installing 'debug' outputs.
+* Rebuilding Debug Info:: Building missing debug info.
+@end menu
+
+@node Separate Debug Info
+@section Separate Debug Info
+
The problem with debugging information is that is takes up a fair amount
of disk space. For example, debugging information for the GNU C Library
weighs in at more than 60 MiB. Thus, as a user, keeping all the
@@ -30926,12 +30974,75 @@ directory using the @code{directory} command (@pxref{Source Path,
@c XXX: keep me up-to-date
The @code{debug} output mechanism in Guix is implemented by the
@code{gnu-build-system} (@pxref{Build Systems}). Currently, it is
-opt-in---debugging information is available only for the packages
-with definitions explicitly declaring a @code{debug} output. This may be
-changed to opt-out in the future if our build farm servers can handle
-the load. To check whether a package has a @code{debug} output, use
-@command{guix package --list-available} (@pxref{Invoking guix package}).
+opt-in---debugging information is available only for the packages with
+definitions explicitly declaring a @code{debug} output. To check
+whether a package has a @code{debug} output, use @command{guix package
+--list-available} (@pxref{Invoking guix package}).
+Read on for how to deal with packages lacking a @code{debug} output.
+
+@node Rebuilding Debug Info
+@section Rebuilding Debug Info
+
+@cindex debugging info, rebuilding
+As we saw above, some packages, but not all, provide debugging info in a
+@code{debug} output. What can you do when debugging info is missing?
+The @option{--with-debug-info} option provides a solution to that: it
+allows you to rebuild the package(s) for which debugging info is
+missing---and only those---and to graft those onto the application
+you're debugging. Thus, while it's not as fast as installing a
+@code{debug} output, it is relatively inexpensive.
+
+Let's illustrate that. Suppose you're experiencing a bug in Inkscape
+and would like to see what's going on in GLib, a library that's deep
+down in its dependency graph. As it turns out, GLib does not have a
+@code{debug} output and the backtrace GDB shows is all sadness:
+
+@example
+(gdb) bt
+#0 0x00007ffff5f92190 in g_getenv ()
+ from /gnu/store/@dots{}-glib-2.62.6/lib/libglib-2.0.so.0
+#1 0x00007ffff608a7d6 in gobject_init_ctor ()
+ from /gnu/store/@dots{}-glib-2.62.6/lib/libgobject-2.0.so.0
+#2 0x00007ffff7fe275a in call_init (l=<optimized out>, argc=argc@@entry=1, argv=argv@@entry=0x7fffffffcfd8,
+ env=env@@entry=0x7fffffffcfe8) at dl-init.c:72
+#3 0x00007ffff7fe2866 in call_init (env=0x7fffffffcfe8, argv=0x7fffffffcfd8, argc=1, l=<optimized out>)
+ at dl-init.c:118
+@end example
+
+To address that, you install Inkscape linked against a variant GLib that
+contains debug info:
+
+@example
+guix install inkscape --with-debug-info=glib
+@end example
+
+This time, debugging will be a whole lot nicer:
+
+@example
+$ gdb --args sh -c 'exec inkscape'
+@dots{}
+(gdb) b g_getenv
+Function "g_getenv" not defined.
+Make breakpoint pending on future shared library load? (y or [n]) y
+Breakpoint 1 (g_getenv) pending.
+(gdb) r
+Starting program: /gnu/store/@dots{}-profile/bin/sh -c exec\ inkscape
+@dots{}
+(gdb) bt
+#0 g_getenv (variable=variable@@entry=0x7ffff60c7a2e "GOBJECT_DEBUG") at ../glib-2.62.6/glib/genviron.c:252
+#1 0x00007ffff608a7d6 in gobject_init () at ../glib-2.62.6/gobject/gtype.c:4380
+#2 gobject_init_ctor () at ../glib-2.62.6/gobject/gtype.c:4493
+#3 0x00007ffff7fe275a in call_init (l=<optimized out>, argc=argc@@entry=3, argv=argv@@entry=0x7fffffffd088,
+ env=env@@entry=0x7fffffffd0a8) at dl-init.c:72
+@dots{}
+@end example
+
+Much better!
+
+Note that there can be packages for which @option{--with-debug-info}
+will not have the desired effect. @xref{Package Transformation Options,
+@option{--with-debug-info}}, for more information.
@node Security Updates
@chapter Security Updates
diff --git a/guix/scripts/build.scm b/guix/scripts/build.scm
index e59e0ee67f..6ca669d172 100644
--- a/guix/scripts/build.scm
+++ b/guix/scripts/build.scm
@@ -474,6 +474,40 @@ the equal sign."
obj)
obj)))
+(define (transform-package-with-debug-info specs)
+ "Return a procedure that, when passed a package, set its 'replacement' field
+to the same package but with #:strip-binaries? #f in its 'arguments' field."
+ (define (non-stripped p)
+ (package
+ (inherit p)
+ (arguments
+ (substitute-keyword-arguments (package-arguments p)
+ ((#:strip-binaries? _ #f) #f)))))
+
+ (define (package-with-debug-info p)
+ (if (member "debug" (package-outputs p))
+ p
+ (let loop ((p p))
+ (match (package-replacement p)
+ (#f
+ (package
+ (inherit p)
+ (replacement (non-stripped p))))
+ (next
+ (package
+ (inherit p)
+ (replacement (loop next))))))))
+
+ (define rewrite
+ (package-input-rewriting/spec (map (lambda (spec)
+ (cons spec package-with-debug-info))
+ specs)))
+
+ (lambda (store obj)
+ (if (package? obj)
+ (rewrite obj)
+ obj)))
+
(define (transform-package-tests specs)
"Return a procedure that, when passed a package, sets #:tests? #f in its
'arguments' field."
@@ -505,6 +539,7 @@ the equal sign."
(with-commit . ,transform-package-source-commit)
(with-git-url . ,transform-package-source-git-url)
(with-c-toolchain . ,transform-package-toolchain)
+ (with-debug-info . ,transform-package-with-debug-info)
(without-tests . ,transform-package-tests)))
(define (transformation-procedure key)
@@ -536,6 +571,8 @@ the equal sign."
(parser 'with-git-url))
(option '("with-c-toolchain") #t #f
(parser 'with-c-toolchain))
+ (option '("with-debug-info") #t #f
+ (parser 'with-debug-info))
(option '("without-tests") #t #f
(parser 'without-tests)))))
@@ -561,6 +598,9 @@ the equal sign."
(display (G_ "
--with-c-toolchain=PACKAGE=TOOLCHAIN
build PACKAGE and its dependents with TOOLCHAIN"))
+ (display (G_ "
+ --with-debug-info=PACKAGE
+ build PACKAGE and preserve its debug info"))
(display (G_ "
--without-tests=PACKAGE
build PACKAGE without running its tests")))
diff --git a/tests/scripts-build.scm b/tests/scripts-build.scm
index 6925374baa..d437301496 100644
--- a/tests/scripts-build.scm
+++ b/tests/scripts-build.scm
@@ -348,6 +348,23 @@
(with-store store
(eq? (t store p) p))))
+(test-assert "options->transformation, with-debug-info"
+ '(#:strip-binaries? #f)
+ (let* ((dep (dummy-package "chbouib"))
+ (p (dummy-package "thingie"
+ (build-system gnu-build-system)
+ (inputs `(("foo" ,dep)
+ ("bar" ,grep)))))
+ (t (options->transformation
+ '((with-debug-info . "chbouib")))))
+ (with-store store
+ (let ((new (t store p)))
+ (match (package-inputs new)
+ ((("foo" dep0) ("bar" dep1))
+ (and (string=? (package-full-name dep1)
+ (package-full-name grep))
+ (package-arguments (package-replacement dep0)))))))))
+
(test-assert "options->transformation, without-tests"
(let* ((dep (dummy-package "dep"))
(p (dummy-package "foo"
--
2.28.0
M
M
Marius Bakke wrote on 10 Oct 2020 23:03
(name . Ludovic Courtès)(address . ludo@gnu.org)
87r1q5equg.fsf@gnu.org
Ludovic Courtès <ludo@gnu.org> writes:

Toggle quote (13 lines)
> * guix/scripts/build.scm (transform-package-with-debug-info): New
> procedure.
> (%transformations): Add 'with-debug-info'.
> (%transformation-options, show-transformation-options-help): Add
> '--with-debug-info'.
> * tests/scripts-build.scm ("options->transformation, with-debug-info"):
> New test.
> * doc/guix.texi (Package Transformation Options): Document
> '--with-debug-info'.
> (Installing Debugging Files): Introduce sections. Remove bit about
> eventual "opt-out" since this is not happening. Document
> '--with-debug-info' under "Rebuilding with Debugging Info".

Love it. LGTM!
-----BEGIN PGP SIGNATURE-----

iQEzBAEBCgAdFiEEu7At3yzq9qgNHeZDoqBt8qM6VPoFAl+CIZcACgkQoqBt8qM6
VPqxVQf+KC2Y2RSIiKKK9Z+E0zRgZDhTTtTVJsbxxJa8Rzrwqx3tWqQY1sDw3Kq3
UMT16+0xsP/jMzA5qvoqR5oV4SgJMQg6LJMxZIAuIcTbxG21tv47oEDqbVqnhX8Y
vq13yR+8N8MCemE4oc0tksC+iNW6aPuKT0wUuVnf8+TDAzZf6/fxQAinDqyLoaNh
6ZcbfkdOa5dcQGB9E6/EGeum5Ia0Xisn01VBbsI34J82LYFDkxtecwcVj1jwWo94
sDU2hnKwQkLxdMH4nk2x8PURzHuAoQZXa4gq9HRvLuCPXeD1AaTnkBd3dgfW6S1E
PIG3w/YKeK1qiyghF8FOcrrJn1cB1g==
=AWWK
-----END PGP SIGNATURE-----

L
L
Ludovic Courtès wrote on 12 Oct 2020 11:39
(name . Marius Bakke)(address . marius@gnu.org)(address . 43885@debbugs.gnu.org)
87v9ffvl4s.fsf@gnu.org
Hi!

Marius Bakke <marius@gnu.org> skribis:

Toggle quote (17 lines)
> Ludovic Courtès <ludo@gnu.org> writes:
>
>> * guix/scripts/build.scm (transform-package-with-debug-info): New
>> procedure.
>> (%transformations): Add 'with-debug-info'.
>> (%transformation-options, show-transformation-options-help): Add
>> '--with-debug-info'.
>> * tests/scripts-build.scm ("options->transformation, with-debug-info"):
>> New test.
>> * doc/guix.texi (Package Transformation Options): Document
>> '--with-debug-info'.
>> (Installing Debugging Files): Introduce sections. Remove bit about
>> eventual "opt-out" since this is not happening. Document
>> '--with-debug-info' under "Rebuilding with Debugging Info".
>
> Love it. LGTM!

Cool. :-)

Unfortunately the ‘glib’ example is impaired by
https://issues.guix.gnu.org/43890, which triggers rebuilds. The bug
really only affects specific situations. It probably shouldn’t be a
blocker, but it’s still annoying. I’ll keep thinking about possible
solutions though.

Thanks,
Ludo’.
L
L
Ludovic Courtès wrote on 20 Oct 2020 16:36
(name . Marius Bakke)(address . marius@gnu.org)(address . 43885-done@debbugs.gnu.org)
874kmpdkw3.fsf@gnu.org
Hi,

Ludovic Courtès <ludo@gnu.org> skribis:

Toggle quote (6 lines)
> Unfortunately the ‘glib’ example is impaired by
> <https://issues.guix.gnu.org/43890>, which triggers rebuilds. The bug
> really only affects specific situations. It probably shouldn’t be a
> blocker, but it’s still annoying. I’ll keep thinking about possible
> solutions though.

This is now fixed so “guix build inkscape --with-debug-info=glib” really
works as advertised. :-)

Pushed as 6aeda81602555fbeac0c0a209e74f5262093b513!

Thanks,
Ludo’.
Closed
?