Имам смесен Free Pascal/C++ проект. Debian 5.0 ("Lenny") на i386, FPC 2.4.4. Когато стартирам програмата, тя се срива при първото cout<<
извикване. Забавно, работеше известно време; някоя актуализация на ОС вероятно го е счупила. Ето изолирания проблем:
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
Make, run, segfault. Пробвано на чисто нова Debian VM - същият резултат.
Сривът се случва в рамките на basic_fstream::sentry::sentry(). Те твърдят, че това местоположение на срив е в съответствие с глобалния cout
обект, който не е инициализиран. Това е странно - мислех, че използването на initc
от страната на Pascal гарантира, че глобалните C++ променливи са инициализирани.
Някакви идеи, моля? Може ли по някакъв начин да е версията на libstdc++, срещу която правя връзка (това е libstdc++.so.6.0.10)?
РЕДАКТИРАНЕ: става все по-странно и по-странно. Пускам същия двоичен файл (p
) на кутия CentOS 5.3 - работи както е рекламирано. Така че вероятно става дума за споделени версии на библиотеки... Ще отида да събера малко повече статистики за различни Linuces.
РЕДАКТИРАНЕ 2: едно нещо, което забелязах: когато направя ldd p
на моя Debian box, ето какво получавам:
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)
Така че всички C библиотеки (само не C++) идват от i686/cmov
директория. Машината Debian също има /lib/libc.so.6
и е различна от тази в cmov
. Каква е работата с тази cmov
директория? И защо две различни копия на libc с едно и също име?
РЕДАКТИРАНЕ: дори в CentOS глобалните конструктори не се извикват - просто се тестват с ad-hoc глобален обект. Просто не се срива в sentry() по някаква причина. Изглежда, че все пак това е проблем с FPC. Има доклад за грешка във FPC относно това поведение.
__stdcall
? - person Kerrek SB   schedule 18.11.2011cdecl
изглежда точно тук и така или иначе, как би могло да има значение за void функция без параметри? - person David Heffernan   schedule 18.11.2011initc
инициализира среда за изпълнение на C++. Имате ли линк към такъв документ? - person David Heffernan   schedule 18.11.2011iostream
използва някои трикове, за да гарантира, че потоците са правилно инициализирани дори за изход от конструктори на статични обекти (обикновено това не би било гарантирано поради недефиниран статичен ред на инициализация между единиците за превод). Може би тези трикове не са съвместими с инициализацията от FreePascal. - person celtschk   schedule 18.11.2011initc
. - person Seva Alekseyev   schedule 18.11.2011initc
е свързано с C код. Но вие искате да стартирате C++. Просто бих се свързал динамично, както предлага sehe. - person David Heffernan   schedule 18.11.2011