===================================================================== Linux GCC FAQ 1994/02/01 版 Mitchum DSouza, 著 日本語訳 萩尾 勝巳(VIC) (NIFTY-Serve GAA00714) 日本語訳日付 1995/02/11 ===================================================================== -------------------- Linux GCC FAQ 1994/02/01 版 ----------------------------- 0) この FAQ の最新バージョンはどこで手に入れられますか? 1) 私が使っている GCC のバージョンを知るにはどうすればいいですか? 2) GCC,as,ld,ar, その他の最新版の配付はどこにありますか? 3) libc.so,libw.so の共有ライブラリの最新版はどこで見つけることができますか? 4) Linux で他にはどのような共有ライブラリが使えますか? 5) Linux 用の共有 DLL ライブラリを作るにはどうすればよいのですか? 6) 完璧なバイナリを実行したのに,"PLT__oct__FUii" メッセージを受け取るのはなぜ ですか? 7) プラットホーム XXX 上に Linux のコードをはきだすクロスコンパイラを作るにはど うすればよいのでしょうか? 8) どのようなシンボルが Linux の GCC によって自動的に定義されますか? 9) コンパイル時に (sigvecといった特別なシグナルなどの) BSD の仕様をなくすには どうすればいいですか? 10) SIGBUS, SIGEMT, SIGIOT, SIGTRAP, SIGSYS などはどこにありますか? 11) libhard と libsoft とは何ですか? 12) メッセージ "can't load library: /lib/libxxx.so, Incompatible version" の意 味は何ですか? 13) わたしのライブラリがとても大きいのはなぜですか?また、どうすれば小さくなり ますか? 14) -N フラグを使うと何が起こりますか?また、どう使えばいいのですか? 15) プログラムのデバッキング情報はどうすれば取れるのですか? 16) どのデバッカが Linux で使えますか? 17) daemon プログラムをデバッグする方法は? 18) profiling とは何ですか?また、プログラムを profile するにはどのようにすれば よいのでしょうか? 19) もし、バイナリが静的にまたは共有ライブラリにリンクされていた場合に、それを 調べる方法はありますか? 20) Linux は LD_LIBRARY_PATH をサポートしていますか? 21) 私のプログラムでは /lib/cpp が必要です。どこから手に入れたらよいのでしょう か? 22) はどこですか? 23) 私のプログラムで、 をインクルードしたいのですが、見つけること ができません。どこにあるのでしょうか? 24) foo() 関数はライブラリに入っているのでしょうか? 25) プログラム XXX を Linux に移植するにはどうすればいいですか? 26) gcc/library の foo でバグを見つけたのですが、どうすればよいのでしょうか? 27) 共有ライブラリが同じ機能を持った静的ライブラリより大きくなるのはなぜです か? 28) /usr/lib 内にある .sa ファイルとは何ですか? 29) Linux 用のオブジェクト指向の C はどこで手に入れられますか? 30) "Internal compiler error: cc1 got fatal signal 11" のメッセージの意味は何で すか? 31) libc.lite とは何ですか? 32) Linux のライブラリは SHADOW Password をサポートしてますか? また、オン・オフはどうすればよいのですか? 33) math.h ルーチンが見つかりません。プログラムで log(), sin() などを使用してい ます。助けてください! 34) GCC のマニュアルはありますか?もしあるなら、どこで手に入れられますか? また、どうすれば印刷できますか? 35) "Undefined symbol _bsd_ioctl" のメッセージが出ました。どうすればいいのです か? 36) バージョンアップするときは、/usr/lib/gcc-lib/i[34]86-linux/ から古い STUFF を取り除くことはできますか? 37) 『助けて』libipc.a はどこですか?dosemu 0.49 のために必要なのですが。 38) XXX がコンパイルできません。_deamon が未定義になります。だれか助けて!! 39) 『助けて』ar と ライブラリについてです。シンボルはライブラリにあるのです が、リンクに失敗します。 40) 助けて!初心者なのですが、 "libc.so.4: incompat. minor ver no." というワー ニングメッセージがでて困っています。 41) c のプログラムのコンパイルの前にチェックする `lint' はどこですか? 42) 私のプログラムで sgtty.h が必要なのですが、どこにあるのでしょうか? 43) SIGSEGV によるコアファイルを止めたり走らせたりするにはどうすればよいので しょうか? 44) "can't load dynamic linker `/lib/ld.so'" のメッセージの意味は何ですか? 45) -O2 と -O6 のオプションの違いは何ですか? 46) 出所不明のバイナリがトロイの木馬のようなウィルスに感染しているかどうか チェックする方法は? 47) C ライブラリのソースはどこにありますか?またリビルドする方法は? 48) FD_* の定義はどこにありますか? 49) -g オプション付でリンクしたら、__fpu_control と ___setfpucw が未定義だと言 われてしまったのですが。 50) わたしのライブラリやアプリケーションを国際化するツールはどこで手に入ります か? 51) `mkimage' という DLL ツールが libgcc のなかに見つかりません。助けてくださ い。 52) "__NEEDS_SHRLIB_libc_4 multiply defined" のメッセージを出ないようにするには どうすればいいのでしょうか? 53) QMAGIC というのは一般的にはどういうものですか? 54) どのようにすれば、QMAGIC の実行ファイルやライブラリを作成できますか? 55) "warning using incompatable library version xxx" のメッセージを出ないように することはできますか? ------------------------------------------------------------------------------- 0) この FAQ の最新バージョンはどこで手に入れられますか? 回答: 最新版は 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 にあるでしょう。 ------------------------------------------------------------------------------- 1) 私が使っている GCC のバージョンを知るにはどうすればいいですか? 回答: 以下のコマンドを実行してください。 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 を走らせることができます。 ------------------------------------------------------------------------------- 2) GCC,as,ld,ar, その他の最新版の配付はどこにありますか? 回答: 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 ------------------------------------------------------------------------------- 3) libc.so,libw.so の共有ライブラリの最新版はどこで見つけることができますか? 回答: 上の (2) を見てください。image*/tar.z ファイルが必要です。486 ためのイメ ージは、/pub/linux/packages/GCC/486 で見つけられます。 ------------------------------------------------------------------------------- 4) Linux で他にはどのような共有ライブラリが使えますか? 回答: 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 ============================================================================== ------------------------------------------------------------------------------- 5) Linux 用の共有 DLL ライブラリを作るにはどうすればよいのですか? 回答: 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' を実行するだけで十 分です。 ** ノート: バージョンが変わっているかもしれません。 ------------------------------------------------------------------------------- 6) 完璧なバイナリを実行したのに,"PLT__oct__FUii" メッセージを受け取るのはなぜ ですか? 回答: おそらく、あなたが持っている libc.so のバージョンが古い、且つ/または、 誤ったバージョンの `ld' をを使ってプログラムをコンパイルしたからでしょ う。 解決方法は、tsx-11.mit.edu の /pub/linux/package/GCC/binutils.tar.z の中 から新バージョンのバイナリユーティリティを手に入れることです。 ------------------------------------------------------------------------------- 7) プラットホーム XXX 上に Linux のコードをはきだすクロスコンパイラを作るにはど うすればよいのでしょうか? 回答: 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 を行うべきです。 ------------------------------------------------------------------------------- 8) どのようなシンボルが Linux の GCC によって自動的に定義されますか? 回答: シンボルは、`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 ------------------------------------------------------------------------------- 9) コンパイル時に (sigvecといった特別なシグナルなどの) BSD の仕様をなくすには どうすればいいですか? 回答: プログラムを -I/usr/include/bsd をつけてコンパイルし、-lbsd をつけてリン クします。したがって、makefile の CFLAGS 行に -I/usr/include/bsd を、 LDFLAGS 行に -lbsd を追加します。もし、あなたが BSD 形式のシグナルの動きが 必要ならば、-D__USE_BSD_SIGNAL を追加する必要は『ありません』。それは、 -I/usr/include/bsd を使ったときに、自動的に追加されます。 ------------------------------------------------------------------------------- 10) SIGBUS, SIGEMT, SIGIOT, SIGTRAP, SIGSYS などはどこにありますか? 回答: 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 から外されました。 なぜなら、それらの動きは手段に頼っていますし、十分に分類することができませ んでした。手段を一致させることによりこれらのシグナルは提供されたかもしれま せんが、それらを提供するときは事の次第を証明し、提供に関しての制限を記述し なければなりません。 ------------------------------------------------------------------------------- 11) libhard と libsoft とは何ですか? 回答: それらは、数値エミュレーションルーチンのライブラリです。もし(例えば 387 のような)数値演算を行うハードウェアを持っているなら hard を、そのようなハ ードがないなら数値演算のエミュレーションを行う soft を選択します。 もし、現在配布している Linux を使用しているならば、これらのライブラリは必要 『ありません』。数値演算エミュレーションはカーネルレベルでサポートしていま す。(すなわち、もし、使いたいなら、`make config' によりカーネルが作られた 時から使えます。) いいかえると 387 は仕事をすることができます。もし、/libm.so.4.x.y から /lib/libm.so.4 をリンクしているなら、安全に消すことができるかもしれません。 ------------------------------------------------------------------------------- 12) メッセージ "can't load library: /lib/libxxx.so, Incompatible version" の意 味は何ですか? 回答: 共有ライブラリが発展していくと、プログラム実行時にクラッシュを引き起こす ようになったり、制限ができたりします。それをはっきりさせるために、バージョ ンによって分類する必要があります。例えば、ファンクションコールがまるっきり 変わる、または無くなってしまった場合などがそうです。 ライブラリの呼び名 - 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) を 見て、最新のライブラリを手に入れることです。 ------------------------------------------------------------------------------- 13) わたしのライブラリがとても大きいのはなぜですか?また、どうすれば小さくなり ますか? 回答: より小さいライブラリが欲しいなら、すべきことはたくさんあります。 * コードの最適化 - コンパイル時に -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 をチェックしてください。 ------------------------------------------------------------------------------- 14) -N フラグを使うと何が起こりますか?また、どう使えばいいのですか? 回答: 仮想記憶によるスワップが可能になります。-N オプションを使うと、ページ境界 いっぱいに詰め込まれた個々のセグメント領域を持ち、それらが連続しない実行 ファイルが使用できるようになります。Linux は、簡単に『忘れること』によって 割り当てられる(すっきりした)ページスワップを活用できます。なぜなら、いつ もファイルから直接に再ロードできるからです。 他方、スワップパーティションやスワップファイルによる物理的なスワップ機能も 持っています。それには、多少の時間とディスクスペースが必要です。 スワップは、通常は小さなプログラムには関係ありません。-N を使ってコンパイル されていたとしてもです。大きなプログラム(例えば、gcc または emacs)、また は複数の段階を持っているようなプログラム(shell や xterm のようなもの)は、 -N なしでコンパイルすべきです。その結果、コードページはきれいに割り当てられ ます。もし、メモリ不足で(プログラムを)走らせたならば、カーネルは仮想記憶 で動いている使われていないコードページ(あとで再ロードできる)を削除しはじ めます。連続しない実行形式では不可能です。 したがって、もしあなたのプログラムが重要なたくさんのメモリを使用するような らば、-N を使用しないか、カーネルのメモリ管理を妨げるしかないでしょう。 ハッキリとした `one-off' プログラムは、このフラグを使用してコンパイルされて います。すなわち、長時間メモリ上にとどまらないものです。例えば、hostname, fsck, mkfs, w などです。daemon では、この -N フラグを決して使用し『ない』 で下さい。メモリ上に常駐することは意味がないからです。 ------------------------------------------------------------------------------- 15) プログラムのデバッキング情報はどうすれば取れるのですか? 回答: プログラムをコンパイルすることが必要です。(すなわち、すべてのオブジェク ト)そして、-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) を使用しなければ、デバッグできないライブラリコー ルもあるでしょう。 もし、性能のデバッグをしたいのならば、バイナリをストリップ化してい『ない』 ことを確認してください。 ------------------------------------------------------------------------------- 16) どのデバッガが Linux で使えますか? 回答: え〜もちろん、一番いいデバッガは `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 から、フルソースを手に入れる必要があるでしょう。 ------------------------------------------------------------------------------- 17) daemon プログラムをデバッグする方法は? 回答: 簡単に書くと、デバックする前に fork していない、daemon プログラムを手に 入れなければなりません。 しかしながら、`gdb' デバッガを使用するということは、fork『後』の daemon に attach できるということです。gdb にデバッグしたいプロセスの id を伝えるこ とでデバッグできます。 これには、`attach' コマンドを使ってください。GDB の完全なオンラインヘルプは ここでは役に立ちます。 また、ソースを入手してなくても、バイナリがストリップされているならば、 `strace' プログラムを手に入れ、daemon のプロセス id に割当て、出力を検査す ることができます。 もし、探しかたを知っていたならば、有効な方法です。 ------------------------------------------------------------------------------- 18) profiling とは何ですか?また、プログラムを profile するにはどのようにすれば よいのでしょうか? 回答: profiling とは、どこでどの動作で時間が費やされたか、たくさんの(システム コールが一定の関数によって作られたか、また、全実行時間を調べる方法です。 コードの最適化やどこで不必要に時間が浪費しているかを見るには良い方法です。 全てのオブジェクトとリンクを profiling するには、-p フラグでコンパイルしな ければなりません。質問 (15) の profiling に必要なライブラリの入手場所を見て ください。 実際に graph profile を手に入れるには、`grof' というプログラムが必要です。 それは、バイナリユーティリティパッケージに入っています。 くりかえしますと、あなたの行きつけの Linux アーカイブサイトで見つけてくださ い。例えば、 tsx-11.mit.edu:/pub/linux/packages/GCC/binutils.tar.z ------------------------------------------------------------------------------- 19) もし、バイナリが静的にまたは共有ライブラリにリンクされていた場合に、それを 調べる方法はありますか? 回答: はいあります。 `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' はバージョンによっては、なにか別の結果を出力をするかもし れません。 ------------------------------------------------------------------------------- 20) Linux は LD_LIBRARY_PATH をサポートしていますか? 回答: はいといいえです。バイナリのコンパイル時に使用した 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 をセットする問題を解決し、適切なユーザーのバイナリを実行しま す。 ------------------------------------------------------------------------------- 21) 私のプログラムでは /lib/cpp が必要です。どこから手に入れたらよいのでしょう か? 回答: 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 が動かな くなるかもしれません。 ------------------------------------------------------------------------------- 22) はどこですか? 回答: varargs.h は、/usr/lib/gcc-lib/i386-linux/2.5.7/include の中の他のシステ ムに存したファイルにあります。 は、K&R にあるものです。gcc のデフォルトは ANSI です。 を代わりに使うべきでしょう。 ** バージョンナンバ 2.5.7 は、あなたの使っている GCC のバージョンに置き換え て下さい。 ** もし、486 用のコンパイラを使っているなら、i386 を i486 に変更してくださ い。 ------------------------------------------------------------------------------- 23) 私のプログラムで、 をインクルードしたいのですが、見つけること ができません。どこにあるのでしょうか? 回答: いくつかのインクルードファイルは、カーネルのバージョンに依存しており、 このように、カーネルのリリースごとになっています。最新のカーネルのソースを 手に入れる必要があり、展開後、リンクを張る必要があります。 もし、/usr/src があり、さらにカーネルのソースがあるなら、以下のコマンドを 実行してください。 % cd /usr/include % ln -sf /usr/src/linux/include/linux % ln -sf /usr/src/linux/include/asm MCC リリースはそれらのリンクを始めから持っていません。したがって、新しい カーネルのソースツリーをインストールしても古いインクルードファイルを使用す ることができます。注意してください。 ------------------------------------------------------------------------------- 24) foo() 関数はライブラリに入っているのでしょうか? 回答: 関数がライブラリに入っているかどうか調べる方法は、以下に示すとおりです。 flock() 関数がサポートされているかどうかを調べるのは以下のようにします。 % nm /usr/lib/libc.a | grep flock 次のような出力結果の場合は、 00000000 T flock flock() 関数が libc.a/libc.sa. に定義されています。 次のような出力結果の場合は、 00000000 U flock flock() が参照できることを示します。`U' は、flock がどこかで定義されてお り、情報を解析することで場所がわかるライブラリをインクルードする必要があ ることを意味しています。 ------------------------------------------------------------------------------- 25) プログラム XXX を Linux に持ってくるにはどうすればいいですか? 回答: だれかが、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)); に変更します。 ------------------------------------------------------------------------------- 26) gcc/library の foo でバグを見つけたのですが、どうすればよいのでしょうか? 回答: 本当ですか? えっと、もし、プログラムが異常終了、または期待通りに動かないならば、まず 最初に試してみて、数行にコードを絞り込んで、確認してください。 静的バージョンと共有バージョンどちらでも発生しますか? (すなわち、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 にでもメールすべきでしょう。 ------------------------------------------------------------------------------- 27) 共有ライブラリが同じ機能を持った静的ライブラリより大きくなるのは何故です か? 回答: 共有ライブラリはディスクスペース不足時でも拡張できるようにするために `holes' という形でスペースを予約しています。`makehole' を呼び出す、または 使用する簡単な `cp' はこの予約領域を使用します。 あなたは、ライブラリを作成後に小さくすることができます。 ------------------------------------------------------------------------------- 28) /usr/lib 内にある .sa ファイルとは何ですか? 回答: .sa ファイルとは、共有ライブラリから抜き出たものであり、正当なライブラリ から取り出したすべてのグローバル変数を含み、ランタイムをリンクするために 必要な関数をポイントしています。質問 (13) を参照してください。 ------------------------------------------------------------------------------- 29) Linux 用のオブジェクト指向の C はどこで手に入れられますか? 回答: オブジェクト指向の C は gcc の 2.4.0 以上のバージョンでリリースされていま す。これは、目下テスト中です。最新バージョンは以下のものです。 tsx-11.mit.edu:/pub/linux/packages/GCC/gcc-2.5.7-p2.tar.gz ------------------------------------------------------------------------------- 30) "Internal compiler error: cc1 got fatal signal 11" のメッセージの意味は何で すか? 回答: GCC はたぶんプログラムを走らせるために貪欲にメモリを消費し、きっと RAM の領域を食いつぶしたのでしょう。普通、致命的シグナルの 11 は、RAM の パリティエラーやハード障害を意味しています。私もハードディスクの不良ブロッ クのせいで cc1 で同じ状態に陥ったことがあります。それは、チップのオーバー ヒート(フレンチフライではありません)によるエラーとして報告されています。 また、低機能の IDE コントローラとドライブで 8MHz AT バスクロック以上で走ら せようとすると発生します。これはスワップスペースの変造を引き起こすことによ り同じエラーとなります。 一般に、シグナル 11 (セグメンテーション・バイオレーション)は、プロセスス ペース不足状態ででメモリをアクセスに行った、またはリードオンリー領域に書き 込みに行ったことを意味しています。たまに、このシグナルはソフトのバグで発生 することもあり、ハード障害とは限りません。(またはシステムの繰り返し ハング。なぜならカーネルで同じ事が起きるからです。)gcc 2.3.3 では、何人か がたくさんの”シグナル 11”を再現しました。 また、`ld' や `as' の最中の障害としても発生します。もし、cc1, cpp, または ld に問題があるとすれば、gcc で -v フラグを付けてリコンパイルして確認して みてください。 ------------------------------------------------------------------------------- 31) libc.lite とは何ですか? 回答: libc.lite とは、フロッピー運用でほとんどの卑しい(訳注:意味不明) UNIX の タスクを満足するための libc ライブラリの軽いバージョンですこれには、curses, dbm, termcap などのコードを含んでいません。もし、あなたの /lib/libc.so.4 が 軽いライブラリをリンクしているならば、フルバージョンに置き換える事をお勧め します。どこで手に入れられるかは質問 (3) を参照してください。 ------------------------------------------------------------------------------- 32) Linux のライブラリは SHADOW Password をサポートしてますか? また、オン・オフはどうすればよいのですか? 回答: サポートしています。 適当な場所に 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 のオン・オフを行う 方法が『ない』ことを意味しています。 ------------------------------------------------------------------------------- 33) math.h ルーチンが見つかりません。プログラムをコンパイルしているのですが、 log(), sin() などが見つかりません。だれか、助けて! 回答: 正しい関数を使用したプログラムをコンパイルしている場合、適切なライブラリ をプログラムに『必ず』リンクしなければなりません。数値演算関数を使うには リンク時に 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 と入力してください。 ------------------------------------------------------------------------------- 34) GCC のマニュアルはありますか?もしあるなら、どこで手に入れられますか? また、どうすれば印刷できますか? 回答: マニュアルは 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 を使 用して見ることができます。『情報』ファイルは情報システムに基づいたハイパー テキスト形式です。 ------------------------------------------------------------------------------- 35) "Undefined symbol _bsd_ioctl" のメッセージが出ました。どうすればいいのです か? 回答: リンク時に /usr/lib/libbsd.a という bsd のライブラリをインクルードするこ とを忘れています。 解決方法: Makefile の LDFLAGS 行に -lbsd フラグを加えてください。(LDFLAGS 行が無い場合は手動で加えてください) ------------------------------------------------------------------------------- 36) バージョンアップするときは、/usr/lib/gcc-lib/i[34]86-linux/ から古いものを取り除くことはできますか? 回答: えっと、もし、gcc のテストバージョンでなければ、ディレクトリから古いバー ジョンを取り除くことは全く問題ありません。"gcc -V " とすること で古いバージョンの GCC でコンパイルすることができます。 ------------------------------------------------------------------------------- 37) 『助けて』libipc.a はどこですか?dosemu 0.49 のために必要なのですが。 回答: Inter Process Communication (IPC) 関数は標準の libc >= libc.so.4.4.1 に あります。もし、あなたが持っている libc が libc.so.4.4.1 以上だった場合は、 -lipc は必要ありません。Makefile からその行を消してください。もし、 libc.so.4.4.1 未満だった場合は、ライブラリをバージョンアップしてください。 ------------------------------------------------------------------------------- 38) XXX がコンパイルできません。_daemon が未定義になります。だれか助けて!! 回答: daemon() は libbsd.a に入っています。-lbsd を Makefile の LDFLAGS 行に 加えてください。 ------------------------------------------------------------------------------- 39) 『助けて』ar と ライブラリについてです。シンボルはライブラリにあるのです が、リンクに失敗します。 回答: しばしば `ranlib' が正しいテーブルを作らないという `ar'のバグです。 以下のコマンドを打ち込めば動くようになります。 % ar -dv libfoo.a __.SYMDEF % ranlib libfoo.a ------------------------------------------------------------------------------- 40) 助けて! 初心者なのですが、"libc.so.4: incompat. minor ver no." というワー ニングメッセージがでて困っています。 回答: 共有ライブラリのバージョンアップが必要です。質問 12 と 3 の概要を見てくだ さい。 ------------------------------------------------------------------------------- 41) c のプログラムのコンパイルの前にチェックする `lint' はどこですか? 回答: `lint' のようなプログラムをチェックするようなものはありません。その代わり にプログラムをチェックするには gcc の過度のオプションを使います。マニュアル に書いてあるいろいろなオプションを見てください。 最も効果的なものは以下のオプションです。 % gcc -Wall foo.c このオプションは起こるであろう可能な限りのワーニングを出力します。 ------------------------------------------------------------------------------- 42) 私のプログラムで sgtty.h が必要なのですが、どこにあるのでしょうか? 回答: sgtty.h は /usr/include/bsd ディレクトリに入ります。コンパイル時に Makefile の CFLAGS 行に以下の行を追加してください。 -I/usr/include/bsd ------------------------------------------------------------------------------- 43) SIGSEGV によるコアファイルの作成を禁止したり、許可したりするにはどうすれば よいのでしょうか? 回答: これは本当は 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 を実行してください。 ------------------------------------------------------------------------------- 44) "can't load dynamic linker `/lib/ld.so'" のメッセージの意味は何ですか? 回答: これは、動的リンカ/ローダがインストールされていないことを意味していま す。質問 4 の libld.so の入手方法を参照してください。 ------------------------------------------------------------------------------- 45) -O2 と -O6 での効率の違いは何ですか? 回答: 現在はありません。もし、あなたが i386/i486 のホスト / ターゲットとして GCC のソースコードを見ているなら、-Ox で x>2 の場合は同じものであることが わかるでしょう。実際、Makefile で x>2 を使用することは悪いことです。なぜな ら、GCC が将来 -O3 といった最適化オプションをインテル(のチップ)をターゲ ット採用するかもしれないため、その最適化によって出力されるコードが破壊され るかもしれません。 ------------------------------------------------------------------------------- 46) 出所不明のバイナリがトロイの木馬のようなウィルスに感染しているかどうか チェックする方法は? 回答: 最初に、もし、あなたのマシンがウィルスに感染しているか心配ならば、動かさ 『ない』ことです(少なくとも root では)。そして、ソースを見つけてリコンパ イルしてください。他の方法としては、"string | less" と入力するこ とで何らかの情報が手に入るかもしれません。もし、動かす賭に出るならば、 何か不穏な動きを探るために "strace" を使うことができます。 ------------------------------------------------------------------------------- 47) C ライブラリのソースはどこにありますか?またリビルドする方法は? 回答: 以下のサイトのモジュールを参照してください。 tsx-11.mit.edu:/pub/linux/pagkages/GCC/libc-4.5.8.tar.gz もし、共有ライブラリが欲しいなら、dll ツールパッケージが必要になるでしょ う。質問 (5) の入手場所を参照してください。 ------------------------------------------------------------------------------- 48) FD_* の定義はどこにありますか? 回答: に含まれていて、マクロも追加されるでしょう。 ------------------------------------------------------------------------------- 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. なにが悪いのでしょうか? 回答: libc.sa の crt0.o と libc.sa と libc.a を最近の linux の libc にアップデ ートする必要があります。しかし、古い libg.a 関係が残ってしまいます。 もし、本当にデバッグライブラリによるスタティックバイナリ(-g の意味する) が必要ならば、libg.a を入手してインストールすべきです。 これについては質問 (15) を見てください。 ------------------------------------------------------------------------------- 50) わたしのライブラリやアプリケーションを国際化するツールはどこで手に入ります か? 回答: 以下のファイルを手に入れてください。 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 のキャラクターセットがやっとサポートされたような状態で す。 ------------------------------------------------------------------------------- 51) `mkimage' という DLL ツールが libgcc のなかに見つかりません。助けてくださ い。 回答: libc.so.4.5.x 以上では、libgcc はすでに共有ではありません。 したがって、mkimage の `-lgcc' の部分を以下のように置き換えなければなりませ ん。 `gcc -print-libgcc-file-name` 短くすると `gcc --print` です。バッククォートは必要ありません。 ------------------------------------------------------------------------------- 52) "__NEEDS_SHRLIB_libc_4 multiply defined" のメッセージを出ないようにするには どうすればいいのでしょうか? 回答: libc.sa.4.5.x 以上では libgcc は共有ではなくなっています。したがって、 /usr/lib/libgcc* ファイルをすべて削除し『なければ』なりません。 % rm -f /usr/lib/libgcc* ------------------------------------------------------------------------------- 53) QMAGIC というのは、一般的にはどういうものですか? 回答: QMAGIC はスタンダードの a.out (ZMAGIC といった)のような実行形式のフォー マットです。しかし、マッピングされない最初のページに置かれます。このことに より、0-4096 の範囲でマッピングされないトラップとして簡単に『まったく』同じ 方法で実現できます。それに対し、あなたのバイナリ側への影響はほとんどありま せん。(~1K) /etc/magic ファイルに正しく登録すれば、あなたの `file' コマンドは QMAGIC バ イナリと同じにすることができます。わたしは、ほとんどのチャネルに適当な エントリーを配付しています。 ------------------------------------------------------------------------------- 54) どのようにすれば、QMAGIC の実行ファイルやライブラリを作成できますか? 回答: QMAGIC の実行ファイルを作るには、最新の `ld' のバイナリやソースのパッチが 必要です。`binutils-as.tar.gz' というファイルが配付されています。質問 (6) を参照してください。 QMAGIC 実行ファイルの作り方: Makefile 中の LDFLAGS 行に以下の部分を追加します。 LDFLAGS = -Wl,-qmagic または LDFLAGS = -Xlinker -qmagic QMAGIC ライブラリの作り方: ごめんなさい。`mkimage' の使い方がいまいちわかりません。もう少し待ってく ださい。 55) "warning using incompatable library version xxx" のメッセージを出ないように することはできますか? 回答: はいできます。 もし、 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 まで。