Linux GCC FAQ

Mitchum DSouza

m.dsouza@uk.ac.caw.mrc-apu

萩尾 勝巳 - 日本語訳

(VIC)

GAA00714@niftyserve.or.jp

February 1, 1994


Note: この文書はかなり以前に書かれたものなので、 いまどきの Linux 環境にはあてはまらない箇所があります。 (JF Project)

Q: 0) この FAQ の最新バージョンはどこで手に入れられますか?
Q: 1) 私が使っている GCC のバージョンを知るにはどうすればいいですか?
Q: 2) GCC,as,ld,ar, その他の最新版の配付はどこにありますか?
Q: 3) libc.so,libw.so の共有ライブラリの最新版はどこで見つけることができますか?
Q: 4) Linux で他にはどのような共有ライブラリが使えますか?
Q: 5) Linux 用の共有 DLL ライブラリを作るにはどうすればよいのですか?
Q: 6) 完璧なバイナリを実行したのに,"PLT__oct__FUii" メッセージを受け取るのはなぜ ですか?
Q: 7) プラットホーム XXX 上に Linux のコードをはきだすクロスコンパイラを作るにはど うすればよいのでしょうか?
Q: 8) どのようなシンボルが Linux の GCC によって自動的に定義されますか?
Q: 9) コンパイル時に (sigvecといった特別なシグナルなどの) BSD の仕様をなくすには どうすればいいですか?
Q: 10) SIGBUS, SIGEMT, SIGIOT, SIGTRAP, SIGSYS などはどこにありますか?
Q: 11) libhard と libsoft とは何ですか?
Q: 12) メッセージ "can't load library: /lib/libxxx.so, Incompatible version" の意 味は何ですか?
Q: 13) わたしのライブラリがとても大きいのはなぜですか?また、どうすれば小さくなり ますか?
Q: 14) -N フラグを使うと何が起こりますか?また、どう使えばいいのですか?
Q: 15) プログラムのデバッキング情報はどうすれば取れるのですか?
Q: 16) どのデバッガが Linux で使えますか?
Q: 17) daemon プログラムをデバッグする方法は?
Q: 18) profiling とは何ですか?また、プログラムを profile するにはどのようにすれば よいのでしょうか?
Q: 19) もし、バイナリが静的にまたは共有ライブラリにリンクされていた場合に、それを 調べる方法はありますか?
Q: 20) Linux は LD_LIBRARY_PATH をサポートしていますか?
Q: 21) 私のプログラムでは /lib/cpp が必要です。どこから手に入れたらよいのでしょう か?
Q: 22) <varargs.h> はどこですか?
Q: 23) 私のプログラムで、<linux/foo.h> をインクルードしたいのですが、 見つけることができません。どこにあるのでしょうか?
Q: 24) foo() 関数はライブラリに入っているのでしょうか?
Q: 25) プログラム XXX を Linux に持ってくるにはどうすればいいですか?
Q: 26) gcc/library の foo でバグを見つけたのですが、どうすればよいのでしょうか?
Q: 27) 共有ライブラリが同じ機能を持った静的ライブラリより大きくなるのは何故です か?
Q: 28) /usr/lib 内にある .sa ファイルとは何ですか?
Q: 29) Linux 用のオブジェクト指向の C はどこで手に入れられますか?
Q: 30) "Internal compiler error: cc1 got fatal signal 11" のメッセージの意味は何で すか?
Q: 31) libc.lite とは何ですか?
Q: 32) Linux のライブラリは SHADOW Password をサポートしてますか? また、オン・オフはどうすればよいのですか?
Q: 33) math.h ルーチンが見つかりません。プログラムをコンパイルしているのですが、 log(), sin() などが見つかりません。だれか、助けて!
Q: 34) GCC のマニュアルはありますか?もしあるなら、どこで手に入れられますか? また、どうすれば印刷できますか?
Q: 35) "Undefined symbol _bsd_ioctl" のメッセージが出ました。どうすればいいのです か?
Q: 36) バージョンアップするときは、/usr/lib/gcc-lib/i[34]86-linux/<old-version> から古いものを取り除くことはできますか?
Q: 37) 『助けて』libipc.a はどこですか?dosemu 0.49 のために必要なのですが。
Q: 38) XXX がコンパイルできません。_daemon が未定義になります。だれか助けて!!
Q: 39) 『助けて』ar と ライブラリについてです。シンボルはライブラリにあるのです が、リンクに失敗します。
Q: 40) 助けて! 初心者なのですが、"libc.so.4: incompat. minor ver no." というワー ニングメッセージがでて困っています。
Q: 41) c のプログラムのコンパイルの前にチェックする `lint' はどこですか?
Q: 42) 私のプログラムで sgtty.h が必要なのですが、どこにあるのでしょうか?
Q: 43) SIGSEGV によるコアファイルの作成を禁止したり、許可したりするにはどうすれば よいのでしょうか?
Q: 44) "can't load dynamic linker `/lib/ld.so'" のメッセージの意味は何ですか?
Q: 45) -O2 と -O6 での効率の違いは何ですか?
Q: 46) 出所不明のバイナリがトロイの木馬のようなウィルスに感染しているかどうか チェックする方法は?
Q: 47) C ライブラリのソースはどこにありますか?またリビルドする方法は?
Q: 48) FD_* の定義はどこにありますか?
Q: 49) -g オプション付でリンクしたら、___fpu_control と ___setfpucw が未定義だと言 われてしまったのですが。 /usr/lib/crt0.o Undefined symbol ___fpu_control reference from text segment. /usr/lib/crt0.o Undefined symbol ___setfpucw reference from text segment. なにが悪いのでしょうか?
Q: 50) わたしのライブラリやアプリケーションを国際化するツールはどこで手に入ります か?
Q: 51) `mkimage' という DLL ツールが libgcc のなかに見つかりません。助けてくださ い。
Q: 52) "__NEEDS_SHRLIB_libc_4 multiply defined" のメッセージを出ないようにするには どうすればいいのでしょうか?
Q: 53) QMAGIC というのは、一般的にはどういうものですか?
Q: 54) どのようにすれば、QMAGIC の実行ファイルやライブラリを作成できますか?
Q: 55) "warning using incompatable library version xxx" のメッセージを出ないよう にすることはできますか?

A:

回答: Ok!ここに、私がコンパイルしたリストがあります。多少の追加/変更は
      大目にみてください。

      以下に述べるファイルは、各ライブラリが最近入っている(または入っていると
      報告された)ファイルです。

      P.S. 以下のライブラリをより確実なものにするために、ライブラリをメンテする
      人々、またライブラリ自身が tools-x.y.tar.z パッケージに入っている 
      doc/table_description ファイルを参照します。
      これらがどこで手に入るかは質問 (5) を参照してください。

これが、Linux 用の DLL ライブラリが登録されている一般的なファイル一覧です。
======================================================================

libc.so     tsx-11.mit.edu:/pub/linux/packages/GCC/image-4.5.8.tar.gz
libm.so         上記の tar.gz ファイルに含まれています。

libX11.so   tsx-11.mit.edu:pub/linux/packages/X11/XFree86-2.0/xf86-lib-2.0
.tar.gz
libXt.so        上記の tar.gz ファイルに含まれています。
libXaw.so       上記の tar.gz ファイルに含まれています。

librl.so    sunsite.unc.edu:/pub/Linux/libs/librl-1.1.tar.z
libgr.so    sunsite.unc.edu:/pub/Linux/libs/libgr-1.2.tar.z
libf2c.so   sunsite.unc.edu:/pub/Linux/development/fortran/libf2c-0.9.tar.z
libF77.so       上記の libf2c.so を代わりに使ってください。
libI77.so       上記の libf2c.so を代わりに使ってください。

libXpm.so   sunsite.unc.edu:/pub/Linux/libs/libXpm32g.tar.z

libnsl.so   ftp.lysator.liu.se:/pub/NYS/nys-0.xx.tar.gz

libolgx.so  sunsite.unc.edu:/pub/Linux/libs/xview3L5.tar.gz
libxview.so     上記の tar.gz ファイルに含まれています。
libsspkg.so     上記の tar.gz ファイルに含まれています。
libUIT.so       上記の tar.gz ファイルに含まれています。

libPEX.so   tsx-11.mit.edu:pub/linux/packages/X11/XFree86-1.3/xf86-pex-2.0
.tar.gz

libtcl.so   sunsite.unc.edu:/pub/Linux/development/tcl/*
libtk.so        tcl/tk のなかのいろいろな tar.gz ファイルに含まれてい
        ます。

libWc.so            不明です。
libXp.so            不明です。

libIV.so    nic.funet.fi:/pub/OS/Linux/images/Slackware/iv1/iv*.tgz
libUnidraw.so   上記の .tgz ファイルに含まれています。

libXm.so    Motif ライブラリはフリーソフトではありません。下記のノートを参照
            してください。

libsrgp.so  sunsite.unc.edu:/pub/Linux/X11/devel/suit.tpz
libsuit.so      上記の tpz ファイルに含まれています。(配布していないと報告
        されています)

libOI.so    tsx-11.mit.edu:/pub/linux/packages/OI/oi40.tar
libOIrg.so       上記の tar ファイルに含まれています。

libld.so    tsx-11.mit.edu:/pub/linux/packages/GCC/ldso-1.4.tar.z
                 (libc 4.4.4 以上が必要です)

libarma.so  ftp.atnf.csiro.au:/pub/karma
libkarmaX11.so      上記の site を見てください。
libkarmaXt.so       上記の site を見てください。
libkarmagraphics.so 上記の site を見てください。
libkarmawidgets.so  上記の site を見てください。
libkarmaxview.so    上記の site を見てください。

libwxwin.so     sunsite.unc.edu:/pub/Linux/X11/devel/wxWin_linux.tgz

libandrew.so    sunsite.unc.edu:/pub/Linux/X11/andrew/andrew.apps.tar.gz

libUil.so       商業ライブラリです。

libBLT.so       sunsite.unc.edu:/pub/Linux/devel/tcl/blt1.0-bin.tar.z

libvga.so       sunsite.unc.edu:/pub/Linux/libs/svgalib097.tgz

libitcl.so      sunsite.unc.edu:/pub/Linux/devel/tcl/itcl1.3-bin.tar.z

------------
ノート 1:-

3D 効果(libXaw3d-0.6)を得る Xaw の DLL ライブラリの一部と Xaw クライアント上
の Mac(TM) ライクのスクロールバーは、おのおの以下で入手できます。

    sunsite.unc.edu:/pub/Linux/libs/libXaw3d-3.0-B.tar.z

    sunsite.unc.edu:/pub/Linux/libs/libXaw.Scrollbar.taz

ノート 2:-

motif 用のライブラリは、お金を払わなければいけません!!
詳しくは以下の引用を読んでください。

------

Metro Link 社は、199 ドルで Linux 用の OSF/Motif 1.2.2 の完全なランタイムと
開発システムを提供します。

必要なもの:
    Linux 0.99pl4 以上 (現在の 0.99pl12 で OK)
    XFree86 1.2 以上 (1.3 で OK)
    libc 4.3.3 以上 (libc 4.4 で OK)

何を含んでいるか:

ランタイム:
    1) Motif ウィンドウマネージャ (mwm)
    2) 共有 motif ライブラリ (libXm.so.1.2.2)
    3) OSF と net からの Motif のデモ

開発ツール:
    1) 共有 + 静的 Motif ライブラリ
    2) 静的 Mrm と Uil ライブラリ
    3) UIL コンパイラ
    4) Motif ヘッダライブラリ
    5) Motif ファンクションコールのマニュアル
    6) Imakefile サポート
    7) OSF/Motif のデモのソース

そして、O'Reilly & Associates, Inc により出版されている X-window books から
あなたが選んだ一冊。

Linux 用 OSF/Motif 1.2.2 は、Metro Link 社へ連絡することで注文できます。
電話番号は (305) 970-7353、FAX 番号は (305) 970-7351、
電子メールは sales@metrolink.com です。

==============================================================================
  Metro Link Incorporated.  2213 W. McNab Rd. Pompano Beach,  Florida  33069
 X11.5 and OSF/Motif for QNX, SVR3, SVR4.[012], SCO, Linux, UnixWare, LynxOS, 
                  AT&T, Venix, ISC, Solaris, Pyramid, SunOS
 Voice: +1.305.970.7353    Fax: +1.305.970.7351  Email: mahesh@metrolink.com
            WATCH your: Word Action Thought Character Heart
==============================================================================

A:

回答: gcc のソースコードを持っていると仮定します。いつもは、GCC の INSTALL ファ
      イルの情報で理解できます。
      プラットホーム XXX で `configure --target=i386-linux-linux --host=XXX' 
      とすることによって `make' をごまかし、処理を続けます。
      Linux のインクルードファイルやカーネルのインクルードファイルや
      tsx-11.mit.edu にある /pub/linux/packages/GCC/src のソースからクロス
      コンパイラやクロスリンカを作ることが必要なことに気づくでしょう。

      linux マシンのコードを作るための Sparc (Sun) 用のクロスコンパイラの作成例
      があります。簡単な方法です。すでに使っている linux マシンを使っている HLU
      によってコンパイルされたlinux ライブラリを使用する簡単な方法です。
      私の『強力な』アドバイスは、いくつかのコンパイルで使用する GNU の make 
      (gmake) を手に入れることです。(バイナリユーティリティや gas が Sun の 
      make 同様に Makefiles.linux を扱うと失敗するでしょう)

    7.1) すでに Sun 上の標準インストールパスとして /usr/local/bin に動く gcc
       バージョン 2.4.5 があると仮定します。すなわち、コンパイラは
       /usr/local/lib/gcc-lib にあります。

       最初は、 以下のように linux 特有のディレクトリを作ります。
       (中間ディレクトリも作る必要があるかもしれません)

        % mkdir -p /usr/local/lib/gcc-lib/i386-linux-linux/bin
        % mkdir -p /usr/local/lib/gcc-lib/i386-linux-linux/2.4.5/include
        % mkdir    /usr/local/lib/gcc-lib/i386-linux-linux/include

    7.2) 環境変数を設定する事により、長いパス名を打ち込まなくてよくなります。
       .login や .cshrc ファイルにセットしてください。同様に DLL などのクロスコ
       ンパイルのために l-ar, l-ranlib を使う必要があるでしょう。
       さしあたり、以下のことを行ってください。

       csh の場合:
           % setenv LBINS /usr/local/lib/gcc-lib/i386-linux-linux/bin/

       sh の場合:
           % LBINS=/usr/local/lib/gcc-lib/i386-linux-linux/bin/
           % export LBINS

       linux, asm, gnu, sys やその他のサブディレクトリの内容として『すべての』 
       linux 特有のヘッダファイルを入れてください。${LBINS}../include 配下を
       『確認』してください。ヘッダファイルの在り処は質問(2)、(23)を見てくださ
       い。あなたは、それぞれについて新しいカーネルをリリースしなければなりませ
       ん。

       私の linux マシンから、sun へ転送の話をしましょう。

        % rcp -r linux_machine:/usr/include ${LBINS}../

       一方、インクルードファイルとカーネルのソースを手に入れる必要があります。
       質問 (2) を見てください。それを展開する必要もあります。
       したがって、limits.h, varargs.h, stdargs.h のような gnu の特別なファイル
       が必要になるでしょう。また、私の linux マシンの話をしましょう。

        % rcp -r \
            linux_machine:/usr/lib/gcc-lib/i386-linux/2.4.5/include \
            ${LBINS}../2.4.5

       i386 または 2.4.5 はあなたのマシンや gcc のバージョンにより変えなければ
       ならないかもしれません。

    7.3) さて、あなたはクロスアセンブラとリンカを展開し、コンパイルしなければな
       りません。

       以下のファイルを手に入れてください。

         tsx-11.mit.edu:/pub/linux/packages/GCC/src/binutils-1.9l.3.tar.gz
         tsx-11.mit.edu:/pub/linux/packages/GCC/src/gas-1.38.1l.2.tar.gz

       そして、どこかで展開してください。

    7.3.1) バイナリユーティリティのディレクトリ binutils-1.9l.3 の中:
        Makefile.linux をエディットして、bindir 定義の行を書き換えてください。

                bindir=${LBINS}

        そして、あなたのマシン(この場合は "sun4")の適当なブロックが並びます。

            HOST_ROOT=${LBINS}..

        0.99pl12 (たぶんそれ以上のレベルでも) のためにa.out.h と page.h をディ
        レクトリにコピーし、MISCFLAGS の中に含まなければならないでしょう。
        そして、カレントバイナリユーティリティのディレクトリで以下のことを実行
        してください。

            % mkdir linux
            % cp ${LBINS}../include/linux/a.out.h linux
            % cp ${LBINS}../include/linux/page.h linux

        そして、Makefile.linux を編集し、適当な MISCFLAGS のラインに -I を加え
        てください。

        そして、実行してください。

            % make -f Makefile.linux archpfx= install

        linux の ar, ranlib ユーティリティとして、l-ar, l-ranlib を実行すること
        ができるようにするために、以下のことを実行してください。(私は個人の
        ${HOME}/bin ディレクトリに l-blah を置いています)

            % sh -c 'for i in ${LBINS}*; do \
                      ln -s $i ${HOME}/bin/l-`basename $i`; done'

    7.3.2) ******* gas-1.38.1l.1 の時 *******
        アセンブラディレクトリ gas-1.38.1l.1 の中:
        makefile.linux を編集し、以下を読んで適当な行を変更してください。

            LINUX_INCDIR=

            HEADERS=-DA_OUT_H=\"${LBINS}../include/linux/a.out.h\"

        そして、打ち込んでください。(たくさんのワーニングがでるでしょう)

            % make -f makefile.linux

         クロスアセンブラのバイナリファイルを手動でコピーしてください。

            % cp a386 ${LBINS}as

        ******* gas-2.2 (それ以上)の時 *******

        アセンブラディレクトリで以下のことを実行してください。

            % ./configure --host=sun4 --target=i386-linux-linux
            % make CC=gcc CFLAGS=-O2 LDFLAGS=-s

    7.3.3) 最後に以下の二つのリンクを行ってください。

            % ln -s ${LBINS}as ${LBINS}../2.4.5/as
            % ln -s ${LBINS}ld ${LBINS}../2.4.5/ld

    7.4) さて、あなたの Sun 上の GCC ソースディレクトリに展開するには以下のこと
       を行ってください。

        % ./configure --host=sun4 --target=i386-linux-linux
        % make  CC=/usr/local/bin/gcc CFLAGS="-O2 -s" \
                tooldir=${LBINS}.. LANGUAGES="c c++ objc"

      libgcc.a ライブラリを作成時にエラーで終了するかもしれませんが、無視してく
      ださい。望みは第一にクロスコンパイラのバイナリですから。

    7.5) 以上の作業が終了後、適切な場所にコピーします。

        % cp cc1 cc1plus cpp ${LBINS}../2.4.5

      前置きとしてコンパイラを bin ディレクトリにコピーし、簡単にどこか(たとえ
      ば ~/bin)にリンクします。

        % cp xgcc ${LBINS}gcc
        % ln -s ${LBINS}gcc ${HOME}/bin/gcc-linux

    7.6) あなたの linux マシンからライブラリを取り出します。

        % rcp linux_machine:/usr/lib/lib\*a ${LBINS}../2.4.5
        % rcp linux_machine:/usr/X386/lib\*a ${LBINS}../2.4.5
        % rcp linux_machine:/usr/lib/crt0.o ${LBINS}../2.4.5

    7.7) そういうことです。なにかコンパイルしてみてください。パッケージに書か
         れているたくさんのよいことがあるので、以下のことをやってみましょう。
         (あなたの ${HOME}/bin にセットするパスをがあると仮定します。)

        % make CC="gcc-linux -O6 -s" RANLIB=l-ranlib AR="l-ar"

    7.8) もし、共有 DLL でクロスコンパイルをしたいならば、以下のものを手に入
         れなければなりません。

        tsx-11.mit.edu:/pub/linux/packages/GCC/src/tools-2.10.tar.z

         クロスバージョンのコンパイルのために用意された tools サブディレクトリ
         の Makefile.cross を使ってください。 Makefile.cross の最初の部分を以下
         のように変更してください。

                CROSSBINDIR=${LBINS}
                CROSSINCDIR=${LBINS}../include

         最後に BINDIR の定義を変更します。わたしは ${LBINS}../dll/bin をセット
         しています。これは、あなたのために ${LBINS}../dll/jump を作成することに
         なるでしょう。そして、

        % make -f Makefile.cross install

         を行うべきです。

A:

回答: 共有ライブラリが発展していくと、プログラム実行時にクラッシュを引き起こす
    ようになったり、制限ができたりします。それをはっきりさせるために、バージョ
    ンによって分類する必要があります。例えば、ファンクションコールがまるっきり
    変わる、または無くなってしまった場合などがそうです。

       ライブラリの呼び名 - libc.so.4.3.3
                               T    T T T
                              /    /  |  \
                             /    /   |   \
                            /    /    |    \
                 ライブラリ名   /     |     \
                               /      |      \
          メジャーバージョンナンバー  |      パッチレベル
                                      |
                            マイナーバージョンナンバー

    メジャーバージョンナンバーの違いは、プログラムをリンクしたライブラリと動作
    する  カレントライブラリのメジャーバージョンとが等しい場合にのみプログラム
    の実行が保証されることです。
    これは、libc.so.4.3.3 でコンパイルされたプログラムは、libc.so.5.1.2 と
    いったより最新の DLL ライブラリ上では実行不可能であるということを意味して
    います。
    つまりプログラムで libc.so.4 を必要としていて、libc.so.5.1.2 から 
    libc.so.4 へのリンクを張っても動かないということです。

    マイナーバージョンナンバーの定義としては、共有 DLL ライブラリでマイナーチェ
    ンジや新追加関数があったが、過去の互換性が保たれていることを示しています。
    マイナーバージョンナンバーがオリジナルのコンパイル時よりより小さいライブラ
    リを使用しようとすると、ナンバー変更によるワーニングが発生するでしょうが、
    一般の実行では全く無視して構いません。

    パッチレベルナンバーはナンバリングの申し合わせからなので無視してかまいませ
    ん。それはいつもはライブラリコードの誤植や小さなバグフィックスで使用されま
    す。

    問題に戻ると、あなたがバイナリの実行を試すときに、正しいライブラリがインス
    トールされていないことを意味します。状況を改善するには、質問の (3),(19) を
    見て、最新のライブラリを手に入れることです。

A:

回答: より小さいライブラリが欲しいなら、すべきことはたくさんあります。

    * コードの最適化 - コンパイル時に -O2 フラグを使います。
    * 合成バイナリのストリップ化 - ld の部分で -s フラグを使います。
    * 合成バイナリの作成 - ld の部分で -N フラグを使います。

    これらを組み合わせて使います。もし、バイナリをストリップ化したいなら、手軽
    に ld の "-s" オプションを使ったソースにしないでください。"strip" コマンド
    を使ってください。"man strip" を実行して詳しい情報を見てください。

    `ld' リンカはデフォルトでプログラムを共有ライブラリにリンクします。しかし
    ながら、関連のある一部を見つけることができない(すなわち .sa ファイル)、
    『または』ユーザにとって不可視ファイルであった場合は(すなわち .a ファイル
    として)静的リンクを試みようとします。あなたのバイナリが大変大きい理由はこ
    れかもしれません。サーチパスは /usr/lib や /lib や / のライブラリから .sa 
    や .a を探します。このことは、stub と DLL 共有ライブラリをこれらのディレク
    トリ中に点在させることになるかもしれません。より柔軟的に行うには (20) を見
    てください。

    たくさんの FSF の作者たちもまた、自分のプログラムがデバッグされ、Makefile 
    から -g オプションが取り去られることを我々が望んでいるのを知っています。
    結果として、スタティックにリンクされたプログラムのなかには莫大なデバッグシ
    ンボルが残っています。もしあなたがソフトをコンパイルし、その動きに満足して
    いるならば、-g を CFLAGS かつ/または LDFLAGS から削除するために、注意深く
    Makefile をチェックしてください。

