- PR -

PostgreSQL+CGI で libpq.so.3: cannot open shared object file

1
投稿者投稿内容
Psyduck
常連さん
会議室デビュー日: 2004/01/18
投稿数: 39
投稿日時: 2005-04-10 15:36
いつもお世話になっております、Psyduckと言います。
PostgreSQLにCGIからアクセスする際にエラーが出て動作しないのですが
アドバイスをいただければありがたいです。

環境:
RedHat 7.2、PostgreSQL 7.4.7、Apache 2.0.53、CGIプログラムはC言語で作成

現象:
CGIを用いて、PostgreSQLで作成したDBにアクセスしようとすると
エラーが出て動作しません。エラーによればライブラリが読み込まれていないようです

Apacheのエラーログ:
error while loading shared libraries: libpq.so.3: cannot open shared object file: No such file or directory

備考:
CGIプログラム作成時には、PostgreSQLのマニュアルに従い
cc -c -I/usr/local/pgsql/include test.c
cc -o test test.o -L/usr/local/pgsql/lib -lpq
としています。コンパイルリンク時には一切のWarning/Error共に出ていません。

エラーログで指示されている libpq.* の一切(3つほどありました)を
cgi-binディレクトリにコピーしても同じでした。

また、libpq.* のpermissionは777あるいは755です。

なお、予め ユーザーapacheに対して、PSQLのgrantコマンドで
アクセス権はselectとupdateが与えてあります。
PostgreSQLのプロセスは起動しています。

test.cgiの実行時に、なぜ動的にライブラリを読みに行くのかも判りません。
プログラム作成時に、静的にライブラリをリンクできないのでしょうか?
もしそれができれば、それでも解決するように思っていますが・・・

どなたか、アドバイスなどいただけるとありがたいです。m(__)m

angel
ぬし
会議室デビュー日: 2005/03/17
投稿数: 711
投稿日時: 2005-04-10 17:49
引用:

Psyduckさんの書き込み (2005-04-10 15:36) より:
現象:
CGIを用いて、PostgreSQLで作成したDBにアクセスしようとすると
エラーが出て動作しません。エラーによればライブラリが読み込まれていないようです

Apacheのエラーログ:
error while loading shared libraries: libpq.so.3: cannot open shared object file: No such file or directory

備考:
CGIプログラム作成時には、PostgreSQLのマニュアルに従い
cc -c -I/usr/local/pgsql/include test.c
cc -o test test.o -L/usr/local/pgsql/lib -lpq
としています。コンパイルリンク時には一切のWarning/Error共に出ていません。


えと、今時ライブラリは全部 shared object として扱われるのが標準だと思いますぞ。
ldd で、CGIファイルにリンクされたライブラリを調べれば分かるはず。
.so ファイルが非標準の /usr/local/pgsql/lib にあるのが、やはり決定的だと思いますね。
解決策としては、/etc/ld.so.config にディレクトリを追加するか、Apache起動時に LD_LIBRARY_PATH 環境変数を設定するかが一般的と思います。
※前者の解決策はシステム全部に影響が出る方法なので注意が必要

詳しくは、man 8 ldconfigや、man 8 ld.soをどうぞ。

[ メッセージ編集済み 編集者: angel 編集日時 2005-04-10 18:19 ]
angel
ぬし
会議室デビュー日: 2005/03/17
投稿数: 711
投稿日時: 2005-04-10 18:13
引用:

Psyduckさんの書き込み (2005-04-10 15:36) より:
プログラム作成時に、静的にライブラリをリンクできないのでしょうか?
もしそれができれば、それでも解決するように思っていますが・・・



おまけ。
man 8 ld.soより
引用:

Linux のバイナリは、コンパイルの時に ld に対して -static オプションが指定されていない限り、動的リンク (実行時リンク) が必要となる。


↑のように、cc(gcc)実行時に、-static をつけていて、対応する .a ライブラリがあれば静的リンクになるはずです。
…が、共有ライブラリが同一システム上にあるなら、敢えて静的リンクにする必要はないと思います。(ライブラリのマイナーバージョンアップ対応が面倒になりますから)

余談ながら、私も動的リンクで、予想外の問題が出て困ったことはあります…、LinuxではなくSolarisで申し訳ないですが。
gccでソフトをビルドして、他のマシンに持って行ったらライブラリ不足で動かない。
特殊なライブラリは使ってないはずなのに何故? と思ったら、gcc に付属する libgcc が問題でした。
gcc3系では自動的に libgcc がリンクされるのを知らずに、ほぼ最小構成で gcc の入っていないマシンに持って行っていた…、という落ちです。
この時は libgcc を静的リンクしてビルドし直しました。

以上、ご参考まで。
あんとれ
ぬし
会議室デビュー日: 2004/01/14
投稿数: 556
投稿日時: 2005-04-10 19:47
引用:

Psyduckさんの書き込み (2005-04-10 15:36) より:

cc -o test test.o -L/usr/local/pgsql/lib -lpq



cc -o test test.o -L/usr/local/pgsql/lib -Wl,-rpath -Wl,/usr/local/pgsql/lib -lpq

としてみて下さい。きっとうまくいくでしょう。
ただし、使用しているコンパイラがgcc、リンカーがbinutils付随のものでない場合は

cc -o test test.o -L/usr/local/pgsql/lib -R/usr/local/pgsql/lib -lpq

とする必要があるかもしれません。
Psyduck
常連さん
会議室デビュー日: 2004/01/18
投稿数: 39
投稿日時: 2005-04-11 03:14
こんにちは、Psyduckです。いつもお世話になっております。
みなさんのおかげで正常に動作するようになりました。
本当にどうもありがとうございました。

angelさん
>今時ライブラリは全部 shared object として扱われるのが標準だと思いますぞ

すみません、私の知識がとても古いものですから・・・
たしかにライブラリの更新を考えると、実行時にリンクする方が良いんですよね。
特に最近のマシンは、CPUも早いしメモリも大きいので問題ないんですね。
勉強になりました。m(__)m

>cc(gcc)実行時に、-static をつけていて、対応する .a ライブラリがあれば静的リンクになるはずです

了解しました。どうもありがとうございました。

あんとれさん
>cc -o test test.o -L/usr/local/pgsql/lib -Wl,-rpath -Wl,/usr/local/pgsql/lib -lpq

これでうまく動きました。
内容もわからずにそのとおりにしています。
無事に動いたので、これからその意味を勉強します。
どうもありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)