Monday, April 21, 2008

64bit PPC build for MacOSX

Someone asked me why there wasn't a 64bit version of Firebird for MacOS powerpc... so I tried a build on the powerpc MacOSX box we have...
sw_vers -productVersion = 10.4.11
Build fails when we try to build config_root.cpp.

/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers/MachineExceptions.h:272: error: typedef 'ExceptionHandlerProcPtr' is initialized (use __typeof__ instead)
/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers/MachineExceptions.h:272: error: 'ExceptionInformation' was not declared in this scope
/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers/MachineExceptions.h:272: error: 'theException' was not declared in this scope
/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers/MachineExceptions.h:306: error: 'ExceptionInformation' was not declared in this scope
/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers/MachineExceptions.h:306: error: 'theException' was not declared in this scope
/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers/MachineExceptions.h:307: error: expected primary-expression before 'userUPP'
/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers/MachineExceptions.h:307: error: initializer expression list treated as compound expression
/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers/fp.h:1338: error: 'SIGDIGLEN' was not declared in this scope


Some googling explains what the problem is. Seems MacOSX is 10.4 is not 100% 64bit friendly and the carbon framework will not support a full 64bit build until MacOSX 10.5.

We use the carbon framework in a few, but very specific places, mainly to load UDF libraries as bundles and also the fbintl library.

So....

I either need to upgrade our powerpc Mac to MacOSX 10.5 to do the build...
or
Anybody out there got a powerpc Mac running MacOSX 10.5 that I could use to check the build?


Tuesday, April 8, 2008

Editline, Curses and Solaris AMD64

We finally solved the last major problem in the Firebird 2.0x build for Solaris 10 AMD 64bit. Whenever we tried to include editline in the build isql_static would coredump. We tracked the problem down to the following:

Seems there is a problem in the Solaris' native implementation of libcurses, the function tgetstr() returns a bad pointer (non-NULL, but out of the process space). This means that until Sun fix it we can't use libcurses to link with editline on Solaris 64bit AMD.

So we came up with a solution...
We downloaded and built ncurses... (5.5) then copied libncurses.a to gen/firebird/lib along with the normal editline.a
Then adjusted make.defaults to remove references to -lcurses for LINK_LIBS and STATICLINK_LIBS and added -lncurses.

We now have a succesful build that seems to work properly. I hope to put the 64bit Solaris AMD builds up in the firebird prerelease area for testing purposes, then commit the changes made to the code base. Then wen 2.04 is ready to be released will create proper versions for full release.

Hope that somebody out there finds this useful, or at least the builds anyway.

Monday, April 7, 2008

Wrongly Named libfbclient on Solaris

There is a small problem with the currently shipping versions of Firebird 2.0.3 for Solaris.
The problem doesn't affect the general workings of Firebird, but if you try to link with the libfbclient library using your own program, you will run into a problem where you will consistently get the following error:

ld: fatal: library -lfbclient: not found

The problem is due to a misnamed libfbclient.so in /opt/firebird/lib

To correct:
cd /opt/firebird/lib
rm libfbclient.so
ln -s libfbclient.so.2 libfbclient.so

This has already been corrected in CVS



Tuesday, April 1, 2008

64bit Firebird for Solaris 10 AMD64

Looks like having a 64bit build of Firebird on Solaris 10 AMD64 is going to be a non-starter.
Alex and I have done all the hard work, and we have a build (currently without editline, since thats a problem in itself), but when we try and run isql created by the build we get the following:

ld.so.1: ./isql: fatal: relocation error: R_AMD^$_32S:
file /usr/lib/64/libfbembed.so.2: symbol (unknown): vakue 0xfffffd7ffee00000
does not fit

or in debug mode trying to run isql from the build directly:
ld.so.1: isql: fatal: relocation error: R_AMD64_PC32
file /home/pbeach/firebird64/gen/firebird/lib/libfbembed.so.2:
symbol main: value 0x2800155d494 does not fit.

A bit of googling finds this:

Bug ID 5102797
Synopsis AMD64: static relocation in dynamic library fails

If you read the details, seems the bug has been around since 15th Sept 2004
and because of its nature, there are no plans to fix it until Solaris 11.

Addendum: 2nd April 2007
Looks like we have found the problem.
LIB_LINK_OPTIONS in the prefix build file was -G
-G on Solaris should tell the linker to create a shared library
However because we are using gcc, something somewhere was getting confused.
If we pass -fPIC and -shared instead the problem is resolved.

From the gcc manaual:


-shared

Produce a shared object which can then be linked with other objects to form an executable. Not all systems support this option. For predictable results, you must also specify the same set of options that were used to generate code (-fpic, -fPIC, or model suboptions) when you specify this option

On some systems, `gcc -shared' needs to build supplementary stub code for constructors to work. On multi-libbed systems, `gcc -shared' must select the correct support libraries to link against. Failing to supply the correct flags may lead to subtle defects. Supplying them in cases where they are not necessary is innocuous.

Friday, March 28, 2008

FreeAdhocUDF for MacOSX

I have just finished porting FreeAdhocUDF to MacOSX and sent the Makefiles, code, plus 32bit UDF libraries for Firebird 1.5.5 and Firebird 2.x to the FreeAdhocUDF types to be included in the distribution.

Issues that you might need to be aware of.
1. In Firebird 1.5.5 we don't ship libib_util.dylib, and even if we did you wouldn't be able to link to it. It seems that Firebird 1.5.5's installer doesn't copy the library to the Framework. This has now been fixed for the next release. Secondly the library was being built as a bundle. All Firebird UDF's need to be created as bundles to work on MacOSX. You can't link a bundle to a bundle. This has also been fixed.
2. In Firebird 1.5.5 you must remove any extension from the UDF library (e.g dylib) to get it to work. So for example FreeAdhocUDF.dylib needs to be renamed to FreeAdhocUDF. This bug has been fixed in flu.cpp for the next version.