A:

回答: 仮想記憶によるスワップが可能になります。-N オプションを使うと、ページ境界
      いっぱいに詰め込まれた個々のセグメント領域を持ち、それらが連続しない実行
      ファイルが使用できるようになります。Linux は、簡単に『忘れること』によっ
      て割り当てられる(すっきりした)ページスワップを活用できます。なぜなら、
      いつもファイルから直接に再ロードできるからです。
      他方、スワップパーティションやスワップファイルによる物理的なスワップ機能
      も持っています。それには、多少の時間とディスクスペースが必要です。

      スワップは、通常は小さなプログラムには関係ありません。-N を使ってコンパイ
      ルされていたとしてもです。大きなプログラム(例えば、gcc または emacs)、
      または複数の段階を持っているようなプログラム(shell や xterm のような
      もの)は、-N なしでコンパイルすべきです。その結果、コードページはきれいに
      割り当てられます。もし、メモリ不足で(プログラムを)走らせたならば、
      カーネルは仮想記憶で動いている使われていないコードページ(あとで再ロード
      できる)を削除しはじめます。連続しない実行形式では不可能です。

      したがって、もしあなたのプログラムが重要なたくさんのメモリを使用するよう
      ならば、-N を使用しないか、カーネルのメモリ管理を妨げるしかないでしょう。

      ハッキリとした `one-off' プログラムは、このフラグを使用してコンパイルされ
      ています。すなわち、長時間メモリ上にとどまらないものです。例えば、
      hostname, fsck, mkfs, w などです。daemon では、この -N フラグを決して
      使用し『ない』で下さい。メモリ上に常駐することは意味がないからです。

A:

回答: プログラムをコンパイルすることが必要です。(すなわち、すべてのオブジェク
    ト)そして、-g フラグを付けてリンクします。言い換えると『すべてのプログラム
    』に -g を付けてコンパイルします。
    デバッキングツールでまだいくつかのファイルが -g で動いています。(デバッキ
    ングツールはバグだらけです)-g フラグを使うより重要なことは、
    -fomit-frame-pointer を使用し『ない』ことであり、これにより、gdb がごまかさ
    れます。
    不幸にして、共有ライブラリは性能のために普通、 -fomit-frame-pointer を付け
    てコンパイルされています。

    その代わりに、デバッキング時に -g または、 -static フラグをリンカに付けた
    り、非共有ライブラリにリンクすることは懸命なことです。もし、そうしなかった
    ら、セグメント違反が発生したときに(メモリアクセスの)経過をたどることがで
    きません。

    リンク時に
        Can't find libg.a
    のメッセージが出力されたならば、
    tsx-11.mit.edu : /pub/linux/packages/GCC/extra*.tar.z 
    ファイルを手に入れる必要があります。

    しかしながら、あなたのマシンで単純に
        % cd /usr/lib; ln -s libc.a libg.a
    を実行すれば十分なデバッキング情報が得られるかもしれません。
    フル機能の libg.a (~2Mb) を使用しなければ、デバッグできないライブラリコー
    ルもあるでしょう。

    もし、性能のデバッグをしたいのならば、バイナリをストリップ化してい『ない』
    ことを確認してください。

A:

回答: はいあります。
    `ldd' というユーティリティを使用してください。このユーティリティは、要求さ
    れるライブラリの情報を出力します。もし、`ldd' を実行したときに何の情報も出
    力されなかった場合は、調べたプログラムは静的にリンクされています。

    例 (1): コマンド(私の linux システム)
        % ldd /bin/init
    出力がないことは静的にリンクされたということです。静的にリンクされればよい
    のです。:-) (ノート: libc.so.4.5.10 以上でリンクされたプログラムでは
    "statically linked" のメッセージが出力されるでしょう。)

    例 (2): コマンド(私の linux システム)
        % ldd /usr/bin/gs
    すなわち、ghostscript インタプリタは以下の情報を出力します。
            libm.so.4       => /lib/libm.so.4.4 (4.0)
            libX11.so.3     => /lib/libX11.so.3.0 (DLL Jump 3.0pl0)
            libc.so.4       => /lib/libc.so.4.4 (DLL Jump 4.3)
    このことは、`gs' プログラムが動的にリンクされ、3 つの共有ライブラリを要求し
    ていることを示しています。括弧内の数はただ一つのライブラリ(libX11)を示し
    ており、プログラムがコンパイルされたときに持っていたライブラリのカレントバ
    ージョンです。`gs' が、数値演算ライブラリ (libm), でコンパイルされたとき
    は、バージョン 4.0 で、DLL ライブラリでなかったのですが、幸運にも 4.4 の 
    DLL ライブラリでも走らせることができそうです。同様に、私のカレントの C ライ
    ブラリ (libc)は、`gs' をコンパイルしたときよりバージョンが上がっています。

    ※ あなたの `ldd' はバージョンによっては、なにか別の結果を出力をするかもし
       れません。

A:

回答: はいといいえです。バイナリのコンパイル時に使用した libc のバージョンに
    依存します。

    * 第一に LD_LIBRARY_PATH は、4.3.3 以上のライブラリでサポートされています。

    すなわち、あなたの stub (/usr/lib/libc.sa) の __load.o ルーチンは、これを実
    現するために変更されています。libc のバージョン 4.4.4 未満でコンパイルされ
    たバイナリでは、Linux の動的リンカは、libc.sa の stub に現れ、作ったバイナ
    リすべてにリンクされる __load.o 形式の静的オブジェクトです。このことは、
    __load.o の変更が、ひとつひとつ、すべてのバイナリに現れ、普及するのに大変
    な時間を要することを意味しています。

    そして、質問の回答としては、4.3.3 (libc.so.4.3.4 以上) 以上のライブラリを使
    用してコンパイルしたならば、イエスです。しかし、結果としては、『すべての』
    バイナリをリコンパイルすれば、気をつける必要はないでしょう。

    * libc のバージョンが 4.4.4 以上では、動的に作られた動的ローダは必要なライ
    ブラリを検索、位置づけ後に自分自身をローディング、アンローディングします。
    この結果、バイナリは小さく、動的ローダ、リンカによる変更は libc から隔離さ
    れます。ld.so パッケージにある ld.so と ldconfig のマニュアルを見てくださ
    い。また,質問 (4) の libld.so の項目も参照してください。

    Linux の LD_LIBRARY_PATH は安全で簡潔であり、Sun-OS で行った方法や行いた
    い方法での動きは予期できません。

    最初に Sun-OS の LD_LIBRARY_PATH の使用方法との違いは、コンパイル(リンク)
    状態中の事であり、Sun-OS の LD_LIBRARY_PATH は、いろいろなライブラリを見つ
    けるために解釈され、作られた細切れのバイナリに『記録』されます。ゆえに、ラ
    ンタイムバイナリにおいては、LD_LIBRARY_PATH を調べる前に(まれに 
    LD_LIBRARY_PATH を解釈せず、記録されたパスの最初の共有ライブラリを見つける
    ことで)共有ライブラリのどこを探すかを知っています。したがって、オーバーヘ
    ッドを減らせます。
    一方 Linux は、この情報を記録していませんが、その代わりとしてリンクに必要な
    ライブラリのランタイム(実行ファイル)を探します。

    Linux でバイナリを実行するとき、もし、LD_LIBRARY_PATH  が『なけれ』ば、ラン
    タイムにライブラリをリンクするために最初 /usr/lib 次に /lib そして / を探し
    ます。これは、"期待サーチパス" として照会されます。

    ※ / は、本当はサーチパスではありませんが、過去の互換性のために残っており、
      ユーザのなかには "/lib/libfoo.so" といった名前を使っている 共有 DLL を
      作ると uselib() は以下のように動作します。

        (1) uselib("/usr/lib//lib/libfoo.so.x")  ---- はずれ
        (2) uselib("/lib//lib/libfoo.so.x")      ---- またはずれ
        (3) uselib("//lib/libfoo.so.x")          ---- 当たり !!

    そのため、実際に DLL を / に置かないでください。

    さて、もし LD_LIBRARY_PATH を『持って』いて、ルート(uid が 0)であるなら
    ば、LD_LIBRARY_PATH は、期待サーチパスにしたがって探します。

    もし、それ以外に普通のユーザ(uid != 0)であり、実行するバイナリが suid 
    実行形式の場合、libc.so.x と必要なライブラリは強制的に期待検索パスのどこ
    かからロードされます。LD_LIBRARY_PATH は無視されます。(事実全くリセット状
    態)これにより、自身のエミュレーションから普通のユーザでは停止します。
    例えば、setuid() は、自分で作った libc ライブラリが呼ばれます。

    最後に、もし、ノーマルユーザで実行するバイナリが『普通の』バイナリなら、
    LD_LIBRARY_PATH は最初に必要とするライブラリを探します。

    もし、ユーザの LD_LIBRARY_PATH でライブラリが見つからなければ、検索パス
    として『期待サーチパス』をセットして検索を続けます。このことで、誤った、
    無駄な LD_LIBRARY_PATH をセットする問題を解決し、適切なユーザーのバイナリ
    を実行します。

A:

回答: だれかが、Linux にプログラムを『持ってきた』時に戻ってください。
    もし、Linux に持ってきたものが何もなかったら、意味がありません。

    本気で考えると、一般的に小変更としては、Linux 用に 100% POSIX にしたがって
    編集したソースが必要です。
    元のプログラムコードが変更されてもいいように、将来的には `make' だけで実行
    形式を作れるようにすべきです。


    もっともよく起こる問題の一つとして、一般関数が Linux のヘッダファイルにマク
    ロで定義されていて、プリプロセッサがコードのなかの類似したプロトタイプ定義
    の解析を拒否することがあげられます。類似したものとしては、atoi() と atol() 
    があげられます。

    その他の一般的な問題としては、"sprintf(string, fmt, ...)" では、ほとんどの
     unix の場合は、配列のポインタを返します。Linux では、配列の中の文字数を返
    します。

    その他の問題は、Linux の GCC は、ANSI コンパイラであるという事実により発生
    しがちです。重要なほとんどの変更は、プリプロセッサのためです。以下のオプシ
    ョンを追加してください。

        -traditional

    は、ただひとつの(消極的な)解決方法です。

    +----------------------------------------+
    | Brouno Haible 氏からの価値あるコメント |
    +----------------------------------------+

    これは、Unix のソフトウェアを Linux に持ってくるときに発生するであろう問題
    を記述してみたものです。

    C で書かれたソフトウェアであると仮定します。

    Linux (言い換えると、Linux のシステムコールと C ライブラリ関数) は、できる
    かぎり、POSIX 互換に近づけています。これから短いリストを作ってみます。


    問題 1: select() の timeout パラメタ
    ------------------------------------

    兆候:
    入力で CPU を食いつぶすポーリングをするようなプログラム

    問題:
    select() はシステムコールです。timeout パラメタは、古典的にシステムでは、
    リードオンリーとして使われます。いくつかのマニュアルには、3 年以上前から
    記述されています。

        select() は、決まった場所で時間が変更されるとおおよそオリジナルの 
        timeout から残った時間を返します。このことは、将来、補足されるでしょ
        う。したがって、select コールでtimeout ポインタが変更されないと思うこ
        とは愚かなことです。

    もし、まじめにこのアドバイスを受け取らなかったら、タイムアウトの構造体の書
    き戻しで 0 のタイムアウトが発生するでしょう。それは同じタイムアウト構造体を
    使った select() の将来的なコールがすぐに戻ってくることを意味します。

    用意:
    タイムアウトの値を select() を呼ぶときはいつも構造体に入れてください。

    以下のようにコードを変更してください。

               struct timeval timeout;
               timeout.tv_sec = 1; timeout.tv_usec = 0;
               while (some_condition)
                 { select(n,readfds,writefds,exceptfds,&timeout); }

    から

               struct timeval timeout;
               while (some_condition)
                 { timeout.tv_sec = 1; timeout.tv_usec = 0;
                   select(n,readfds,writefds,exceptfds,&timeout);
                 }

    へ

    問題2: システムコールによる割り込み
    ------------------------------------

    兆候:
    コントロール Z でプログラムを止め、その後リスタートした、または、その他の
    状況で、コントロール C 割り込みのシグナルが発生したとき、コプロセスが終了
    します。"interrupted system call" や "write: unknown error" のようなメッセ
    ージが返ってきます。

    問題:
    実行中のシステムコールプログラムはシグナルプロセスにより割り込みがかかり、
    -1 を返し、errno = EINTR をセットします。そのプログラムは異常終了したように
    見えてしまいます。

    解説:
    あなたのプログラムは(signal(), sigaction(), sigvec() を使う)インストール
    されたシグナルハンドラを持っています。シグナルが発生するとシグナルハンドラ
    が呼び出されます。この現象は、ほかの UNIX システムの場合、非同期、または
   2, 3 の遅いシステムコールで起こります。

        シグナルが遅いデバイス(ファイルでない、ターミナルのような)で read(2),
        write(2), open(2), ioctl(2) のシステムコールの実行中や pause(2) のシス
        テムコールや wait(2) のシステムコールの実行中に引き起こされたとき、
        前もって停止したまたはゾンビプロセスがすでに存在しているためすぐには
        戻ってきません。シグナルをキャッチする関数が実行され、システムコール
        割り込みが errno に EINTR をセットするプロセスを呼び出し、-1 を返しま
        す。

    Linux (POSIX も含みます)では、シグナルをチェックし、シグナルハンドラを
    実行します。
          * 非同期であったか(タイマの刻み),
          * 『どの』システムコールからのリターンであるか
          * 以下に示すシステムコールの実行中であったか
                  select(),
                  pause(),
                  connect(), accept(),
                  ターミナル、ソケット、パイプ、 /proc ファイルへの read(),
                  ターミナル、ソケット、パイプ、ラインプリンタへの write(),
                  FIFO, PTY, またはシリアル回線への open(),
                  ターミナルへの ioctl(),
                  F_SETLKW コマンドでの fcntl(),
                  wait4(),
                  syslog(),
                  その他 TCP or NFS 操作
          『その他のオペレーティングシステムでは、以下のシステムコールも含めな
          ければならないかもしれません。

           creat(), close(), getmsg(), putmsg(), msgrcv(), msgsnd(), recv(),
           send(), wait(), waitpid(), wait3(), tcdrain(), sigpause(),
           semop() 』

    最後の 2 つのケースとシグナルハンドラの復帰値の仮定によりシステムコールは
    -1 を返し、errno に EINTR をセットします。

    もし、SA_RESTART フラグが符合したシグナルとしてセットされても、ほとんどの場
    合、システムコールはシグナルハンドラ実行後、自動的にリスタート(続行)し、
    あなたのプログラムは EINTR は見えません。

    あなたはなぜこれがデフォルトの動作でないのか質問するかもしれません。理由は
    EINTR を返し、セットすることがより強力(プログラムに対し受け取ったすべて
    シグナルに直ちに反応する機会を与えます)であるからです。
    システムコールはもはや『ダークトンネル』ではないのです。

    ノート : いくつかのバージョンの BSD Unix のデフォルト動作はシステムコールを
    リスタートすることです。割り込まれたシステムコールを取り出すためには、
    SV_INTERRUPT または SA_INTERRRUP フラグを使用しなければなりません。

    修正方法としては 2 つの方法を選択できます。

    修正 1:
    あなたのインストールした全てのシグナルハンドラに対し、シグアクションフラグ
    として、SA_RESTRT を追加します。例えば、

                signal (sig_nr, my_signal_handler);

    を

                 signal (sig_nr, my_signal_handler);
                 { struct sigaction sa;
                   sigaction (sig_nr, (struct sigaction *)0, &sa);
                 #ifdef SA_RESTART
                   sa.sa_flags |= SA_RESTART;
                 #endif
                 #ifdef SA_INTERRUPT
                   sa.sa_flags &= ~ SA_INTERRUPT;
                 #endif
                   sigaction (sig_nr, &sa, (struct sigaction *)0);
                 }

    に変更します。

    ノート : これをほとんどのシステムコールに適用する場合、read(), write(),
    ioctl(), select(), pause(), connect() 上の EINTR をチェックしなければなりま
    せん。
    ここに read() と ioctl() の 2 つの例をあげておきます。

    read() を使っているオリジナル部分の

                 int result;
                 while (len > 0)
                   { result = read(fd,buffer,len);
                     if (result < 0) break;
                     buffer += result; len -= result;
                   }
    を

                 int result;
                 while (len > 0)
                   { result = read(fd,buffer,len);
                     if (result < 0) { if (errno != EINTR) break; }
                     else { buffer += result; len -= result; }
                   }

    に変更します。
    また、ioctl() を使っているオリジナルの部分の

                 int result;
                 result = ioctl(fd,cmd,addr);

    を

                 int result;
                 do { result = ioctl(fd,cmd,addr); }
                    while ((result == -1) && (errno == EINTR));

    に変更します。

