質問

GCC 2.6.0に基づいてレガシーコンパイラを使用して、まだ使用している古い埋め込まれたプロセッサのクロスコンパイルを使用しています(はい、1994年以来まだ使用されています!)。このチップのためにGCCポートを行ったエンジニアは、それ以来ずっと進んでいます。 Web上のどこかからGCC 2.6.0のソースを回復できるかもしれませんが、このチップの変更セットは企業史のホールで消えました。コンパイラがまだ実行され、実行可能な実行可能ファイルを作成したため、最近まで混乱していましたが、Linuxカーネル2.6.25(および2.6.26)の時点では、メッセージで失敗します。 gcc: virtual memory exhausted...パラメーターなしで、またはのみで実行された場合でも -v. 。 2.6.24カーネルとコンパイラの動作を使用して、開発システム(2.6.26から)を再起動しました(2.6.25で再起動することはできません)。

このチップのビルドを行う目的で2.6.24に保持しているシステムが1つありますが、Linuxの世界が実行されるシステムを再構築できなくなった場合に備えて、少し露出していると感じています。コンパイラ(つまり、2.6.24システムが死亡し、いくつかのソフトウェアパーツが利用できなくなったため、2.6.24を新しいシステムにインストールして実行することはできません)。

このレガシーコンパイラを実行するために、より近代的なインストールにできることについて、誰かがアイデアを持っていますか?

編集:

いくつかのコメントに答えるために...

悲しいことに、失われたチップに固有のソースコードの変更です。この損失は、2つの主要な企業ReorgsといくつかのSysadmins(いくつかの大部分が本当に混乱を残しました)で発生しました。現在、構成制御を使用していますが、この問題には遅すぎる納屋のドアを閉めることです。

VMの使用は良いアイデアであり、私たちが最終的にやっていることかもしれません。その考えをありがとう。

最後に、Ephemientが提案したようにStraceを試してみて、最後のシステムコールはBrk()であり、新しいシステム(2.6.26カーネル)でエラーを返し、古いシステム(2.6.24カーネル)で成功を返しました。これは、TCSHの「制限」が古いシステムと新しいシステムで同じ値を返すことを除いて、私が実際に仮想メモリを使い果たしていることを示しています。 /Proc /Meminfoは、新しいシステムがわずかに多くのメモリとかなりの交換スペースを持っていることを示しています。多分それは断片化の問題ですか、それともプログラムがロードされている場所ですか?

私はさらに調査を行い、「BRKランダム化」がカーネル2.6.25に追加されましたが、 CONFIG_COMPAT_BRK デフォルトで有効になっていると思われます(BRKランダム化を無効にします)。

編集:

わかりました、詳細:BRKランダム化は原因であるように見えます。GCCがBRK()を呼び出してデータセグメントの終了を変更し、現在失敗し、レガシーGCCが「仮想メモリが排出された」と報告します。 BRKランダム化を無効にするいくつかの文書化された方法があります。

  • sudo echo 0 > /proc/sys/kernel/randomize_va_space

  • sudo sysctl -w kernel.randomize_va_space=0

  • で新しいシェルを開始します setarch i386 -R tcsh (または "-r -l")