Firebird 2.x does not have any of these problems :-)

In compiling FreeAdhocUDF for MacOSX, it has to be noted that MacOSX has no idea of sysinfo.h, so I had to add a chunk of code to handle the getting of a MAC address, and to get the random_info/randomness for GUIDs. This does seem to work nicely now.

The FreeAdhocUDF libraries I have provided are 32bit intel for Firebird 1.5.5 and Firebird 2.x, if you want to build ppc libraries, or 64bit libraries enjoy. If you have problems, let me know.

On ppc you "might" have to add the following to the Makefile
i.e. change
LDFLAGS=$(CF) $(LIB) -bundle -flat_namespace -undefined suppress to
LDFLAGS=$(CF) $(LIB) -bundle -flat_namespace -undefined suppress /usr/sys/bundle.o

Friday, March 21, 2008

Exceptions, gcc and Solaris 10 AMD 64bit

For a little while now Alex and I have been battling a problem on Solaris 10 64bit AMD. We have been trying to port Firebird 2.0x to 64bit Solaris. However after fixing a few issues, e.g. defining the platform etc, we found that isql_static would core dump on trying to create a database. This is where the fun begins...

The default debugger for gcc shipped with Solaris 10 can't handle 64bit applications. Solution - build your own from a later version. At least this way we can now step through the Firebird code and try to see whats happening..

After some careful debugging sessions we find that Firebird seems to be OK, when you try to create a database, Firebird first trys to open it as an existing database, if it can't find an existing database we throw an internal exception and go on to create it.

The problem is isql_static is occurring when the exception is thrown...

Program received signal SIGSEGV, Segmentation fault.
0x0000000000488385 in __EH_FRAME_BEGIN__ ()

(gdb) bt
#0 0x0000000000488385 in __EH_FRAME_BEGIN__ ()
#1 0xfffffd7ffedacf3c in _Unwind_RaiseException_Body () from /lib/64/libc.so.1
#2 0xfffffd7ffedad129 in _Unwind_RaiseException () from /lib/64/libc.so.1
#3 0xfffffd7ffef3c71e in __cxa_throw (obj=0x1, tinfo=0x1, dest=0x474e5543432b2b00)
at /builds/sfw10-gate/usr/src/cmd/gcc/gcc-3.4.3/libstdc++-v3/libsupc++/eh_throw.cc:75
#4 0x000000000056510b in Firebird::status_exception::raise (status_vector=0x8d19e0)
at ../src/common/fb_exception.cpp:197
#5 0x0000000000694137 in ERR_punt () at ../src/jrd/err.cpp:562
#6 0x0000000000693ced in ERR_post (status=335544344) at ../src/jrd/err.cpp:441
#7 0x00000000005c66d4 in PIO_open (dbb=0xfffffd7ffec29050, string=@0xfffffd7fffdec9e0,
trace_flag=false, connection=0x0, file_name=@0xfffffd7fffdeca20, share_delete=false)
at ../src/jrd/os/posix/unix.cpp:646

So Firebird looks OK, i.e. its doing what it should do, however Solaris is causing a crash dump on the exception.

Some more detective work uncovered the following:

The problem is caused by the use of the -lc flag which was explicitly added to linker command line by autoconf.

Because we always use g++/gcc as linker, there is no need for us to need add in libc explicitly - it's done by compiler itself when it invokes ld. But autoconf seems to be doing it anyway.

When it is added to the command line, libc (Solaris native library) then happens to be added to ld's command line before libgcc_s where we would find gcc's own exception support library. If this happens any call to functions that have the same name, that happen to be present in both libraries, will go to libc, not libgcc_s.

There is at least one such function - Unwind_RaiseException(), which is called by g++ generated
code when exception is thrown. But instead of libgcc_s::Unwind_RaiseException() libc::Unwind_RaiseException() is called, but not with the parameters the Solaris native function expects - cue core dump.

Solution:

Don't use -lc

Thursday, March 13, 2008

Where is libfbclient.dylib on MacOSX?

There was a post to the Firebird Support list, asking how you link Qt to the libfbclient.dylib on MacOSX Firebird SuperServer. The problem being, that libfbclient.dylib is not "shipped" as part of the MacOSX framework... heres the detailed answer on how it works.

Firebird on MacOSX is delivered as a framework,

For more information on a frameworks look on : http://developer.apple.com

In a nutshell - "A framework is a hierarchical directory that encapsulates shared resources, such as a dynamic shared library, nib files, image files, localized strings, header files, and reference documentation in a single package. Multiple applications can use all of these resources simultaneously. The system loads them into memory as needed and shares the one copy of the resource among all applications whenever possible."

This is the "best" way to deliver an application on MacOSX.

However to do this the main dylibs (shared libraries) that run Firebird become part of the framework itself.

The main dylib that drives Classic is libfbembed, for SuperServer its libfbclient.

With Classic we ship both libfbembed and libfbclient, libfbclient as a separate dylib can be found in the libraries directory.

for SuperServer we ship libfbclient

However libfbembed (Classic) and libfbclient (SuperServer) are not directly obvious as shared libraries, i.e. if you look for them by that name with a dylib extension you are not going to find them. However if you took a close look at postfix.darwin in the Firebird source builds/posix (this is the code that sets up the framework) you will find that they become Firebird.framework/Firebird which is a link to Firebird.framework/Versions/Current/Firebird.

Where
Firebird.framework/Firebird is libfbembed.dylib for Classic and
Firebird.framework/Firebird is libfbclient.dylib for SuperServer