diff --git a/pkgs/applications/version-management/git-and-tools/git/default.nix b/pkgs/applications/version-management/git-and-tools/git/default.nix index 84af1a2fcbb23..aa0cb613bccb2 100644 --- a/pkgs/applications/version-management/git-and-tools/git/default.nix +++ b/pkgs/applications/version-management/git-and-tools/git/default.nix @@ -153,6 +153,7 @@ stdenv.mkDerivation { ''); enableParallelBuilding = true; + separateDebugInfo = true; meta = { homepage = http://git-scm.com/; diff --git a/pkgs/build-support/setup-hooks/separate-debug-info.sh b/pkgs/build-support/setup-hooks/separate-debug-info.sh index 518be96473342..d3a1ca9ed2854 100644 --- a/pkgs/build-support/setup-hooks/separate-debug-info.sh +++ b/pkgs/build-support/setup-hooks/separate-debug-info.sh @@ -1,19 +1,19 @@ export NIX_SET_BUILD_ID=1 -export NIX_LDFLAGS+=" --compress-debug-sections=zlib" -export NIX_CFLAGS_COMPILE+=" -ggdb -Wa,--compress-debug-sections" +export NIX_CFLAGS_COMPILE+=' -ggdb' dontStrip=1 fixupOutputHooks+=(_separateDebugInfo) _separateDebugInfo() { - local dst="${debug:-$out}" - if [ "$prefix" = "$dst" ]; then return; fi + local debugout="${debug:-$out}" + if [ "$prefix" = "$debugout" ]; then return; fi - dst="$dst/lib/debug/.build-id" + local hashandname="$(basename "$debugout")" + local debugpath="$(dirname "$debugout")/${hashandname:0:2} ${hashandname:2}" # Find executables and dynamic libraries. local i magic - while IFS= read -r -d $'\0' i; do + while read -r -d $'\0' i; do if ! isELF "$i"; then continue; fi # Extract the Build ID. FIXME: there's probably a cleaner way. @@ -25,11 +25,18 @@ _separateDebugInfo() { # Extract the debug info. header "separating debug info from $i (build ID $id)" - mkdir -p "$dst/${id:0:2}" - objcopy --only-keep-debug "$i" "$dst/${id:0:2}/${id:2}.debug" - strip --strip-debug "$i" - + local relpath="lib/debug/.build-id/${id:0:2}/${id:2}.debug" + local debugfile="$debugout/$relpath" + mkdir -p $(dirname "$debugfile") + objcopy --only-keep-debug --compress-debug-sections "$i" "$debugfile" # Also a create a symlink .debug. - ln -sfn ".build-id/${id:0:2}/${id:2}.debug" "$dst/../$(basename "$i")" + ln -sfn ".build-id/${id:0:2}/${id:2}.debug" "$debugout/lib/debug/$(basename "$i").debug" + + if ! objdump -sj .nix_debug "$i" &> /dev/null; then + # The space is to prevent a reference. + objcopy --add-section=.nix_debug=<(echo "$debugpath/$relpath") "$i" + fi + strip $commonStripFlags "$i" + done < <(find "$prefix" -type f -print0) } diff --git a/pkgs/development/libraries/glibc/common.nix b/pkgs/development/libraries/glibc/common.nix index a189edb9832df..a299d5e09e516 100644 --- a/pkgs/development/libraries/glibc/common.nix +++ b/pkgs/development/libraries/glibc/common.nix @@ -26,6 +26,7 @@ stdenv.mkDerivation ({ inherit (stdenv) is64bit; enableParallelBuilding = true; + separateDebugInfo = true; patches = [ /* Have rpcgen(1) look for cpp(1) in $PATH. */ diff --git a/pkgs/development/tools/misc/gdb/default.nix b/pkgs/development/tools/misc/gdb/default.nix index 472bb4de58b9e..c0b6486767232 100644 --- a/pkgs/development/tools/misc/gdb/default.nix +++ b/pkgs/development/tools/misc/gdb/default.nix @@ -1,5 +1,5 @@ { fetchurl, stdenv, ncurses, readline, gmp, mpfr, expat, texinfo, zlib -, dejagnu, perl, pkgconfig +, dejagnu, perl, pkgconfig, binutils, nix , python ? null , guile ? null , target ? null @@ -21,6 +21,8 @@ let stdenv.system == "i686-gnu" || (stdenv ? cross && stdenv.cross.config == "i586-pc-gnu"); + nixExtension = ./nix.py; + in assert isGNU -> mig != null && hurd != null; @@ -42,6 +44,7 @@ stdenv.mkDerivation rec { ++ stdenv.lib.optional doCheck dejagnu; enableParallelBuilding = true; + separateDebugInfo = true; configureFlags = with stdenv.lib; [ "--with-gmp=${gmp}" "--with-mpfr=${mpfr}" "--with-system-readline" @@ -64,6 +67,9 @@ stdenv.mkDerivation rec { postInstall = '' # Remove Info files already provided by Binutils and other packages. + sed '-es|"objcopy"|"${binutils}/bin/objcopy"|' \ + '-es|"nix-store"|"${nix.out}/bin/nix-store"|' \ + '${nixExtension}' > "$out/share/gdb/python/gdb/command/nix.py" rm -v $out/share/info/bfd.info ''; diff --git a/pkgs/development/tools/misc/gdb/nix.py b/pkgs/development/tools/misc/gdb/nix.py new file mode 100644 index 0000000000000..eb8530c03b3f3 --- /dev/null +++ b/pkgs/development/tools/misc/gdb/nix.py @@ -0,0 +1,67 @@ +import os +import subprocess + +import gdb + +_objects_without_symbols_loaded = set() + +def _new_objfile(event): + _load(event.new_objfile) + +gdb.events.new_objfile.connect(_new_objfile) + +def _clear_objfiles(event): + _objects_without_symbols_loaded.clear() + +gdb.events.clear_objfiles.connect(_clear_objfiles) + +def _get_debug_file_path(obj): + try: + out = subprocess.check_output([ + "objcopy", + "--dump-section=.nix_debug=/dev/stdout", + obj.filename, + "/dev/null", + ], stderr=subprocess.STDOUT) + if b"File in wrong format" in out: + # objdump isn't exiting with failure in this case. + return None + return str(out).replace(" ", "", 1).rstrip() + except: + return None + +def _load(obj): + debugfile = _get_debug_file_path(obj) + if not debugfile: + return + + try: + obj.add_separate_debug_file(debugfile) + gdb.write("Loaded symbols for {}.\n".format(obj.username)) + _objects_without_symbols_loaded.discard(obj) + except Exception as e: + _objects_without_symbols_loaded.add(obj) + gdb.write("Error loading debug symbols: {}\n".format(e)) + gdb.write("From: {}\n".format(debugfile, e)) + gdb.write("For: {}\n".format(obj.username)) + if not os.path.exists(debugfile): + gdb.write("The debug file doesn't exists.\n") + gdb.write("You can download missing debug files with 'nix-download-debug'.\n") + +def _download(objs): + debugfiles = [_get_debug_file_path(obj) for obj in objs] + subprocess.check_call(["nix-store", "-rk"] + debugfiles) + +class CommandNixDownloadDebug(gdb.Command): + def __init__(self): + super(CommandNixDownloadDebug, self).__init__("nix-download-debug", gdb.COMMAND_USER) + + def invoke(self, arg, from_tty): + assert not arg + try: + _download(_objects_without_symbols_loaded) + finally: + for obj in list(_objects_without_symbols_loaded): + _load(obj) + +CommandNixDownloadDebug() diff --git a/pkgs/tools/compression/xz/default.nix b/pkgs/tools/compression/xz/default.nix index 5d6a8634b1baa..d3d54c76d2a6a 100644 --- a/pkgs/tools/compression/xz/default.nix +++ b/pkgs/tools/compression/xz/default.nix @@ -10,6 +10,8 @@ stdenv.mkDerivation rec { outputs = [ "dev" "out" "bin" "man" "doc" ]; + enableParallelBuilding = true; + separateDebugInfo = true; doCheck = true; # In stdenv-linux, prevent a dependency on bootstrap-tools.