1

私が取り組んでいる非常に独特な問題があります。solaris 8/sparc プラットフォームで古いコンパイラ (gcc 2.95 以前) でコンパイルされたコードがあります。solaris 8/sparc では問題なく動作しますが、solaris 10/sparc ではクラッシュします。(solaris 10 はおそらく、solaris 8 と下位互換性があります)

デバッグ時に、アプリがホスト名を対応する i/p アドレスに変換しようとすると、問題が発生することがわかります。gethostbyname_r を使用し、続いて inet_ntoa を使用して、ipv4 のクワッドドット番号を取得します。ソリューションを gdb で実行すると、gethostbyname_r によって返される in_addr には i/p アドレスを表す正しい整数が含まれていることがわかりますが、inet_ntoa 呼び出しは不正な形式の文字列を返します。それが本当に inet_ntoa の失敗であることを確認する際の困難の 1 つは、コードが次のように記述されていることです。

strcpy(hostaddr, inet_ntoa(*((struct in_addr *) hostdata.h_addr)));

したがって、技術的には、inet_ntoa によって返される値を確認できません。しかし、私はすることができます

print (char*)inet_ntoa(*((struct in_addr *) hostdata.h_addr_list[0]))

gdbで確認すると(これは十分に近いと思います)、不正な形式のi/pアドレスが出力されます。たとえば、「0.0」です。(ホスト名には有効な i/p アドレスがあり、そのマシンから解決できるため、0.0 で始まる i/p も正しい値ではありません)

inet_ntoa で安全でない strcpy を使用すると、少し不明な点が生じ、セグメンテーション違反が発生することがわかります。

このような inet_ntoa の失敗の原因は何か、似たような経験をしたことがある方からのご意見をお待ちしております。どういうわけかシステムが役割を果たしており、それを修正するために何ができるかを考えることすらできません。

すべてのコメントは大歓迎です。

制約: コードを変更して機能させることはできません (それ以外の場合は簡単に解決できます)。そのため、strcpy がセグ フォールトに対して非常に危険な関数であり、inet_ntoa が非推奨であることを知っていても、私はその面で無力です。

編集:並列処理の問題だと思います。よくわかりませんが、アプリがマルチスレッドではないと思います。しかし、新しい sol10 マシンは 64 コアのマシンです。思考連鎖の理由は、inet_ntoa の唯一の実際の問題は静的バッファーであり、コードはこの呼び出しをループで行うためです。

4

1 に答える 1

0

リンカ (そしてもちろん悪いコード) が問題であることがわかりました。標準ライブラリ関数 (inet_ntoa_r) とまったく同じ名前の関数を持つことは素晴らしいアイデアでしたが、とてもいい人です。コードをライブラリにリンクする際に -static オプションを使用しようとすると、ユーザー ライブラリ ファイルにこのシンボルが存在するというエラーが表示され始めました。ユーザーライブラリからその関数を取り除くと、そのクラッシュから移動しました(修正しようとしている他の問題に。別の質問を期待してください:))。誰かがこれが役に立つことを願っています

于 2012-09-18T21:10:05.960 に答える