2016-04-13 8 views
3

私は共有オブジェクトとしてコンパイルされた大きなプロジェクトを扱っています。 DWARF-2シンボル(-g -feliminate-unused-debug-types)でコンパイルすると、.debug_infoは約700Mになります。DWARF-2重複シンボルを削除するとメモリが枯渇する

私は-feliminate-dwarf2-dupsを追加する場合、リンカは死ぬ:

error adding symbols: Memory exhausted 
ld returned 1 exit status 

これは4GのRAMを搭載したシステムです。これは広範囲のシステムでコンパイルする必要があるため、4G RAMを消費することは受け入れられません。 --no-keep-memoryldに渡そうとしましたが、それでも失敗します。

ldは通常、入力ファイルのシンボルテーブルをメモリにキャッシュすることで、メモリ使用量のスピードを最適化します。このオプションは、必要に応じてシンボルテーブルを再読み込みすることによって、代わりにldにメモリ使用量を最適化するよう指示します。これは、大きな実行可能ファイルをリンクしているときにldがメモリ領域を使い果たした場合に必要になることがあります。

私はld負荷にメモリ内のすべてのシンボルを推測している、それはディスク上に格納するのにかかる5+倍のメモリを取るdupesを、見つけることについて行きます。

これを段階的に行う簡単な方法はありますか?以下のような:任意の重複削除する最初の.oファイルから

  1. ロードのシンボル次の.oファイル
  2. からのシンボルは、それらをマージ
  3. ロード、
  4. 後藤2.

私ができますファイルを2つずつ一時アーカイブにリンクし、それらを2つなどにリンクしますが、私ははこのプロジェクトのビルドプロセスを変更したくありません。たぶん私はobjcopyこれらのセグメントを削除するために使用することができます、別々に二重排除を実行し、最後のELFにデバッグセクションを挿入?

これらのDWARFマージを実行できるツールはありますか? dwarfdumpはファイルのみを読み取ります。あるいは、実際にファイルをリンクするのではなく、gcc/ldを呼び出すだけでいいですか?

+1

一緒にリンクされている小さなプロジェクトに分割することはできますか? – OMGtechy

+0

@OMGtechyそれは独自のプロジェクトです。 CFLAGSを追加するだけでなく、makeプロセスのいくつかの場所で小さなツールを動かすだけで1ヶ月以上の作業が必要になります。 – mtijanic

+0

http://stackoverflow.com/questions/1413171/what -is-strip-gcc-application-used-forのいずれかを使用して、重複したシンボルを削除するか、b)不要なものを削除して問題のサイズを小さくするかを確認してください。 – OMGtechy

答えて

3

私はDWARFサイズを減らすために2つの方法を知っています。あなたが望むものは、あなたの意図する目的によって異なります。

dwzツールを使用してDWARFを圧縮しているFedora(と多分他のディストリビューションもあります)。これは実際にはあなたのプログラムや共有ライブラリをリンクしてからdwzを実行した後に機能します。それは意味論的なコンプレッサーです。つまり、DWARFを理解してより小さなフォームに書き換えます。 DWARF用語では、部分的なCUを作成し、そのようにデータを共有します。 dwzには、より多くの共有のために異なる実行可能ファイル間でデータを圧縮できるモードもあります。

dwzが最良の圧縮を生成します。主な欠点は、開発者のワークフローにはうまく適合しないことです。少し遅く、メモリを大量に使用します。ディストリビューションには最適です。他の展開状況には適していると思います。

debuginfoを圧縮するもう1つの方法は、gccに-fdebug-types-sectionフラグを使用することです。これはDWARF出力を変更して、大きな型をそれぞれのセクションに入れます。型は内容によってハッシュされます。リンカはこれらのセクションを自動的にマージします。

タイプがDWARFのかなりの部分であるため、このアプローチでは適切な圧縮が得られます。リンカでこのように同じセクションをマージするのは安価です。大きな欠点は圧縮があまり良くないということです。

gdbは、これらの種類の圧縮の両方を理解しています。他のツールでのサポートは少しばかげています。

+0

ありがとうございます。私は目の前で終わりのない過去1時間の 'dwz'を実行していたので、それは解決策ではありません。それが最終結果として何を生み出すのか見たいので、私は何を目標にするのか知っています。次に '-fdebug-types-section'を試してみましょう。どうやら、それはDWARF-4用ですが、多分それはうまくいくでしょう。 – mtijanic

+0

binutils 2.26でサポートされている圧縮デバッグセクションもあります。 – dbrank0

+0

