Bug 13442 - gold screws up exception handling with --incremental flag
Summary: gold screws up exception handling with --incremental flag
Status: ASSIGNED
Alias: None
Product: binutils
Classification: Unclassified
Component: gold (show other bugs)
Version: 2.22
: P2 normal
Target Milestone: ---
Assignee: Cary Coutant
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-11-26 23:32 UTC by Samuel Bronson
Modified: 2017-01-11 14:42 UTC (History)
3 users (show)

See Also:
Host: i486-linux-gnu
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Samuel Bronson 2011-11-26 23:32:34 UTC
For example, take this program:

% cat demo.cc
#include <exception>
#include <cstdio>

using namespace std;

main ()
{
    try {
        throw exception();
    }
    catch (exception &e) {
        printf("%s\n", e.what());
    }
}

// ------ 8< ------

and try this:

% g++ -o demo demo.cc -Wl,--incremental-full
% ./demo
terminate called after throwing an instance of 'std::exception'
  what():  std::exception
zsh: abort      ./demo


Versions and such:

% uname -a
Linux hydrogen 2.6.30-1-686 #1 SMP Sat Aug 15 19:11:58 UTC 2009 i686 GNU/Linux

% g++ --version
g++ (Debian 4.6.1-15) 4.6.1

% gold --version
GNU gold (GNU Binutils for Debian 2.22) 1.11

The C++ library also posesses Debian version 4.6.1-15.
Comment 1 Samuel Bronson 2012-02-11 00:13:53 UTC
Ping?
Comment 2 Cary Coutant 2012-02-11 00:24:30 UTC
Have you tried this with a recent linker? This should have been fixed with:

http://sourceware.org/ml/binutils/2011-09/msg00113.html
Comment 3 Samuel Bronson 2013-02-26 01:55:56 UTC
Doesn't work with this either:

naesten@hydrogen:..hacking/bugs/gold-incremental-exception% dpkg -l binutils-gold
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                Version        Architecture   Description
+++-===================-==============-==============-===========================================
ii  binutils-gold       2.23.1-1~exp6  i386           GNU gold linker utility
Comment 4 Espen Grindhaug 2014-11-12 12:40:59 UTC
This is still a problem in master from today (40e91bc71f7).
Comment 5 Espen Grindhaug 2014-11-12 13:44:49 UTC
Comparing with and without -Wl,--incremental-full i notice that when compiling with -Wl,--incremental-full the output binary is missing the .eh_frame_hdr section.
Comment 6 Espen Grindhaug 2014-11-14 08:13:28 UTC
After some further digging into libgcc and glibc (i'm no expert here!) it looks like the system expects to find the eh_frame_hdr section. As far as i can tell the problem then lies here:

layout.cc:1522

void
Layout::add_eh_frame_for_plt(Output_data* plt, const unsigned char* cie_data,
			     size_t cie_length, const unsigned char* fde_data,
			     size_t fde_length)
{
  if (parameters->incremental())
    {
      // FIXME: Maybe this could work some day....
      return;
    }
Comment 7 Cary Coutant 2014-11-15 00:04:53 UTC
Incremental linking deliberately disables the --eh_frame_hdr option, because of the difficulty involved in incrementally updating it. It could be rebuilt from scratch on each incremental update, but I have no plans to work on that in the near future.
Comment 8 Espen Grindhaug 2014-12-08 17:00:41 UTC
(In reply to Cary Coutant from comment #7)
> Incremental linking deliberately disables the --eh_frame_hdr option, because
> of the difficulty involved in incrementally updating it. It could be rebuilt
> from scratch on each incremental update, but I have no plans to work on that
> in the near future.

I will try to figure this out myself then. How hard can it be? :-P

Does gold correctly incrementally update the eh_frame section today, so that it is just the eh_frame_hdr that is missing?
Comment 9 Cary Coutant 2015-03-12 22:16:35 UTC
> Does gold correctly incrementally update the eh_frame section today, so that
> it is just the eh_frame_hdr that is missing?

It does, but there's a severe restriction -- the updated pieces of .eh_frame must fit exactly into their old spots. There's no support for adding patch space or leaving holes in the .eh_frame section.

For debug info, we do try to make the patch space look like an empty compile unit, and when we have to leave holes, we make sure they're large enough that we can forge a dummy compile unit to fill the space. If you want to tackle this, take a look at how we handle .debug_info for examples.
Comment 10 Matt Godbolt 2017-01-11 14:42:37 UTC
On a whim I tried incremental linking on our existing large codebase and hit this exact same problem.

This happens with Ubuntu 14.04's default g++ 4.8.4 and gold 1.11 (binutils 2.24) reproduced using Samuel's steps (adding -fuse-ld=gold).

It also happens with a custom-built GCC 6.3.0 with an in-tree build of gold (binutils 2.26, gold 1.11) - though in order to get around the plugin support built into this build the repro case needs -fno-lto too.