3

Free Pascal /C++プロジェクトが混在しています。i386、FPC2.4.4上のDebian 5.0( "Lenny")。プログラムを実行すると、最初のcout<<呼び出しでクラッシュします。おかしなことに、それはしばらくの間機能していました。いくつかのOSアップデートはおそらくそれを壊しました。分離された問題は次のとおりです。

p.pas:

{$L c.o}    
program p;
uses initc;
procedure Hello; cdecl; external name 'Hello';

begin
     Hello;
end.     

c.cpp:

#include <iostream>
//void * __dso_handle; //You might need to uncomment that
extern "C" void Hello()
{
    std::cout << "Hello world";
}

Makefile:

p : c.o p.pas Makefile
    fpc p.pas -k-lstdc++

c.o : c.cpp
    g++ -c c.cpp

作成、実行、セグメンテーション違反。まったく新しいDebianVMを試してみました-同じ結果です。

クラッシュはbasic_fstream::セントリー::sentry()内で発生します。cout彼らは、このクラッシュの場所は、初期化されていないグローバルオブジェクトと一致していると主張しています。これは奇妙なinitcことです。Pascal側から使用すると、グローバルC++変数が確実に初期化されると思いました。

何かアイデアはありますか?どういうわけか、リンクしているlibstdc ++のバージョン(libstdc ++。so.6.0.10)でしょうか?

編集:それはますます奇妙になります。pCentOS 5.3ボックスで同じバイナリ()を実行します-宣伝どおりに機能します。おそらくそれは共有ライブラリバージョンに関するものです...私はさまざまなLinucesに関するいくつかの統計を収集しに行きます。

EDIT2:私が気づいたことの1つ:ldd pDebianボックスで行うと、次のようになります。

linux-gate.so.1 =>  (0xb77a6000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb76a6000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb754b000)
libm.so.6 => /lib/i686/cmov/libm.so.6 (0xb7524000)
/lib/ld-linux.so.2 (0xb77a7000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7517000)

そして、それが機能するCentOSボックスで同じことをすると:

libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb7ec2000)
libc.so.6 => /lib/libc.so.6 (0xb7d69000)
libm.so.6 => /lib/libm.so.6 (0xb7d40000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7d34000)
/lib/ld-linux.so.2 (0xb7fb7000)

i686/cmovしたがって、すべてのCライブラリ(C ++ライブラリだけでなく)はディレクトリから取得されます。Debianマシンにもがあり/lib/libc.so.6、のマシンとは異なりcmovます。cmovそのディレクトリとの取引は何ですか?そして、なぜ同じ名前のlibcの2つの異なるコピーがあるのでしょうか。

編集:CentOSでも、グローバルコンストラクターは呼び出されません-アドホックグローバルオブジェクトでテストされただけです。何らかの理由でsentry()でクラッシュすることはありません。結局、これはFPCの問題のようです。この動作に関するバグレポートがFPCにあります。

4

3 に答える 3

3

実際、静的 co に明示的にリンクしようとしました (libstdc++.so のすべてのさまざまなバージョンを使用して、ボックスで見つけることができました) が、同じ種類の失敗が発生します。

Runtime error 216 at $00007F3B9C9EFAD1
  $00007F3B9C9EFAD1

すぐに古いインストールを試してみます。更新Maverick でもリンクを機能させることができません (gcc 4.4.5 および fpc 2.4.0-2ubuntu1.10.10)。

動的リンクに変更した後にのみ、Natty ボックスで動作するようにしました。

p.pas で:

{$L c.so}

メイクファイル

p : c.so p.pas Makefile
    fpc p.pas

c.so : c.cpp
    g++ -shared -fPIC c.cpp -o $@

走る

$ LD_LIBRARY_PATH=$PWD
$ ./p
Hello world
于 2011-11-17T22:53:49.180 に答える
0

Initc により、FPC は起動コードを glibc 初期化子を呼び出す形式に切り替え、通常の ctor/dtor メカニズムを介して C++ を初期化する必要があります。

initc は Pascal メモリ管理を libmalloc を使用するように切り替えないことに注意してください。Pascal コードは、mmap(2) に直接基づく独自のサブアロケータを使用します。

問題はメモリ割り当てにも関連しているように見えるため、initc の代わりにユニット「cmem」を使用して、pascal ランタイムがメモリ管理に glibc の libmalloc 部分を使用するように強制します。

于 2011-11-18T08:07:19.690 に答える
0

特にcout(他のグローバル ストリームと同様に) の場合、次の行を C++ エントリ ポイントに追加すると役立ちます。

std::ios_base::Init();

より大きな問題がまだ存在します - 任意のグローバル C++ オブジェクトが構築されません。

于 2011-11-18T20:39:31.520 に答える