mirror of
https://git.in.rschanz.org/ryan77627/guix.git
synced 2024-11-07 07:26:13 -05:00
guix build: Add '--with-debug-info'.
* 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".
This commit is contained in:
parent
ccf3dcba3d
commit
6aeda81602
3 changed files with 173 additions and 5 deletions
121
doc/guix.texi
121
doc/guix.texi
|
@ -352,6 +352,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.
|
||||
|
@ -9884,6 +9889,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
|
||||
|
@ -31688,6 +31724,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
|
||||
|
@ -31737,12 +31785,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
|
||||
|
|
|
@ -474,6 +474,40 @@ (define replacements
|
|||
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 @@ (define %transformations
|
|||
(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 @@ (define %transformation-options
|
|||
(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 @@ (define (show-transformation-options-help)
|
|||
(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")))
|
||||
|
|
|
@ -348,6 +348,23 @@ (define (package-name* obj)
|
|||
(with-store store
|
||||
(eq? (t store p) p))))
|
||||
|
||||
(test-equal "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"
|
||||
|
|
Loading…
Reference in a new issue