From 93c333895a4e2dc9baabec8ade60d9d2ac0a91e2 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Tue, 21 Aug 2018 22:39:41 +0200 Subject: grafts: Add (guix build debug-link) and use it. Fixes . Reported by Mark H Weaver . * guix/build/debug-link.scm: New file. * guix/build/graft.scm (%graft-hooks): New variable. (graft): Add #:hooks and honor it. * guix/grafts.scm (graft-derivation/shallow): Add (guix build debug-link) and (guix elf) to #:modules. * tests/debug-link.scm: New file. * Makefile.am (MODULES): Add guix/build/debug-link.scm. (SCM_TESTS): Add tests/debug-link.scm. --- tests/debug-link.scm | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 tests/debug-link.scm (limited to 'tests/debug-link.scm') diff --git a/tests/debug-link.scm b/tests/debug-link.scm new file mode 100644 index 0000000000..2dde3cb460 --- /dev/null +++ b/tests/debug-link.scm @@ -0,0 +1,158 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2018 Ludovic Courtès +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see . + +(define-module (test-debug-link) + #:use-module (guix elf) + #:use-module (guix build utils) + #:use-module (guix build debug-link) + #:use-module (guix gexp) + #:use-module (guix store) + #:use-module (guix tests) + #:use-module (guix monads) + #:use-module (guix derivations) + #:use-module (gnu packages bootstrap) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-26) + #:use-module (srfi srfi-64) + #:use-module (rnrs io ports) + #:use-module (ice-9 match)) + +(define %guile-executable + (match (false-if-exception (readlink "/proc/self/exe")) + ((? string? program) + (and (file-exists? program) (elf-file? program) + program)) + (_ + #f))) + +(define read-elf + (compose parse-elf get-bytevector-all)) + +(define %store + (open-connection-for-tests)) + +(define-syntax-rule (test-assertm name exp) + (test-assert name + (run-with-store %store exp + #:guile-for-build (%guile-for-build)))) + + +(test-begin "debug-link") + +(unless %guile-executable (test-skip 1)) +(test-assert "elf-debuglink" + (let ((elf (call-with-input-file %guile-executable read-elf))) + (match (call-with-values (lambda () (elf-debuglink elf)) list) + ((#f #f) ;no '.gnu_debuglink' section + (pk 'no-debuglink #t)) + (((? string? file) (? integer? crc)) + (string-suffix? ".debug" file))))) + +;; Since we need %BOOTSTRAP-GCC and co., we have to skip the following tests +;; when networking is unreachable because we'd fail to download it. +(unless (network-reachable?) (test-skip 1)) +(test-assertm "elf-debuglink" + ;; Check whether we can compute the CRC just like objcopy, and whether we + ;; can retrieve it. + (let* ((code (plain-file "test.c" "int main () { return 42; }")) + (exp (with-imported-modules '((guix build utils) + (guix build debug-link) + (guix elf)) + #~(begin + (use-modules (guix build utils) + (guix build debug-link) + (guix elf) + (rnrs io ports)) + + (define read-elf + (compose parse-elf get-bytevector-all)) + + (setenv "PATH" (string-join '(#$%bootstrap-gcc + #$%bootstrap-binutils) + "/bin:" 'suffix)) + (invoke "gcc" "-O0" "-g" #$code "-o" "exe") + (copy-file "exe" "exe.debug") + (invoke "strip" "--only-keep-debug" "exe.debug") + (invoke "strip" "--strip-debug" "exe") + (invoke "objcopy" "--add-gnu-debuglink=exe.debug" + "exe") + (call-with-values (lambda () + (elf-debuglink + (call-with-input-file "exe" + read-elf))) + (lambda (file crc) + (call-with-output-file #$output + (lambda (port) + (let ((expected (call-with-input-file "exe.debug" + debuglink-crc32))) + (write (list file (= crc expected)) + port)))))))))) + (mlet* %store-monad ((drv (gexp->derivation "debuglink" exp)) + (x (built-derivations (list drv)))) + (call-with-input-file (derivation->output-path drv) + (lambda (port) + (return (match (read port) + (("exe.debug" #t) #t) + (x (pk 'fail x #f))))))))) + +(unless (network-reachable?) (test-skip 1)) +(test-assertm "set-debuglink-crc" + ;; Check whether 'set-debuglink-crc' successfully updates the CRC. + (let* ((code (plain-file "test.c" "int main () { return 42; }")) + (debug (plain-file "exe.debug" "a")) + (exp (with-imported-modules '((guix build utils) + (guix build debug-link) + (guix elf)) + #~(begin + (use-modules (guix build utils) + (guix build debug-link) + (guix elf) + (rnrs io ports)) + + (define read-elf + (compose parse-elf get-bytevector-all)) + + (setenv "PATH" (string-join '(#$%bootstrap-gcc + #$%bootstrap-binutils) + "/bin:" 'suffix)) + (invoke "gcc" "-O0" "-g" #$code "-o" "exe") + (copy-file "exe" "exe.debug") + (invoke "strip" "--only-keep-debug" "exe.debug") + (invoke "strip" "--strip-debug" "exe") + (invoke "objcopy" "--add-gnu-debuglink=exe.debug" + "exe") + (set-debuglink-crc "exe" #$debug) + (call-with-values (lambda () + (elf-debuglink + (call-with-input-file "exe" + read-elf))) + (lambda (file crc) + (call-with-output-file #$output + (lambda (port) + (write (list file crc) port))))))))) + (mlet* %store-monad ((drv (gexp->derivation "debuglink" exp)) + (x (built-derivations (list drv)))) + (call-with-input-file (derivation->output-path drv) + (lambda (port) + (return (match (read port) + (("exe.debug" crc) + (= crc (debuglink-crc32 (open-input-string "a")))) + (x + (pk 'fail x #f))))))))) + +(test-end "debug-link") -- cgit v1.2.3