A:

回答: GCC はたぶんプログラムを走らせるために貪欲にメモリを消費し、きっと RAM 
    の領域を食いつぶしたのでしょう。普通、致命的シグナルの 11 は、RAM の
    パリティエラーやハード障害を意味しています。私もハードディスクの不良ブロッ
    クのせいで cc1 で同じ状態に陥ったことがあります。それは、チップのオーバー
    ヒート(フレンチフライではありません)によるエラーとして報告されています。
    また、低機能の IDE コントローラとドライブで 8MHz AT バスクロック以上で走ら
    せようとすると発生します。これはスワップスペースの変造を引き起こすことによ
    り同じエラーとなります。

    一般に、シグナル 11 (セグメンテーション・バイオレーション)は、プロセスス
    ペース不足状態ででメモリをアクセスに行った、またはリードオンリー領域に書き
    込みに行ったことを意味しています。たまに、このシグナルはソフトのバグで発生
    することもあり、ハード障害とは限りません。(またはシステムの繰り返し
    ハング。なぜならカーネルで同じ事が起きるからです。)gcc 2.3.3 では、何人か
    がたくさんの”シグナル 11”を再現しました。

    また、`ld' や `as' の最中の障害としても発生します。もし、cc1, cpp, または
    ld に問題があるとすれば、gcc で -v フラグを付けてリコンパイルして確認して
    みてください。

