From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp1 ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms11 with LMTPS id OXc4DhCTgF9XCQAA0tVLHw (envelope-from ) for ; Fri, 09 Oct 2020 16:42:56 +0000 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp1 with LMTPS id qGSFCRCTgF8PNwAAbx9fmQ (envelope-from ) for ; Fri, 09 Oct 2020 16:42:56 +0000 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 8CA9A9402A2 for ; Fri, 9 Oct 2020 16:42:55 +0000 (UTC) Received: from localhost ([::1]:59740 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kQvTo-0006r9-Ku for larch@yhetil.org; Fri, 09 Oct 2020 12:42:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37390) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kQvGR-0003pc-SV for guix-patches@gnu.org; Fri, 09 Oct 2020 12:29:04 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:52794) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kQvGQ-0004dV-3a for guix-patches@gnu.org; Fri, 09 Oct 2020 12:29:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1kQvGP-0000e6-Ra for guix-patches@gnu.org; Fri, 09 Oct 2020 12:29:01 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#43885] [PATCH] guix build: Add '--with-debug-info'. Resent-From: Ludovic =?UTF-8?Q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Fri, 09 Oct 2020 16:29:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 43885 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 43885@debbugs.gnu.org Cc: Ludovic =?UTF-8?Q?Court=C3=A8s?= X-Debbugs-Original-To: guix-patches@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.16022609252451 (code B ref -1); Fri, 09 Oct 2020 16:29:01 +0000 Received: (at submit) by debbugs.gnu.org; 9 Oct 2020 16:28:45 +0000 Received: from localhost ([127.0.0.1]:36107 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kQvG8-0000dS-QO for submit@debbugs.gnu.org; Fri, 09 Oct 2020 12:28:45 -0400 Received: from lists.gnu.org ([209.51.188.17]:57718) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kQvG5-0000dH-Q7 for submit@debbugs.gnu.org; Fri, 09 Oct 2020 12:28:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37368) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kQvG5-0003e2-0C for guix-patches@gnu.org; Fri, 09 Oct 2020 12:28:41 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:46528) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kQvG4-0004cr-73; Fri, 09 Oct 2020 12:28:40 -0400 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=59286 helo=gnu.org) by fencepost.gnu.org with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1kQvG2-0007GY-RH; Fri, 09 Oct 2020 12:28:40 -0400 From: Ludovic =?UTF-8?Q?Court=C3=A8s?= Date: Fri, 9 Oct 2020 18:28:16 +0200 Message-Id: <20201009162816.4414-1-ludo@gnu.org> X-Mailer: git-send-email 2.28.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-Spam-Score: -3.3 (---) X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+larch=yhetil.org@gnu.org Sender: "Guix-patches" X-Scanner: scn0 Authentication-Results: aspmx1.migadu.com; dkim=none; dmarc=pass (policy=none) header.from=gnu.org; spf=pass (aspmx1.migadu.com: domain of guix-patches-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=guix-patches-bounces@gnu.org X-Spam-Score: 3.49 X-TUID: NsTNH32TyIJH * 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(-) 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=, 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=) + 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=, 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