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



Tuesday, March 11, 2008

Building GCC 4.2.1 On Solaris

Alex and I are currently trying to implement a 64bit version of Firebird 2.x for Solaris 10, and we are running into a number of problems. However they shouldn't be insurmountable. Every port has its problems one way or another, but this one is proving to be particularly annoying....

The default version of gcc shipped with Solaris 10 is 3.4.3 and is found in /usr/sfw/bin
The current available version of gcc (released is) 4.3
So the version Sun makes available dates from 2005...
One assumes that Sun has no interest in letting Solaris users use more modern versions of gcc and would rather we use their own compiler.
Hmm so much for Sun and open source...

But to properly compile on Solaris 10 with 64bit see notes from gcc.gnu.org

"
i?86-*-solaris2.10
Use this for Solaris 10 or later on x86 and x86-64 systems. This configuration is supported by GCC 4.0 and later versions only.

It is recommended that you configure GCC to use the GNU assembler in /usr/sfw/bin/gas but the Sun linker, using the options --with-gnu-as --with-as=/usr/sfw/bin/gas --without-gnu-ld --with-ld=/usr/ccs/bin/ld"

So gcc 4.0 is the lowest version you can use for cross-compiling 32bit and 64bit applications on Solaris 10...

So we have to build our own gcc to do the firebird compilation, here's how you do it....
1. Download a copy of the gcc source (e.g. gcc-4.1.2.tar.gz) from gcc.gnu.org
2. Install gnu tar, solaris tar has problems extracting the source from the gcc tar file.
3. You will probably need to install libintl too (you can get a pre-built version of this froim www.sunfreeware.com)
4. gunzip gcc-4.1.2.tar.gz
5. /usr/local/bin/tar -xvf gcc-4.1.2.tar
6. cd gcc-4.1.2
7. mkdir objdir
8. cd objdir
9. ../configure --with-gnu-as --with-as=/usr/sfw/bin/gas --without-gnu-ld --with-ld=/usr/ccs/bin/ld --enable-shared --enable-languages=c,c++
10. gmake
11. as root - make install

Your new version of gcc will be installed in /usr/local/bin