FS#10975 - Add support for separated packages with debug symbols to makepkg (patch included)
Attached to Project:
Pacman
Opened by Jan M. (funkyou) - Monday, 21 July 2008, 22:39 GMT
Last edited by Allan McRae (Allan) - Tuesday, 27 November 2012, 06:09 GMT
Opened by Jan M. (funkyou) - Monday, 21 July 2008, 22:39 GMT
Last edited by Allan McRae (Allan) - Tuesday, 27 November 2012, 06:09 GMT
|
Details
Hi there,
today i sat down and wrote another patch for makepkg, this time to create separate packages with debug symbols automatically... As Arch is a distro that "keeps it upstream" it should be an easy thing to create backtraces and report bugs, at least theoretically :) But then all the nice debug symbols are stripped by default which makes it a bit of a hassle to get some proper debug info, especially if you must rebuild a whole set of packages, as its sometimes not just done with rebuilding one package with debug info... For example, if you want to have some kde-related stuff with debug info, you need also to rebuild at least kdelibs and kdebase (and maybe even Qt) ... As this is just too much hassle and not optimal(tm), i just thought "this must be stopped" and created this patch :) HOW ITS DONE (the theory): -------------------------- "GDB allows you to put a program's debugging information in a file separate from the executable itself, in a way that allows GDB to find and load the debugging information automatically. Since debugging information can be very large--sometimes larger than the executable code itself, some systems distribute debugging information for their executables in separate files, which users can install only when they need to debug a problem." Ok, that sounds nice, but how do we do it? Its easy... Lets take an executable file like "ls" and compile it with debug info... Then we use objcopy to move only the debug symbols into a new file. This happens with "objcopy --only-keep-debug $file $file.debug" ... This creates "$file.debug" which holds all debugging symbols... The second step is to strip the file as we already do in arch, by using "strip" for executables and "strip --strip-debug" for shared libraries, because we have now the symbols in another file and dont need them anymore... As the last step, gdb must know if a file has its debug symbols in a separated file... For this we use objcopy again on the file and add the "debug link flag" to it which points to the file(name): "objcopy --add-gnu-debuglink=$file.debug $file" (As a sidenote: You cant use a full path with the "--add-gnu-debuglink" parameter, but just the name of the file _and_ the debug file must be available for objcopy. This means that you must create the .debug file in the same path as the executable/library and move the .debug file elsewhere afterwards, because otherwise it will not work later...) Finally, when using gdb on such files, it looks into the following directories for .debug files (example for "ls"): `/bin/ls.debug' `/bin/.debug/ls.debug' `/usr/lib/debug/bin/ls.debug' MAKEPKG IMPLEMENTATION: ----------------------- The implementation in makepkg is pretty easy and lightweight... At first there is another option called "splitdebug" in makepkg.conf which can be used only together with the "strip" option, so both need to be enabled to create debug packages... Then we just need another directory in $startdir, where the .debug files will be placed. In the patched version this directory is called $startdir/dbg. To create the .debug files, i have modified the strip stuff in tidy_install() and added another function for creating the debug package called create_debug_package()... create_debug_package() is a stripped-down copy of create_package(), with lesser stuff added to the .PKGINFO (like groups or the install file, we dont need that for debug symbols) and it also adds the -debug suffix to the package name automatically... Before calling create_package(), there are two new checks for the "strip" and "splitdebug" options. If both are enabled, create_debug_package() will be called after create_package() to package the generated debug symbol files... The .debug files are placed into the same directory as their executables. In my opionion, this is the easiest and KISSest way to deal with it... Other distros use "/usr/lib/debug/THE/FULL/PREFIX/$FILE" for that, but i think thats just overkill... HOW TO TEST IT: --------------- Just use the attached makepkg, enable the "strip" option in makepkg.conf and also add "splitdebug" to the options array... Then run makepkg on any package you like... This should create 2 packages: $package and $package-debug... To test it with gdb: Install both packages, run gdb, open a executable file from the package inside gdb ("file /path/file") and it should load and find the debug symbols automatically... DISADVANTAGES: -------------- So far none, at least for me :) The implementation in tidy_install() could be a bit cleaner, but i dont know how to do it and would like to see some feedback about this - especially on the way how i handle the "objcopy --add-gnu-debuglink" stuff, as it needs to be done in the same directory as the file + file.debug... The size of the -debug packages could be an issue. It varies from package to package, from about 5% (for kdesvn) to over 70% (for amarok-base) of the original package... Also notice that will not decrease performance in any way, as the binaries are still stripped like before... Please test this stuff and give me some feedback, thanks! Greetings Jan |
This task depends upon
Closed by Allan McRae (Allan)
Tuesday, 27 November 2012, 06:09 GMT
Reason for closing: Implemented
Additional comments about closing: In git - many patches culminating in 254329f6
Tuesday, 27 November 2012, 06:09 GMT
Reason for closing: Implemented
Additional comments about closing: In git - many patches culminating in 254329f6
A few comments:
1) I think that a flag for makepkg be better than specifying an option in the PKGBUILD.
2) If we stick with using an option, we could have splitdbg/dbgpkg or whatever the option gets called imply strip. In fact, either way, a single check early on the these options/flag don't conflict would save a lot of multiple testing afterward.
3) I like using /usr/lib/debug much more than having debug files along side their counterparts in the filesystem. It just seems cleaner. Also, that allows configuring the path (as you can changing it in gdb). e.g think about what setting the path to "/" would achieve. :)
My only qualm is... this seems like something that can be more generalized with all the different "split packages" ideas floating around. Perhaps integration with some of that would make this a much cooler idea.
Allan, thanks for your suggestions, they are quite legit for me and definitely an improvement. I will rework the patch when i have time (could take a bit) and post an updated version here...
Aaron, this patch has nothing to do with splitting packages. It does not even split anything but just creates a second package containing all the symbols. Just take a look at the diff, its pretty self-explaining...
When i am on it, i will also combine it with our splitpkg patch from KDEmod, that should be an easy job... But again, this patch has nothing to do with splitting packages :-)
FS#10976.With that said, I think Allan is going to round up the challengers post-3.2 and try to get something we can mostly all agree on.
- debug symbols are now placed in /usr/lib/debug
- there is a new flag (-t|--splitdbg) to enable -debug packages
- the makepkg.conf option got renamed to "splitdbg". Using "dbgpkg" for that was just too prone for typos ;)
- you can now freely combine/use the flag and the "strip" and "splitdbg" options in makepkg.conf, it will always work as intended
- there is now a check if any .debug files have been created. This is important for stuff like wallpaper packages or so which contain no binaries. The former version just created an empty -debug package in that case
Its still hackish, as i am not a bash pro at all, but it works fine for me so far. If you have any suggestions, i would be happy to read them...
About splitting packages: I have also combined the patch with our splitpkg stuff. I know that this is just one of many ways to split pkgs, but i wanted to have a working solution _now_, as i intend to use that on the KDEmod packages... If there is any interest in these patches, they are currently located here: http://www.kdemod.ath.cx/svn/work/kde41-move-it-to-usr/_buildsystem/patches/
Basically I like the idea (but I didn't check your implementation).
So far i have tested split & "normal" pkgs and repackaging. It works fine.
Again: this is more a quick hack that basically works and does the job for me, and not a real proper implementation ;)
One of the biggest pains in the ass is not having easy access to debug symbols.
What is holding this up? (I would like to help, if there is anything I can do.)
I would strongly request, devs to rethink the current policy of not carring -debug packages in repos. Because its "Anti-upstream".
makepkg-splitdbg2.patch (5.3 KiB)
+ depends=($pkgname)
should be depends=($pkgname-$pkgver-$pkgrel)
+ provides=${provides/%/-dbg}
+ conflicts=${conflicts/%/-dbg}
These are not needed in my opinion.
replaces=()
There is an obvious problem with this when dealing with packages with hard linked binaries (git for example). A solution would be to not generate debug packages for these, or to add a check in order to not strip an already stripped binary.
Suppose a package has /usr/bin/prog1 and /usr/bin/prog2 which are the same inode. Then prog1 will be stripped, giving
/usr/lib/debug/usr/bin/prog1.debug
and the .gnu_debuglink section of prog1 (hence prog2) will contain "prog1.debug".
Then prog2 will not be stripped, as it already contains a .gnu_debuglink section. But if gdb is used on prog2, since it is .gnu_debuglink-ed to prog1.debug, it will indeed find the debug symbols in /usr/lib/debug/usr/bin/prog1.debug
I suspect it will not work if hardlinked files are not in the same directory. Gentoo has a much more robust way to deal with this, but given that it will be seldom needed, it may be best to "Keep It Simple".
Here is a new patch for makepkg, which I tested with the git package. Note that git-fetch and git-merge-ours are the same file.
% SPLIT_DBG=1 makepkg.new -f
% sudo pacman -U git-1.7.1.1-1-i686.pkg.tar.gz git-dbg-1.7.1.1-1-i686.pkg.tar.gz
% gdb /usr/lib/git-core/git-fetch
GNU gdb (GDB) 7.1
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /usr/lib/git-core/git-fetch...Reading symbols from /usr/lib/debug/usr/lib/git-core/git-merge-ours.debug...done.
done.
(gdb) quit
For the hard link issue, check how we handle compressing man pages in makepkg. That might give you a hint on how to handle them.
For example, if /bin/prog and /usr/bin/prog2 are hard linked, and we create /usr/lib/debug/bin/prog.debug, then this should be hardlinked to /usr/lib/debug/usr/bin/prog.debug (and not prog2.debug). Of course, another name prog2.debug could be created for user-friendliness, but it would not be used. The only package I have here using off-directory hardlinks is glibc, which has /usr/bin/getconf and /usr/lib/getconf/*, and its PKGBUILD manually strips files, I don't have a suitable PKGBUILD for testing this case (of course I could forge one...).
backup=()
in the create_dbgpackage() function.
They seem to provide KDE debug packages as an option.
http://chakra-project.org/news/index.php?/archives/112-KDE-Debug-Packages.-Its-time-to-contribute-to-KDE-!.html
I really need to sit down and do some makepkg patch reviewing...
The main idea is that debug packages will be added to pkgname array and for each of it package_<name>-dbg function will be created. So it treated like usual split packages.
Tested on split and non-split packages. All seems to work fine.
Is the latest patch submitted by Vitaliy good enough to be implemented?
It would be nice to have this so we could have split debuging packages.
You can follow discussion about this patch here http://mailman.archlinux.org/pipermail/pacman-dev/2011-August/014023.html.
It was never reviewed by Allan but according to last reviwing from Dave Reisner it still has some issues with portability.
Due to lack of attention here I kind of give up it and now I unlikely find time to continue work on it.
The last version of patch in the mail list contains error.
eval "package ..." should be replaced by eval "function package ...".
Unfortunately I did this last change in hurry and didn't test it.
I just hope my work can be useful in future here.
did I understand Dave Reisner's comment correctly that makepkg is supported for other platforms too? I understood Dave Reisner correctly makepkg also supported on OSX and cygwin?
Wouldn't it be possible to make the code for building debug packages platform specific: If the compiler is gcc and objectdump and readelf exist allow building of debug packages, in all other cases ignore the flag.
When a Build ID is 717dddecd8a7c928c72d4c0afe14bdf58ad0783d
gdb will look here:
/usr/lib/debug/.build-id/71/7dddecd8a7c928c72d4c0afe14bdf58ad0783d.debug
regardless of path etc.
So with a little bit of parsing you can do this quick and dirty in 5 lines of bash or so, assuming you reuse the strip loop in makepkg and don't bother with seperate packages.
Adding something similar to following to makepkg should do: (requires eu-strip from elfutils, if using strip will require a slightly longer step)
file="<filename>"
bldid=$(file -n -b $file | grep -o -E '0x[a-f0-9]+')
dir="${bldid:2:2}"
mkdir -p $pkgdir/usr/lib/debug/$dir/
eu-strip -f $pkgdir/usr/lib/debug/$dir/${bldid:4:-1}.debug $file
Heres how it looks in valgrind for anyone who cares:
--3123-- Reading syms from /lib/ld-2.14.1.so (0x4000000)
--3123-- Considering /usr/lib/debug/.build-id/68/e0fd99cfe47a0d6c2d0e3c272dfb33558dfef6.debug ..
--3123-- .. build-id is valid
....
--3123-- Reading syms from /lib/libc-2.14.1.so (0x4e2f000)
--3123-- Considering /usr/lib/debug/.build-id/d7/ea87cfa3d875b8a290aa2fb7d2146f73494ef5.debug ..
--3123-- .. build-id is valid
etc.
I used /usr/bin/objcopy --compress-debug-sections --only-keep-debug
instead of eu-strip.
"--12370-- Reading syms from /usr/bin/rtorrent (0x400000)
--12370-- Considering /usr/lib/debug/.build-id/a1/ec3cc04fa376fca521981919430eb4776ad1c6.debug ..
--12370-- .. build-id mismatch (found (null) wanted a1ec3cc04fa376fca521981919430eb4776ad1c6)
--12370-- object doesn't have a symbol table
"
Heres a really shitty function I made that seems to work just fine.
I incorporated this into the strip loop since I don't really care about disk space.
Note that I have no clue about how bash works, so I'm pretty sure it could be a lot nicer.
seperate_debuginfo() {
local elf="$1"
local bldidx=$(/usr/bin/readelf -n $elf | /bin/grep "Build ID")
local bldid=${bldidx:14:40}
if [[ $bldid ]]; then
local short=${bldid:0:2}
#echo "Splitting up debug symbols: ELF: $elf -> Build ID: $bldid"
if [[ ! -d usr/lib/debug/.build-id/$short ]]; then
/bin/mkdir -m 0755 -p "usr/lib/debug/.build-id/$short"
fi
local new_build_id=${bldid:2:40}
/usr/bin/objcopy --compress-debug-sections --only-keep-debug $elf "usr/lib/debug/.build-id/$short/$new_build_id.debug"
fi
}
You probably want to fix the hardcoded paths before trying it.
I mean its not a "nice to have feature" it something like essential to fix bugs. Right now i have to start a virtual machine (or my gentoo on the second partition) if i find a bug while running archlinux only because other distros have debug symbols.
I doubt that everyone is willing to have a second system with the same software just to report bugs, also this is _not_ KISS, KISS would be if pacman would have the ability to deliver debug packages.
To build them your own (especially with KDE) is some kind of unuseable and the opposite of KISS
This Bug is opened since 2008 and really should finally be fixed
https://projects.archlinux.org/users/allan/pacman.git/log/?h=working-split/debug
And as a KDE developer I really hope Arch starts shipping debug symbols, but still; thanks a bunch for this. :)
+# Help line for debug package suffix
+AC_ARG_WITH(debug-suffix,
+ AS_HELP_STRING([--with-debux-suffix=name], [set the suffix for split debugging symbol packages used by makepkg]),
+ [DEBUGSUFFIX=$withval], [DEBUGSUFFIX=debug])
+1 for inclusion of debugging packages in arch, hitting a specific bug and not being able to get a meaningful backtrace (even with recompiling) is not cool.
Please leave the discussion about debugging packages in Arch Linux out of this report. This bug is for tracking the implementation in pacman only.
Edit: sorry for the noise, I clearly can't read the issue status :/.