A:

回答: マニュアルは sunsite の GCC ディレクトリにあります。
        sunsite.unc.edu:/pub/Linux/GCC/gcc-man.tar.z

    このファイルは cccp.1, cpp.1, g++.1, gcc.1 の man ファイルを含んでいます。

    もし、あなたが印刷されたすべての GCC のマニュアルを必要としているなら、
    GCC が置いてあるどこかのローカル ftp サイトやその他の FSF の都合のよいとこ
    ろからすべてのソースを手に入れなければなりません。GCC のソースから TeX 版
    のマニュアルを作る必要があります。

    もし、あなたがライブラリのファンクションコールのマニュアルを探しているな
    ら、glibc の全てのソースが必要です。これは、GCC のソースがある ftp サイト
    と同じ場所にあります。再び、マニュアルを作成するために TeX が必要となりま
    す。
    このマニュアルで注意すべき点は 900 ページの大きさであることです。
    系図を取っておき、dvi ファイルとしてオンラインで保存しておいてください。

    『情報』ファイルから来るどちらのパッケージも Gnu info や xinfo, emacs を使
    用して見ることができます。『情報』ファイルは情報システムに基づいたハイパー
    テキスト形式です。

A:

回答: はいできます。
    もし、 ld.so のバージョン 1.4 以上を持っているなら、環境変数に LD_NOWARN を
    追加することでメッセージを出なくすることができます。注: 致命的なエラーメッ
    セージは出力されます。

    csh (tcsh)では:
        setenv LD_NOWARN
    sh (bash)では:
        export LD_NOWARN=1

    です。

===============================================================================

                       謝辞: (順不同)

                                  H.J.Lu
                               Dirk Hohndel
                                David Engel
                              Eric Youngdale
                             Bill Metzenthen
                                Rik Faith
                              Steven S. Dick
                               Bruno Haible
                               Andrew Tefft
                                Kai Petzke
                              Tuomas J Lukka
                             Fergus Henderson
                              Paul Gortmaker
                               Olaf Flebbe
                              そして、もちろん

                              Linus Torvalds

===============================================================================

注意 もし、あなたの名前が無く、意味・無意味にかかわらず何か貢献していても、
     どうか、気分を害さないでください。私の単なるミスですので。私に電子メールを
     ください。修正しますので。

===============================================================================

この FAQ を Linux 用 GCC の明確な回答の宝庫にするために、電子メールによる質問を
 (もし、回答もあるならば、それも) 校正、追加して私のお手伝いをしてください。

                    Mitchum DSouza <m.dsouza@uk.ac.cam.mrc-apu>

-- 
comp.os.linux.announce へのご意見は linux-announce@tc.cornell.edu まで。