FYI: 'dwz'と' -fdebug-types-section'はビルドマシンが十分に強力なときにうまく動作します。しかし、私がサポートしなければならないさまざまなハードウェアでは、時間がかかりすぎるか、クラッシュするだけです。私はあなたのハードウェアが十分であるかどうかを確認するためのチェックを追加し、そうであれば実行することができます。 – mtijanic

2

Tom Tromeyの提案に加えて、あなたが行うことができるもう1つの方法は、例えばクロスコンパイラをビルドすることです。 x86_64システムで、さまざまなシステムをすべてターゲットにしています。

これはリンカメモリの4GB制限を完全に排除し、より高速である可能性があります(幅広い種類の小型システムにはおそらくwimpy CPUが搭載されている可能性があるため、ネイティブにビルドするには、分だけかかる)。

また、-fsplit-dwarfを使用することもできます。最終共有ライブラリにデバッグビットをリンクする必要はありません。それらを別々に保つことができます。

更新:

我々はすでにcrosscompilersを使用して行います。問題は、ビルドマシンに使用するすべてのx86_64システムが、これを最適化するのに十分強力であるとは限りません。その場合

、あなたはハード 4GBの要件はありませんし、これは受け入れられないことを、あなたの主張は偽です。約500ドルで64GBのRAMが得られ、すべての速度を上げることができます。

開発者は、開発者は、あなたが自分の時間を無駄にしている、16ギガバイト未満でプライマリシステムを持っている場合は、その次システム

上でビルドを実行することをお勧めします。

-fsplit-ドワーフ、私はまだ同様のシンボルをダウンロードする必要があると思いリモートで構築されている場合にについて

、そう

ゲインを得ることがほとんどありませんが、あなたができることですバイナリをビルドします。スプリットデバッグ情報と一緒にhttps://en.wikipedia.org/wiki/Gold_(linker)また

金リンカが私のために非常によく働いた:

+0

すでにクロスコンパイラを使用しています。問題は、ビルドマシンに使用するすべてのx86_64システムが、これを最適化するのに十分強力であるとは限りません。さらに、開発者はプライマリシステムでビルドを実行しながら、何か他のことをしたいことがあります。ビルド全体が今まで2GのRAMを使い、突然8が必要になった場合、私は全員のワークフローを破ります。 '-fsplit-dwarf'に関しては、リモートでビルドされている場合でも、シンボルをダウンロードする必要がありますので、得ることはほとんどありません。 – mtijanic

+0

@mtijanic私は答えを更新しました。 –

+0

「4GBのハードな要件はありません」ということは、更新が必要な何百ものマシンがあり、かなり野心的(そして高価)です。私はちょうど決めることができない何か。 「開発者が16GB未満のプライマリシステムを使用している場合、時間を無駄にしています。彼らはまた、ブラウザ、エディタ、オフィスツール、その他のものを実行しています。 "利益はバイナリを構築できるということです。"私はまだできます、それはちょうど巨大です。私はサイズのために*最適化できません。いずれにしても、すべての最適化にスイッチを使用し(dupsを削除する、圧縮する、分割する)、各マシンの所有者に決定させることになります。ありがとう! – mtijanic

1

はまあ、しようとする他の事は、それはより速く/より良い、リンクかもしれない大規模なアプリケーションを構築するための「ゴールド」のリンカーを使用することです。

「核分裂がGCC 4.7で実装され、objcopyを金リンカーの最近のバージョンからのサポートを必要とされる。

使用-gsplit-ドワーフオプションをコンパイル時分割DWARFの生成を可能にする。このオプションが必要

ゴールドリンカーの--gdb-indexオプション(gccまたはg ++とリンクする場合は-Wl、-gdb-indexオプションを使用してください)を使用してください。 )リンク時に、.gdb_indexセクションを作成します。あなたがそれを必要とするので、2つのファイルを作成する必要があります。 "

+0

私は次に「金」を試してみましょう。それは私が必要とするものだけかもしれません。同じコードがカーネルモジュールにリンクされることもあり、 'gold'はそれを行うことはできませんが、ここでは例外を作ることに問題はありません。カーネルモジュールのインフラにはすでに700Mのシンボルを処理する方法があります。 – mtijanic

+0

@mtijanicそれは明らかにデータのレイアウトをもう少しキャッシュフレンドリーなものにしてくれた私の方がやや速かった。http://stackoverflow.com/questions/30010588/is-binary-linked-with-gold-linker-running-faster –

+0

@mtijanicリンカーが高速であるだけでなく、金リンカーで作成されたアプリケーションも少し速く、混乱して申し訳ありません。 –

関連する問題