下記urlのソースをgcc 4.6.1でコンパイルしたバイナリをレンタルサーバ(tok2)で動かそうとしています。このサーバはバイナリcgiをサポートしています。
http://d.hatena.ne.jp/neuromancer_sho/20111024/1319447432
g++のオプションで -static を指定しているので、サーバ側に手元のマシン上のライブラリが無くても動作するだろう、と予測したのですが、Internal Server Errorになってしまいます。エラーログなどはサーバ仕様上見れません。手元のlinuxマシンではapache上でcgiとして動作しています。
特殊なライブラリを使用しない、c++0xの新命令も使用しないcgi
cout<<"Content-Type: text/html\n\n"<<endl; など
であれば、正常に動きます。
サーバ側にライブラリ(soファイル??)が無いとダメなのでしょうか?
レンタルサーバのスペック:
gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-46)
Linux 17.pro.tok2.com 2.6.18-164.11.1.el5xen #1 SMP Wed Jan 20 08:53:10 EST 2010 i686 i686 i386 GNU/Linux
手元のマシンのスペック:
gcc (GCC) 4.6.1 20110819 (prerelease)
Linux arch 2.6.33.7-co-0.7.9 #1 PREEMPT Sat Apr 9 20:30:51 UTC 2011 i686 Intel(R) Core(TM) i5 CPU 750 @ 2.67GHz GenuineIntel GNU/Linux
# ただの思いつきです
while(dent = readdir(dir)) ret.push_back(dent->d_name);
のくだりで、dent->d_name って複製しなくて大丈夫でしょうか?
下のようにしたくなっちゃいますが...
while(dent = readdir(dir)) { string s(dent->d_name); ret.push_back(s); }
その手法を理解してませんでした。
ldd したところ、
linux-gate.so.1 => (0xffffe000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb75ef000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0xb75d2000)
libc.so.6 => /lib/libc.so.6 (0xb7469000)
libm.so.6 => /lib/libm.so.6 (0xb743f000)
/lib/ld-linux.so.2 (0xb76e6000)
となり、この中のlinux-gate.so.1 がサーバには存在してませんでした。
ありがとうございます。
soファイルを含めてスタティックリンクする事は出来ないのでしょうか?
以下のリンクとか参考になるかもです。
http://www.trilithium.com/johan/2005/06/static-libstdc/
でも、libstdc++.so.6とかはスタティックリンクされそうなもんなんですけどね。
-static-libstdc++ とかつけると変わりますかね。
http://blog.kmckk.com/archives/2149044.html
「動的実行ファイルではありません」と返って来ました。、となると動的ライブラリの問題では無いということになりますかね。。
-static に -static-libstdc++ を付け足したバイナリは同じものでした。
fileコマンドでは
ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.27, BuildID[sha1]=0xf3cef00f82da2fdbec363f80a51e86b2e9889b93, not stripped
と表示されました。この情報を元にサーバの対応状況を調べようと思います。
色々参考になります。ありがとうございます。
autoをやめて見るとか、cgiccを使わずにヘッダをはくとか、それぞれやってみると、調べる対象が切り分けられていいかもです。
cgicc不使用(リンクも無し)の場合も、c++0x不使用(-stdオプションも無し)の場合も、
11が返って来ます。
そして、両方不使用でstaticリンクしたものも11、dynamicの場合、正常な結果が返って来ました。
どうやら問題はstaticリンクにある様な気がしてきました。
サーバ上でstaticとdynamic両方でsystem("file cpp.cgi") したところ、
ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), for GNU/Linux 2.6.27, dynamically linked
ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.27, dynamically linked
となり、"version 1 "の後ろの(SYSV)というのが成功パターンの様な気がしてきました。
ひょっとして、ファイルが大きすぎて実行させてもらえないんでしょうか・・・
1.2MBもあるし・・
C++をやめて、C言語の最小構成で試したところ、dynamicでもstaticでも(SYSV)表示になりましたが、staticのreturnコードは11のままです。
static実行禁止 又は ファイルが大きすぎ(612kBまで減りましたが)のどちらかみたいな感じです。
printf("Content-Type: text/html\n\n");
printf("Hello, Cgi\n");
ソースはこのままで、g++のオプションに-staticをつけるのはやめて、
g++ cppcgi.cpp -std=c++0x /usr/lib/libcgicc.a /usr/lib/libstdc++.a -o cppcgi.cgi
fileコマンドの結果はdynamically linked です。
statically linkedだとダメ。という結果ですが、理由は分かりません。
特殊なライブラリを使用しない、c++0xの新命令も使用しないcgi
cout<<"Content-Type: text/html\n\n"<<endl; など
であれば、正常に動きます。
とあったのですが、こんなコードでもスタティックリンクするとダメだったということですよね?
system 関数の戻り値って、子プロセスが出したシグナルを返すわけじゃないですよね。
ERRNO が返ってきてるのじゃないか、と思うのですけれど。
ERRNO = 11 は、EAGAIN で、リソースが利用できないときに出るやつです。
そうなんです。よくわかりません。
>system 関数の戻り値って
シェルの戻り値と子プロセスの戻り値が8bitづつくっついているイメージだと勝手に想像してました。リソースが利用できないですか、勉強してみます。
お二人とも、ご協力いただいてありがとうございました。