Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ stdenv.mkDerivation {
'');

enableParallelBuilding = true;
separateDebugInfo = true;

meta = {
homepage = http://git-scm.com/;
Expand Down
29 changes: 18 additions & 11 deletions pkgs/build-support/setup-hooks/separate-debug-info.sh
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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 <original-name>.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)
}
1 change: 1 addition & 0 deletions pkgs/development/libraries/glibc/common.nix
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ stdenv.mkDerivation ({
inherit (stdenv) is64bit;

enableParallelBuilding = true;
separateDebugInfo = true;

patches =
[ /* Have rpcgen(1) look for cpp(1) in $PATH. */
Expand Down
8 changes: 7 additions & 1 deletion pkgs/development/tools/misc/gdb/default.nix
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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;
Expand All @@ -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"
Expand All @@ -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
'';

Expand Down
67 changes: 67 additions & 0 deletions pkgs/development/tools/misc/gdb/nix.py
Original file line number Diff line number Diff line change
@@ -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()
2 changes: 2 additions & 0 deletions pkgs/tools/compression/xz/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down