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) はどこですか? Q: 23) 私のプログラムで、 をインクルードしたいのですが、見 つけることができません。どこにあるのでしょうか? 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/ から古いものを取り除くことはできますか? 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" のメッセージを 出ないようにすることはできますか? Q: 0) この FAQ の最新バージョンはどこで手に入れられますか? A: 回答: 最新版は comp.os.linux.announce に定期的にポストされており、主要 な Linux サイトに配付されています。例えば、 sunsite.unc.edu:/pub/Linux/docs/faqs その他の GCC, C, C++, g++, Objective-C の FAQ は多分 rtfm.mit.edu:pub/usenet/news.answers にあるでしょう。 Q: 1) 私が使っている GCC のバージョンを知るにはどうすればいいですか? A: 回答: 以下のコマンドを実行してください。 gcc -v あなたの使っている GCC のバージョンを確認できます。(この文章を) 書いて いる時点で私のマシンで上記のコマンドを実行すると、以下のように表 示されま す。 Reading specs from /usr/lib/gcc-lib/i386-linux/2.5.7/specs gcc version 2.5.7 これと同じものか、それ以上のバージョンにアップグレードする事をお 勧めしま す。 P.S もし、以下の出力結果を得たなら、 Reading specs from /usr/lib/gcc-lib/i486-linux/2.5.7/specs gcc version 2.5.7 486 用にコンパイルされた gcc を走らせることができます。 Q: 2) GCC,as,ld,ar, その他の最新版の配付はどこにありますか? A: 回答: GCC 配付の公式の場所は、tsx-11.mit.edu の /pub/linux/packages/ GCC です。 他のミラーサイトでも同様です。すべての GCC の現物の最新バージョン は、 ここで見つけられます。 (この文章を)書いている時点の最新の GCC は、バージョン 2.5.7 で あり、 以下の場所で手に入れました。 tsx-11.mit.edu:/pub/linux/packages/GCC/gcc-2.5.7-p1.tar.gz しかしながら、これは GNU foundation による GCC の利用できる最新バ ージョン のことを意味しているのではありません。最新の * 配付 * バージョン です。 Linux GCC のメンテをしている人々は、あなたのためにあなた自身が利 用できる 最新バージョンをコンパイルしやすいように作っています。GCC ソース とともに 配置するスクリプトがあなたのために用意されています。 もし、あなたが現物をコンパイルしたいなら、最新のインクルード(ヘ ッダ) ファイルが必要になるでしょう。(この文章を)書いている時点の最新 の インクルード(ファイル)は、以下から入手できます。 tsx-11.mit.edu:/pub/linux/packages/GCC/inc-4.5.8.tar.gz Q: 3) libc.so,libw.so の共有ライブラリの最新版はどこで見つけることがで きますか? A: 回答: 上の (2) を見てください。image*/tar.z ファイルが必要です。486 た めのイメ ージは、/pub/linux/packages/GCC/486 で見つけられます。 Q: 4) Linux で他にはどのような共有ライブラリが使えますか? 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 ======================================================================= ======= Q: 5) Linux 用の共有 DLL ライブラリを作るにはどうすればよいのですか? A: 回答: tsx-11.mit.edu から、以下のファイルを手に入れてインストールしてく ださい。 /pub/linux/packages/GCC/src/tools-2.10.tar.z 徹底的に doc サブディレクトリの README.tr ファイルを読んでくださ い。 たくさんの努力によりだれもが共有 DLL を作ることができるように読み やすく、 出来るかぎりのことが載せてあります。 もし、あなたが README.ps よりも日付の新しい README.tr を見つけ、 きれいな ポストスクリプトバージョンが欲しいならば、 README.tr を作りなおさ なければ ならないでしょう。しかし、groff を『必ず』インストールしなければ なりませ ん。doc サブディレクトリで、コマンド `make README.ps' を実行する だけで十 分です。 ** ノート: バージョンが変わっているかもしれません。 Q: 6) 完璧なバイナリを実行したのに,"PLT__oct__FUii" メッセージを受け取 るのはなぜですか? A: 回答: おそらく、あなたが持っている libc.so のバージョンが古い、且つ/ま たは、 誤ったバージョンの `ld' をを使ってプログラムをコンパイルしたから でしょ う。 解決方法は、tsx-11.mit.edu の /pub/linux/package/GCC/ binutils.tar.z の中 から新バージョンのバイナリユーティリティを手に入れることです。 Q: 7) プラットホーム XXX 上に Linux のコードをはきだすクロスコンパイラ を作るにはどうすればよいのでしょうか? 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 を行うべきです。 Q: 8) どのようなシンボルが Linux の GCC によって自動的に定義されますか ? A: 回答: シンボルは、`linux', `__unix__', '__i386__', `__linux__', `__unix', `__i386', `__linux' です。 正しいリストはコンパイル時にの gcc に -v フラグを使うことで表示さ れます。 P.s コンパイラを通してプログラムで "linux" は自動的に定義されます 。POSIX に準拠していま『せん』。__linux__ の代わりとしてオペレーティング システム のような特別なコンパイルプログラムが使うべきものです。__linux__ は POSIX に準拠していま『す』。 このことは、あなたの linux の特別なコードの回りを包むことができる ことを 意味しています。(例えば) #ifdef __linux__ ...[linux specific code here]... #endif /* ifdef linux */ Makefile に定義する特別な何かを加えなくて良いのです。 あなたは、ファイルにあなた自身の定義を加えるだけです。 /usr/lib/gcc-lib/i386-linux/2.5.7/specs Q: 9) コンパイル時に(sigvecといった特別なシグナルなどの) BSD の仕様を なくすにはどうすればいいですか? A: 回答: プログラムを -I/usr/include/bsd をつけてコンパイルし、-lbsd をつ けてリン クします。したがって、makefile の CFLAGS 行に -I/usr/include/bsd を、 LDFLAGS 行に -lbsd を追加します。もし、あなたが BSD 形式のシグナ ルの動き が必要ならば、-D__USE_BSD_SIGNAL を追加する必要は『ありません』。 それは、 -I/usr/include/bsd を使ったときに、自動的に追加されます。 Q: 10) SIGBUS, SIGEMT, SIGIOT, SIGTRAP, SIGSYS などはどこにありますか? A: 回答: Linux は 100% POSIX コンパチであり、これらは POSIX のシグナルでは ありま せん。簡単な方法としては、それらのシグナルを SIGUNUSED で再定義す ることで す。 /usr/include/bsd/signal.h の定義を見てください。 しかしながら、それらのシグナルがないことが、POSIX に『従う』こと を覚えて おくべきです。これらを SIGUNUSED で #define する代わりに、新しい プログラ ムは以下のようにすべきです。 #ifdef SIGSYS ....[non-posix sigsys code here].... #endif SIGSYS(SIGBUS も同様に)の使用が必要なコードとなります。 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990) の B.3.3.1.1 からの抜 粋です。 「SIGBUS, SIGEMT, SIGIOT, SIGTRAP と SIGSYS は、POSIX.1 から外され ました。 なぜなら、それらの動きは手段に頼っていますし、十分に分類することが できませ んでした。手段を一致させることによりこれらのシグナルは提供されたか もしれま せんが、それらを提供するときは事の次第を証明し、提供に関しての制限 を記述し なければなりません。 Q: 11) libhard と libsoft とは何ですか? A: 回答: それらは、数値エミュレーションルーチンのライブラリです。もし(例 えば 387 のような)数値演算を行うハードウェアを持っているなら hard を、そ のような ハードがないなら数値演算のエミュレーションを行う soft を選択しま す。 もし、現在配布している Linux を使用しているならば、これらのライブラ リは必要 『ありません』。数値演算エミュレーションはカーネルレベルでサポート していま す。(すなわち、もし、使いたいなら、`make config' によりカーネルが 作られた 時から使えます。) いいかえると 387 は仕事をすることができます。もし、/libm.so.4.x.y から /lib/libm.so.4 をリンクしているなら、安全に消すことができるかもしれ ません。 Q: 12) メッセージ "can't load library: /lib/libxxx.so, Incompatible version" の意味は何ですか? 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) を 見て、最新のライブラリを手に入れることです。 Q: 13) わたしのライブラリがとても大きいのはなぜですか?また、どうすれば 小さくなりますか? 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 をチェックしてください。 Q: 14) -N フラグを使うと何が起こりますか?また、どう使えばいいのですか ? A: 回答: 仮想記憶によるスワップが可能になります。-N オプションを使うと、ペ ージ境界 いっぱいに詰め込まれた個々のセグメント領域を持ち、それらが連続し ない実行 ファイルが使用できるようになります。Linux は、簡単に『忘れること 』によっ て割り当てられる(すっきりした)ページスワップを活用できます。な ぜなら、 いつもファイルから直接に再ロードできるからです。 他方、スワップパーティションやスワップファイルによる物理的なスワ ップ機能 も持っています。それには、多少の時間とディスクスペースが必要です 。 スワップは、通常は小さなプログラムには関係ありません。-N を使って コンパイ ルされていたとしてもです。大きなプログラム(例えば、gcc または emacs)、 または複数の段階を持っているようなプログラム(shell や xterm のよ うな もの)は、-N なしでコンパイルすべきです。その結果、コードページは きれいに 割り当てられます。もし、メモリ不足で(プログラムを)走らせたなら ば、 カーネルは仮想記憶で動いている使われていないコードページ(あとで 再ロード できる)を削除しはじめます。連続しない実行形式では不可能です。 したがって、もしあなたのプログラムが重要なたくさんのメモリを使用 するよう ならば、-N を使用しないか、カーネルのメモリ管理を妨げるしかないで しょう。 ハッキリとした `one-off' プログラムは、このフラグを使用してコンパ イルされ ています。すなわち、長時間メモリ上にとどまらないものです。例えば 、 hostname, fsck, mkfs, w などです。daemon では、この -N フラグを決 して 使用し『ない』で下さい。メモリ上に常駐することは意味がないからで す。 Q: 15) プログラムのデバッキング情報はどうすれば取れるのですか? 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) を使用しなければ、デバッグできないライブラ リコー ルもあるでしょう。 もし、性能のデバッグをしたいのならば、バイナリをストリップ化してい 『ない』 ことを確認してください。 Q: 16) どのデバッガが Linux で使えますか? A: 回答: え〜もちろん、一番いいデバッガは `gdb' です。お気に入りのサイトで 探してく ださい。例えば、 prep.ai.mit.edu:/pub/gnu/gdb-4.11.tar.gz にあります。 Linux 用のは sunsite.unc.edu:/pub/Linux/devel/gdb-4.11-bin.tar.gz にあります。 X デバッガは gdb を元としているので(すなわち、最初に gdb をインス トールす る必要がありますが)使用できます。ソースは ftp.x.org:/contrib/xxgdb-1.06.tar.Z にあります。 また、UPS デバッガは Rick Sladkey 氏により作られました。それは xxgdb と同 様に X 配下で動作しますが、似ていません。単なる X のテキストベース のデバッ ガではありません。良い特徴をたくさん持っており、もし、デバッグ材料 に時間を 費やすならば、材料をチェックアウトすべきでしょう。UPS の Linux 用の パッチは sunsite.unc.edu:/pub/Linux/devel/ ups-2.45.2-linux-0.1.diff.gz で見つけられます。また、近くの X アーカイブまたは ftp.x.org:/contrib/ups-2.45.2.tar.Z から、フルソースを手に入れる必要があるでしょう。 Q: 17) daemon プログラムをデバッグする方法は? A: 回答: 簡単に書くと、デバックする前に fork していない、daemon プログラム を手に 入れなければなりません。 しかしながら、`gdb' デバッガを使用するということは、fork『後』の daemon に attach できるということです。gdb にデバッグしたいプロセスの id を 伝えるこ とでデバッグできます。 これには、`attach' コマンドを使ってください。GDB の完全なオンライン ヘルプは ここでは役に立ちます。 また、ソースを入手してなくても、バイナリがストリップされているなら ば、 `strace' プログラムを手に入れ、daemon のプロセス id に割当て、出力 を検査す ることができます。 もし、探しかたを知っていたならば、有効な方法です。 Q: 18) profiling とは何ですか?また、プログラムを profile するにはどの ようにすればよいのでしょうか? A: 回答: profiling とは、どこでどの動作で時間が費やされたか、たくさんの( システム コールが一定の関数によって作られたか、また、全実行時間を調べる方法 です。 コードの最適化やどこで不必要に時間が浪費しているかを見るには良い方 法です。 全てのオブジェクトとリンクを profiling するには、-p フラグでコンパ イルしな ければなりません。質問 (15) の profiling に必要なライブラリの入手場 所を見て ください。 実際に graph profile を手に入れるには、`grof' というプログラムが必 要です。 それは、バイナリユーティリティパッケージに入っています。 くりかえしますと、あなたの行きつけの Linux アーカイブサイトで見つけ てくださ い。例えば、 tsx-11.mit.edu:/pub/linux/packages/GCC/binutils.tar.z Q: 19) もし、バイナリが静的にまたは共有ライブラリにリンクされていた場合 に、それを調べる方法はありますか? 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' はバージョンによっては、なにか別の結果を出力をす るかもし れません。 Q: 20) Linux は LD_LIBRARY_PATH をサポートしていますか? 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 をセットする問題を解決し、適切なユーザーのバ イナリ を実行します。 Q: 21) 私のプログラムでは /lib/cpp が必要です。どこから手に入れたらよい のでしょうか? A: 回答: cpp は /usr/lib/gcc-lib/i386-linux/2.5.7 の中にあります。 (gcc のバージョンナンバーは変わっているかもしれません) 以下のコマンドを実行してください。 % cd /lib; ln -sf /usr/lib/gcc-lib/i486-linux/2.5.7/cpp ** 2.5.7 はあなたの使っている GCC のものにしてください。 ** 386 のコンパイラを使っているなら、i486 を i386 にしてください。 他の方法で、よりよい解決方法はこちらです。 % cat > /lib/cpp #!/bin/sh cc -E "$@" Ctrl-D[EOF] この方法は、新しい gcc にして、古い gcc を削除したときに /lib/cpp が動かな くなるかもしれません。 Q: 22) はどこですか? A: 回答: varargs.h は、/usr/lib/gcc-lib/i386-linux/2.5.7/include の中の他 のシステ ムに存したファイルにあります。 は、K&R にあるものです。gcc のデフォルトは ANSI です。 を代わりに使うべきでしょう。 ** バージョンナンバ 2.5.7 は、あなたの使っている GCC のバージョンに 置き換え て下さい。 ** もし、486 用のコンパイラを使っているなら、i386 を i486 に変更し てくださ い。 Q: 23) 私のプログラムで、 をインクルードしたいのですが、見 つけることができません。どこにあるのでしょうか? A: 回答: いくつかのインクルードファイルは、カーネルのバージョンに依存して おり、 このように、カーネルのリリースごとになっています。最新のカーネルの ソースを 手に入れる必要があり、展開後、リンクを張る必要があります。 もし、/usr/src があり、さらにカーネルのソースがあるなら、以下のコマ ンドを 実行してください。 % cd /usr/include % ln -sf /usr/src/linux/include/linux % ln -sf /usr/src/linux/include/asm MCC リリースはそれらのリンクを始めから持っていません。したがって、 新しい カーネルのソースツリーをインストールしても古いインクルードファイル を使用す ることができます。注意してください。 Q: 24) foo() 関数はライブラリに入っているのでしょうか? A: 回答: 関数がライブラリに入っているかどうか調べる方法は、以下に示すとお りです。 flock() 関数がサポートされているかどうかを調べるのは以下のようにし ます。 % nm /usr/lib/libc.a | grep flock 次のような出力結果の場合は、 00000000 T flock flock() 関数が libc.a/libc.sa. に定義されています。 次のような出力結果の場合は、 00000000 U flock flock() が参照できることを示します。`U' は、flock がどこかで定義さ れてお り、情報を解析することで場所がわかるライブラリをインクルードする必 要があ ることを意味しています。 Q: 25) プログラム XXX を Linux に持ってくるにはどうすればいいですか? 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)); に変更します。 Q: 26) gcc/library の foo でバグを見つけたのですが、どうすればよいので しょうか? A: 回答: 本当ですか? えっと、もし、プログラムが異常終了、または期待通りに動かないならば 、まず 最初に試してみて、数行にコードを絞り込んで、確認してください。 静的バージョンと共有バージョンどちらでも発生しますか? (すなわち、DLL ライブラリと静的ライブラリどちらかの問題でしょうか ?) gcc の走る別のマシンを使うことはできますか?言い換えると、Linux/ GCC のみで なく、GCC 全体の問題ですか?もしそうなら以下に示す USENET のニュー スグルー プに投稿したほうがよいかもしれません。 gnu.gcc.bug, gnu.gcc.help, gnu.g++.help, comp.lang.c, or comp.lang.c++. 問題は数値演算エミュレータですか?もしそうなら、数値演算エミュレー タの作者 である Bill Metzenthen 氏 (apm233m@vaxc.cc.monash.edu.au) にメール した ほうがよいかもしれません。 結局、linux-bugs@sunsite.unc.edu か、私 (mitchum.dsouza@mrc-apu.cam.ac.uk) か、HLU にでもメールすべきでしょう。 Q: 27) 共有ライブラリが同じ機能を持った静的ライブラリより大きくなるのは 何故ですか? A: 回答: 共有ライブラリはディスクスペース不足時でも拡張できるようにするた めに `holes' という形でスペースを予約しています。`makehole' を呼び出す、 または 使用する簡単な `cp' はこの予約領域を使用します。 あなたは、ライブラリを作成後に小さくすることができます。 Q: 28) /usr/lib 内にある .sa ファイルとは何ですか? A: 回答: .sa ファイルとは、共有ライブラリから抜き出たものであり、正当なラ イブラリ から取り出したすべてのグローバル変数を含み、ランタイムをリンクする ために 必要な関数をポイントしています。質問 (13) を参照してください。 Q: 29) Linux 用のオブジェクト指向の C はどこで手に入れられますか? A: 回答: オブジェクト指向の C は gcc の 2.4.0 以上のバージョンでリリースさ れていま す。これは、目下テスト中です。最新バージョンは以下のものです。 tsx-11.mit.edu:/pub/linux/packages/GCC/gcc-2.5.7-p2.tar.gz Q: 30) "Internal compiler error: cc1 got fatal signal 11" のメッセージ の意味は何ですか? A: 回答: GCC はたぶんプログラムを走らせるために貪欲にメモリを消費し、きっ と RAM の領域を食いつぶしたのでしょう。普通、致命的シグナルの 11 は、RAM の パリティエラーやハード障害を意味しています。私もハードディスクの不 良ブロッ クのせいで cc1 で同じ状態に陥ったことがあります。それは、チップのオ ーバー ヒート(フレンチフライではありません)によるエラーとして報告されて います。 また、低機能の IDE コントローラとドライブで 8MHz AT バスクロック以 上で走ら せようとすると発生します。これはスワップスペースの変造を引き起こす ことによ り同じエラーとなります。 一般に、シグナル 11 (セグメンテーション・バイオレーション)は、プロ セスス ペース不足状態ででメモリをアクセスに行った、またはリードオンリー領 域に書き 込みに行ったことを意味しています。たまに、このシグナルはソフトのバ グで発生 することもあり、ハード障害とは限りません。(またはシステムの繰り返 し ハング。なぜならカーネルで同じ事が起きるからです。)gcc 2.3.3 では 、何人か がたくさんの”シグナル 11”を再現しました。 また、`ld' や `as' の最中の障害としても発生します。もし、cc1, cpp, または ld に問題があるとすれば、gcc で -v フラグを付けてリコンパイルして確 認して みてください。 Q: 31) libc.lite とは何ですか? A: 回答: libc.lite とは、フロッピー運用でほとんどの卑しい(訳注:意味不明) UNIX の タスクを満足するための libc ライブラリの軽いバージョンですこれには 、curses, dbm, termcap などのコードを含んでいません。もし、あなたの /lib/ libc.so.4 が 軽いライブラリをリンクしているならば、フルバージョンに置き換える事 をお勧め します。どこで手に入れられるかは質問 (3) を参照してください。 Q: 32) Linux のライブラリは SHADOW Password をサポートしてますか?また 、オン・オフはどうすればよいのですか? A: 回答: サポートしています。 適当な場所に SHADOW_PWD を定義してコンパイルし、shadow ライブラリを リンク する必要があります。shadow ライブラリは以下で入手できます。 sunsite.unc.edu:/pub/Linux/distributions/SLS/a4/shadow.tgz 具体的には Makefile の CFLAGS 行に -DSHADOW_PWD フラグを、LDFLAGS 行に -lshadow フラグを追加すればいいのです。 ソースビットを変更しなければならないかもしれませんし、shadow をサポ ートし た "cript()" は関数ではなく、マクロとして提供されます。 それゆえ、すべての "extern int crypt()" でもつまづくかもしれません 。 これは、getpwent(), setpwent() その他のルーチンを使った『すべての』 必要な バイナリをコンパイルすることなしでは、shadow password のオン・オフ を行う 方法が『ない』ことを意味しています。 Q: 33) math.h ルーチンが見つかりません。プログラムをコンパイルしている のですが、 log(), sin() などが見つかりません。だれか、助けて! A: 回答: 正しい関数を使用したプログラムをコンパイルしている場合、適切なラ イブラリ をプログラムに『必ず』リンクしなければなりません。数値演算関数を使 うには リンク時に libm.a をインクルードしなければならないということです。 言い換え ると LDFLAGS に -lm を、curses 関数では -lcurses を dbm 関数では -ldbm など を加える必要があります。 普通は、オブジェクトの後に -lm フラグを置きます。 % gcc -lm -o math_prog math_prog.c は、まずいやり方で数値演算関数は解析できません。そうではなく、 % gcc -o math_prog math_prog.c -lm と入力してください。 Q: 34) GCC のマニュアルはありますか?もしあるなら、どこで手に入れられま すか?また、どうすれば印刷できますか? 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 を使 用して見ることができます。『情報』ファイルは情報システムに基づいた ハイパー テキスト形式です。 Q: 35) "Undefined symbol _bsd_ioctl" のメッセージが出ました。どうすれば いいのですか? A: 回答: リンク時に /usr/lib/libbsd.a という bsd のライブラリをインクルー ドするこ とを忘れています。 解決方法: Makefile の LDFLAGS 行に -lbsd フラグを加えてください。( LDFLAGS 行が無い場合は手動で加えてください) Q: 36) バージョンアップするときは、/usr/lib/gcc-lib/i[34]86-linux/ から古いものを取り除くことはできますか? A: 回答: えっと、もし、gcc のテストバージョンでなければ、ディレクトリから 古い バージョンを取り除くことは全く問題ありません。 "gcc -V " とすることで古いバージョンの GCC でコンパイルすることができます 。 Q: 37) 『助けて』libipc.a はどこですか?dosemu 0.49 のために必要なので すが。 A: 回答: Inter Process Communication (IPC) 関数は標準の libc >= libc.so.4.4.1 に あります。もし、あなたが持っている libc が libc.so.4.4.1 以上だった 場合は、 -lipc は必要ありません。Makefile からその行を消してください。もし、 libc.so.4.4.1 未満だった場合は、ライブラリをバージョンアップしてく ださい。 Q: 38) XXX がコンパイルできません。_daemon が未定義になります。だれか助 けて!! A: 回答: daemon() は libbsd.a に入っています。-lbsd を Makefile の LDFLAGS 行に 加えてください。 Q: 39) 『助けて』ar とライブラリについてです。シンボルはライブラリにあ るのですが、リンクに失敗します。 A: 回答: しばしば `ranlib' が正しいテーブルを作らないという `ar'のバグです 。 以下のコマンドを打ち込めば動くようになります。 % ar -dv libfoo.a __.SYMDEF % ranlib libfoo.a Q: 40) 助けて!初心者なのですが、"libc.so.4: incompat. minor ver no." というワーニングメッセージがでて困っています。 A: 回答: 共有ライブラリのバージョンアップが必要です。質問 12 と 3 の概要を 見てくだ さい。 Q: 41) c のプログラムのコンパイルの前にチェックする `lint' はどこですか ? A: 回答: `lint' のようなプログラムをチェックするようなものはありません。そ の代わり にプログラムをチェックするには gcc の過度のオプションを使います。マ ニュアル に書いてあるいろいろなオプションを見てください。 最も効果的なものは以下のオプションです。 % gcc -Wall foo.c このオプションは起こるであろう可能な限りのワーニングを出力します。 Q: 42) 私のプログラムで sgtty.h が必要なのですが、どこにあるのでしょう か? A: 回答: sgtty.h は /usr/include/bsd ディレクトリに入ります。コンパイル時 に Makefile の CFLAGS 行に以下の行を追加してください。 -I/usr/include/bsd Q: 43) SIGSEGV によるコアファイルの作成を禁止したり、許可したりするには どうすればよいのでしょうか? A: 回答: これは本当は GCC の質問ではなく、shell の質問なのですが、なにがな んでも 完全にコアファイルを作らなくするには C-shell `csh' (tcsh) の場合 % limit core 0 Bourne shell `sh' (bash) の場合 % ulimit -c 0 を実行してください。 シグナル 11 (SEGV) を受け取った時のみ、コアファイルを作るようにする には C-shell `csh' (tcsh) の場合 % limit core unlimited Bourne shell `sh' (bash) の場合 % ulimit -c unlimited を実行してください。 Q: 44) "can't load dynamic linker `/lib/ld.so'" のメッセージの意味は何 ですか? A: 回答: これは、動的リンカ/ローダがインストールされていないことを意味し ていま す。質問 4 の libld.so の入手方法を参照してください。 Q: 45) -O2 と -O6 での効率の違いは何ですか? A: 回答: 現在はありません。もし、あなたが i386/i486 のホスト / ターゲット として GCC のソースコードを見ているなら、-Ox で x>2 の場合は同じもので ある ことがわかるでしょう。実際、Makefile で x>2 を使用することは悪い こと です。なぜなら、GCC が将来 -O3 といった最適化オプションをインテ ル(の チップ)をターゲット採用するかもしれないため、その最適化によって 出力 されるコードが破壊されるかもしれません。 Q: 46) 出所不明のバイナリがトロイの木馬のようなウィルスに感染しているか どうかチェックする方法は? A: 回答: 最初に、もし、あなたのマシンがウィルスに感染しているか心配ならば 、動かさ 『ない』ことです(少なくとも root では)。そして、ソースを見つけて リコンパ イルしてください。他の方法としては、"string | less" と 入力することで何らかの情報が手に入るかもしれません。もし、動かす賭 に出る ならば、何か不穏な動きを探るために "strace" を使うことができます。 Q: 47) C ライブラリのソースはどこにありますか?またリビルドする方法は? A: 回答: 以下のサイトのモジュールを参照してください。 tsx-11.mit.edu:/pub/linux/pagkages/GCC/libc-4.5.8.tar.gz もし、共有ライブラリが欲しいなら、dll ツールパッケージが必要になる でしょ う。質問 (5) の入手場所を参照してください。 Q: 48) FD_* の定義はどこにありますか? A: 回答: に含まれていて、マクロも追加されるでしょう。 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. なにが悪いのでしょうか ? A: 回答: libc.sa の crt0.o と libc.sa と libc.a を最近の linux の libc に アップデ ートする必要があります。しかし、古い libg.a 関係が残ってしまいます 。 もし、本当にデバッグライブラリによるスタティックバイナリ(-g の意味 する) が必要ならば、libg.a を入手してインストールすべきです。 これについては質問 (15) を見てください。 Q: 50) わたしのライブラリやアプリケーションを国際化するツールはどこで手 に入りますか? A: 回答: 以下のファイルを手に入れてください。 sunsite.unc.edu:/pub/Linux/utils/nls/cat-pack.tar.gz そして、指示に従ってください。 ユーザが作ったいろいろな言語によるカタログは以下のところで見つけら れます。 sunsite.unc.edu:/pub/Linux/utils/nls/catalogs それらを入るべきディレクトリに導入します。 注1: 国際化ツールと関数はバージョン 4.4.4(例えば、libc.so.4.5.x 以上)で 使用可能です。 注2: linux における『国際化』の状況は遅れており、linux pl14 で Latin-1/ISO-8859-1 のキャラクターセットがやっとサポートされたような 状態で す。 Q: 51) `mkimage' という DLL ツールが libgcc のなかに見つかりません。助 けてください。 A: 回答: libc.so.4.5.x 以上では、libgcc はすでに共有ではありません。 したがって、mkimage の `-lgcc' の部分を以下のように置き換えなければ なりませ ん。 `gcc -print-libgcc-file-name` 短くすると `gcc --print` です。バッククォートは必要ありません。 Q: 52) "__NEEDS_SHRLIB_libc_4 multiply defined" のメッセージを出ないよ うにするにはどうすればいいのでしょうか? A: 回答: libc.sa.4.5.x 以上では libgcc は共有ではなくなっています。したが って、 /usr/lib/libgcc* ファイルをすべて削除し『なければ』なりません。 % rm -f /usr/lib/libgcc* Q: 53) QMAGIC というのは、一般的にはどういうものですか? A: 回答: QMAGIC はスタンダードの a.out (ZMAGIC といった)のような実行形式 のフォー マットです。しかし、マッピングされない最初のページに置かれます。こ のことに より、0-4096 の範囲でマッピングされないトラップとして簡単に『まった く』同じ 方法で実現できます。それに対し、あなたのバイナリ側への影響はほとん どありま せん。(~1K) /etc/magic ファイルに正しく登録すれば、あなたの `file' コマンドは QMAGIC バ イナリと同じにすることができます。わたしは、ほとんどのチャネルに適 当な エントリーを配付しています。 Q: 54) どのようにすれば、QMAGIC の実行ファイルやライブラリを作成できま すか? A: 回答: QMAGIC の実行ファイルを作るには、最新の `ld' のバイナリやソースの パッチが 必要です。`binutils-as.tar.gz' というファイルが配付されています。質 問 (6) を参照してください。 QMAGIC 実行ファイルの作り方: Makefile 中の LDFLAGS 行に以下の部分を追加します。 LDFLAGS = -Wl,-qmagic または LDFLAGS = -Xlinker -qmagic QMAGIC ライブラリの作り方: ごめんなさい。`mkimage' の使い方がいまいちわかりません。もう少し 待ってく ださい。 Q: 55) "warning using incompatable library version xxx" のメッセージを 出ないようにすることはできますか? 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 -- comp.os.linux.announce へのご意見は linux-announce@tc.cornell.edu まで 。