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



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