私はそれらを試してみましたが、Brk()戻り値がそれらのない(そして常に同じ)という点で効果があるようです(カーネル2.6.25と2.6.26の両方で試しました)が、brk()まだ失敗するので、レガシーGCCはまだ失敗します:-(。

さらに、設定しました vm.legacy_va_layout=1vm.overcommit_memory=2 変更なしで、私はで再起動しました vm.legacy_va_layout=1kernel.randomize_va_space=0 /etc/sysctl.confに保存された設定。まだ変更はありません。

編集:

使用 kernel.randomize_va_space=0 カーネル2.6.26(および2.6.25)では、次のBRK()コールが報告されています。 strace legacy-gcc:

brk(0x80556d4) = 0x8056000

これは、brk()が失敗したことを示しますが、データセグメントがすでに要求されたものを超えて終了するため、失敗したようです。 objdumpを使用すると、データセグメントが0x805518cで終了するはずですが、故障したbrk()は、データセグメントが現在0x8056000で終了することを示しています。

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .interp       00000013  080480d4  080480d4  000000d4  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .hash         000001a0  080480e8  080480e8  000000e8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .dynsym       00000410  08048288  08048288  00000288  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .dynstr       0000020e  08048698  08048698  00000698  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .rel.bss      00000038  080488a8  080488a8  000008a8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .rel.plt      00000158  080488e0  080488e0  000008e0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .init         00000008  08048a40  08048a40  00000a40  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  7 .plt          000002c0  08048a48  08048a48  00000a48  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  8 .text         000086cc  08048d10  08048d10  00000d10  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  9 .fini         00000008  080513e0  080513e0  000093e0  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 10 .rodata       000027d0  080513e8  080513e8  000093e8  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 11 .data         000005d4  08054bb8  08054bb8  0000bbb8  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 12 .ctors        00000008  0805518c  0805518c  0000c18c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 13 .dtors        00000008  08055194  08055194  0000c194  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 14 .got          000000b8  0805519c  0805519c  0000c19c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 15 .dynamic      00000088  08055254  08055254  0000c254  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 16 .bss          000003b8  080552dc  080552dc  0000c2dc  2**3
                  ALLOC
 17 .note         00000064  00000000  00000000  0000c2dc  2**0
                  CONTENTS, READONLY
 18 .comment      00000062  00000000  00000000  0000c340  2**0
                  CONTENTS, READONLY
SYMBOL TABLE:
no symbols

編集:

以下のEphemientのコメントをエコーするには、「GCCをソースなしでバイナリとして扱うのはとても奇妙です」!

したがって、Strace、Objdump、GDB、および386のアセンブラーとアーキテクチャの私の限られた理解を使用して、私はこの問題をレガシーコードで最初のマロックコールに追跡しました。レガシーGCCは、nullを返すMallocを呼び出します。これにより、Stderrで「仮想メモリが排出された」メッセージが表示されます。このマロックはlibc.so.5にあり、getenvを何度も呼び出し、brk()を呼び出すことになります...

このことから、問題はBRKランダム化以上のものであると判断することができます。または、radion_va_space = 0およびlegacy_va_layout = 1 sysctl設定にもかかわらず、BRKランダム化を完全に無効にしていません。

役に立ちましたか?

解決

Linux +を仮想マシンにインストールします。

他のヒント

あなたは持っていますか ソース このカスタムコンパイラ用? 2.6.0のベースラインを回復できる場合(そして、それは比較的簡単なはずです)、Diffとパッチは変更セットを回復するはずです。

その後、その変更セットを使用して、最新のGCCに対して新しいバージョンを構築することをお勧めします。そして、それを構成制御下に置きます。

申し訳ありませんが、叫ぶつもりはありません。 30年のほとんどの間、私が同じことを言ってきただけです。

あなたはできる strace gcc-2.6.0 実行可能?それは読書のようなことをしているかもしれません /proc/$$/maps, 、出力が取るに足らない方法で変化すると混乱します。同様の問題がありました 最近気づいた 2.6.28から2.6.29の間。

もしそうなら、あなたはハックすることができます /usr/src/linux/fs/proc/task_mmu.c または古い出力を復元するか、いくつかをセットアップする $LD_PRELOAD 偽物に gcc 別のファイルを読むことに。

編集

あなたが言及して以来 brk...

CONFIG_COMPAT_BRK デフォルトを作成します kernel.randomize_va_space=1 それ以外の 2, 、しかし、それはまだヒープ以外のすべてを無作為にします(brk).

あなたがあなたの問題がなくなるかどうかを確認してください echo 0 > /proc/sys/kernel/randomize_va_space また sysctl kernel.randomize_va_space=0 (同等)。

もしそうなら、追加してください kernel.randomize_va_space = 0/etc/sysctl.conf または追加します norandmaps カーネルコマンドライン(同等)に、そして再び幸せになります。

私は遭遇しました これ そしてあなたの問題について考えました。バイナリで再生してELF形式に移動する方法を見つけることができますか?または、それは無関係かもしれませんが、objdumpで遊ぶことでより多くの情報を提供できます。

プロセスメモリマップをご覧ください。

だから私は何かを解決しました...それは完全な解決策ではありませんが、レガシーGCCで私が抱えていた元の問題を乗り越えます。

.plt(手順リンケージテーブル)にすべてのlibc呼び出しにブレークポイントを置く(libc.so.5)getEnv()がget:get:

    MALLOC_TRIM_THRESHOLD_
    MALLOC_TOP_PAD_
    MALLOC_MMAP_THRESHOLD_
    MALLOC_MMAP_MAX_
    MALLOC_CHECK_

だから私はこれらをウェブ検索し、見つけました これ アドバイスしました

    setenv MALLOC_TOP_PAD_ 536870912

その後、レガシーGCCは機能します!!!!

しかし、家に無料ではなく、失敗する前にビルドのリンクに起きたので、私たちが持っているレガシーnldでさらに何かが起こっています:-(それは報告しています:

    Virtual memory exceeded in `new'

In /etc/sysctl.conf私は持っています:

    kernel.randomize_va_space=0
    vm.legacy_va_layout=1

それでも同じように機能します

    kernel.randomize_va_space=1
    vm.legacy_va_layout=0

しかし、そうではありません

kernel.randomize_va_space=2

「LDD」を使用して共有ライブラリの依存関係を確認するための提案がありました。レガシーGCCにはLIBC5のみが必要ですが、レガシーNLDにはLIBG ++も必要です。 LIBG ++のLIBC5バージョン。

だから、私が言ったように、まだ家にいない...近づいている。おそらく、NLD問題に関する新しい質問を投稿します。

編集:

私はもともと、この答えを「受け入れる」ことを控えるつもりでした。なぜなら、私はまだ対応するレガシーリンカーに問題があるからですが、少なくともこの質問について何らかの最終性を得るために、私はその立場を再考しています。

ありがとう。

  • VMを使用することを提案するためのAN0NYM0USC0ワード(最終的に受け入れられた答えになる可能性があります)
  • Straceを使用することを提案し、Stackoverflowの使用を支援するためのephemient
  • objdumpの使用を提案するためのshodanex

編集

以下は私が学んだ最後のことです。今では、他の方法で完全に解決できなかったので、VMソリューションを受け入れます(少なくともこれに割り当てられた時間で)。

新しいカーネルにはconfig_compat_brkビルドフラグがあり、LIBC5を使用できるようにするため、このフラグで新しいカーネルを構築すると問題が解決します(カーネルSRCを通して見ると、すべてのパスに従っているわけではありません)。また、ランタイムで(カーネルビルド時間ではなく)LIBC5の使用を許可する別の文書化された方法もあります:Sudo Sysctl -W Kernel.Randomize_va_space = 0。ただし、これは完全なジョブを行いません。また、レガシーコンパイラやリンカーなど、一部の(ほとんど?)libc5アプリはまだ壊れます。これは、新しいカーネルと古いカーネル間のアラインメントの仮定の違いによるものと思われます。 Linkerバイナリにパッチを適用して、BSSの終わりをページ境界に上げるために、より大きなBSSセクションを持っていると思わせました。これは私にとって満足のいく解決策ではありません。私は重要なバイナリ実行可能ファイルに盲目的にパッチを適用しているため、新しいカーネルでパッチ付きリンカーを実行しても、古いカーネルの元のリンカー実行に少し同一の出力を生成しましたが、それはそれを証明しません。他のいくつかのリンカー入力(つまり、リンクされているプログラムを変更します)も同じ結果を生成します。

システムが死んだ場合に再インストールできるディスク画像を作成するだけではありませんか?またはVMを作りますか?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top