Subject Re: [Firebird-Architect] XSQLDA/XSQLVAR issues
Author Jim Starkey
Samofatov, Nickolay wrote:

>All,
>
>I cannot afford writing detailed explanation often, but I can do it
>once.
>
>
>
>Note that there is a number of ways to store stack frame size. One
>compiler may chose to store frame size in bytes, another may chose to
>save pointer to function return address, etc.
>
>
Nickolay, I think that people who design linkers and loaders are
familiar with these issues, too, and go out of their way to make sure
that modules with different stack disciples can not be mixed in a single
run unit. This has not always been the case, as anywho who suffered
through Sun's transition from a BSD based Solaris to Sys V based
Solaris. To avoid these problem, they do some nasty things with
libraries to ensure than any incompatible module mix will fail to link
and/or load. I don't know where this is universally the case, and if
you know of systems with problems, I'd like to hear them.

Based on my experimentation, a gcc compiled object will not link to a
Forte compiled library and will not load a Forte compiled library,
though it's possible that I missed some combination of switches that the
mass of options. If you'd like to try your self, here is a library
header (Lib.h):

extern "C"
{
typedef void (*Callback)(void);

void invokeCallback(Callback fn);
};


class Lib
{
public:
~Lib();
void enter (Callback fn);
};

a module to be build into a library (Lib.cpp):

#include <stdio.h>
#include "Lib.h"

void invokeCallback(Callback fn)
{
printf ("invokeCallback\n");
Lib lib;
lib.enter(fn);
printf ("invokeCallback still here\n");
}

Lib::~Lib()
{
printf ("Lib destructor here\n");
}

void Lib::enter(Callback fn)
{
printf ("Lib::enter\n");
(fn)();
printf ("Lib:: enter still here\n");
}

a module to attempt to link against it (caller.cpp)

#include <stdio.h>
#include "Lib.h"

static void callback (void);

class Exception
{
public:
Exception ()
{
printf ("Exception here\n");
}
};


int main()
{
printf ("main here\n");

try
{
invokeCallback (callback);
printf ("main still here\n");
}
catch (Exception& exception)
{
printf ("Exception caught\n");
}

return 0;
}

void callback (void)
{
printf ("callback here\n");
throw Exception();
}

and, finally, a program to try and load it dynamically (loader.cpp):

#include <stdio.h>
#include <dlfcn.h>
#include "Lib.h"

static void callback (void);

class Exception
{
public:
Exception ()
{
printf ("Exception here\n");
}
};


int main()
{
printf ("loader here\n");
void *libr = dlopen("./liblib.so", RTLD_NOW);

if (!libr)
{
printf ("dlopen failed: %s\n", dlerror());
return -1;
}

void *fn = dlsym(libr, "invokeCallback");

if (!fn)
{
printf ("dlsym failed: %s\n", dlerror());
return -1;
}

try
{
((void (*)(Callback)) fn) (callback);
printf ("main still here\n");
}
catch (Exception& exception)
{
printf ("Exception caught\n");
}

return 0;
}

void callback (void)
{
printf ("callback here\n");
throw Exception();
}

If you can find any system were caller links or load loads and the
subsequent unwind either blows up or fails to call the Lib destructor,
then I will have to rethink my strategy.

--

Jim Starkey
Netfrastructure, Inc.
978 526-1376