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

DoneSubmitted by Ludovic Courtès.
2 participants
  • Ludovic Courtès
  • Marius Bakke
Ludovic Courtès wrote on 9 Oct 18:28 +0200
(address . guix-patches@gnu.org)(name . Ludovic Courtès)(address . ludo@gnu.org)
* guix/scripts/build.scm (transform-package-with-debug-info): Newprocedure.(%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 abouteventual "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.texiindex 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 Updatesdiff --git a/guix/scripts/build.scm b/guix/scripts/build.scmindex 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.scmindex 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
Marius Bakke wrote on 10 Oct 23:03 +0200
(name . Ludovic Courtès)(address . ludo@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!
iQEzBAEBCgAdFiEEu7At3yzq9qgNHeZDoqBt8qM6VPoFAl+CIZcACgkQoqBt8qM6VPqxVQf+KC2Y2RSIiKKK9Z+E0zRgZDhTTtTVJsbxxJa8Rzrwqx3tWqQY1sDw3Kq3UMT16+0xsP/jMzA5qvoqR5oV4SgJMQg6LJMxZIAuIcTbxG21tv47oEDqbVqnhX8Yvq13yR+8N8MCemE4oc0tksC+iNW6aPuKT0wUuVnf8+TDAzZf6/fxQAinDqyLoaNh6ZcbfkdOa5dcQGB9E6/EGeum5Ia0Xisn01VBbsI34J82LYFDkxtecwcVj1jwWo94sDU2hnKwQkLxdMH4nk2x8PURzHuAoQZXa4gq9HRvLuCPXeD1AaTnkBd3dgfW6S1EPIG3w/YKeK1qiyghF8FOcrrJn1cB1g===AWWK-----END PGP SIGNATURE-----
Ludovic Courtès wrote on 12 Oct 11:39 +0200
(name . Marius Bakke)(address . marius@gnu.org)(address . 43885@debbugs.gnu.org)
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 byhttps://issues.guix.gnu.org/43890, which triggers rebuilds. The bugreally only affects specific situations. It probably shouldn’t be ablocker, but it’s still annoying. I’ll keep thinking about possiblesolutions though.
Ludovic Courtès wrote on 20 Oct 16:36 +0200
(name . Marius Bakke)(address . marius@gnu.org)(address . 43885-done@debbugs.gnu.org)
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” reallyworks as advertised. :-)
Pushed as 6aeda81602555fbeac0c0a209e74f5262093b513!