unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* Perhaps we can (and should) just detect dangerous linkages...
@ 2002-10-13 17:33 Rob Browning
  2002-10-13 19:05 ` Neil Jerram
  0 siblings, 1 reply; 3+ messages in thread
From: Rob Browning @ 2002-10-13 17:33 UTC (permalink / raw)



Feel free to disagree, but after the recent "add-on" lib discussion,
it seems to me that the fundamental problem is not specific to guile,
and probably isn't one we can fix from the guile side, and though the
libguile12-foo approach seems like it would fix the problem with
libguile, it wouldn't help the broader unix sub-library versioning
problem, and couldn't scale to fix that problem because
libguile12-gtk2-gnome3-foo is only for crazy people :>

However yesterday I did start to wonder if we might be able to at
least *detect* the problem at runtime whenever it involves libguile.
If this isn't too hard, then I think it might be worth doing.
Detecting dual-libguile linkages should help avoid some fairly
confusing runtime errors by aborting before any damage can be done.

I haven't quite figured out the details yet, but the general idea
would be to arrange it so that anything that compiles against libguile
stashes away the major number for that version of libguile (via a
#define/macro) at compile time, and then checks that number with a
libguile function call at runtime.

I've wondered if we might be able to make this automatic somehow, but
even if not, it doesn't seem unreasonable to require every library (or
app) that uses libguile to call scm_require_version(SCM_MAJOR) before
calling any other guile functions.  A failed check would cause an
abort with a suitable message.  A naive implementation should only
require a couple of lines of code.

I've tested this in my little sub-lib testbed and it seems to work:

  $ ./some-app-1
  init libuses-base-foo1
  init libbase1
  init libuses-base-bar
  init libbase1

  $ ./some-app-2
  init libuses-base-foo2
  Required libbase version 2 but found version 1.  Aborting.

  $ ldd .libs/some-app-2
        libuses-base-bar.so.1 => not found
        libbase1.so.1 => not found
        libuses-base-foo2.so.2 => not found
        libbase2.so.2 => not found
        libc.so.6 => /lib/libc.so.6 (0x40028000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

some-app-2 was linked against libuses-base-foo2 which was linked
against libbase2 and libuses-base-bar which was linked against
libbase1.  So when some-app-2 calls libuses_base_foo_init and that in
turn calls libbase_require_version(LIBBASE_MAJOR_VERSION), the check
fails because at runtime foo is calling the libbase_require_version
from libbase1, but passing it the compile-time embedded value for
LIBBASE_MAJOR_VERSION from the libbase2 it was compiled against.

Thoughts?

-- 
Rob Browning
rlb @defaultvalue.org, @linuxdevel.com, and @debian.org
Previously @cs.utexas.edu
GPG=1C58 8B2C FB5E 3F64 EA5C  64AE 78FE E5FE F0CB A0AD


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Perhaps we can (and should) just detect dangerous linkages...
  2002-10-13 17:33 Perhaps we can (and should) just detect dangerous linkages Rob Browning
@ 2002-10-13 19:05 ` Neil Jerram
  2002-10-13 19:58   ` Rob Browning
  0 siblings, 1 reply; 3+ messages in thread
From: Neil Jerram @ 2002-10-13 19:05 UTC (permalink / raw)
  Cc: guile-devel

>>>>> "Rob" == Rob Browning <rlb@defaultvalue.org> writes:

    Rob> some-app-2 was linked against libuses-base-foo2 which was linked
    Rob> against libbase2 and libuses-base-bar which was linked against
    Rob> libbase1.  So when some-app-2 calls libuses_base_foo_init and that in
    Rob> turn calls libbase_require_version(LIBBASE_MAJOR_VERSION), the check
    Rob> fails because at runtime foo is calling the libbase_require_version
    Rob> from libbase1, but passing it the compile-time embedded value for
    Rob> LIBBASE_MAJOR_VERSION from the libbase2 it was compiled against.

When an app like this is run, does the system load and use both
libbase1 and libbase2, or does it load both but only use one, or what?

        Neil



_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Perhaps we can (and should) just detect dangerous linkages...
  2002-10-13 19:05 ` Neil Jerram
@ 2002-10-13 19:58   ` Rob Browning
  0 siblings, 0 replies; 3+ messages in thread
From: Rob Browning @ 2002-10-13 19:58 UTC (permalink / raw)
  Cc: guile-devel

Neil Jerram <neil@ossau.uklinux.net> writes:

>>>>>> "Rob" == Rob Browning <rlb@defaultvalue.org> writes:
>
>     Rob> some-app-2 was linked against libuses-base-foo2 which was linked
>     Rob> against libbase2 and libuses-base-bar which was linked against
>     Rob> libbase1.  So when some-app-2 calls libuses_base_foo_init and that in
>     Rob> turn calls libbase_require_version(LIBBASE_MAJOR_VERSION), the check
>     Rob> fails because at runtime foo is calling the libbase_require_version
>     Rob> from libbase1, but passing it the compile-time embedded value for
>     Rob> LIBBASE_MAJOR_VERSION from the libbase2 it was compiled against.
>
> When an app like this is run, does the system load and use both
> libbase1 and libbase2, or does it load both but only use one, or what?

Well with my proposed checks, the app would just crater.  Without the
checks, see my earlier message(s) for more details, but the summary is
that athough I suspect it depends heavily on the OS (and probably even
on whether or not you're using libtool), on a current Debian/GNU/Linux
system using libtool, if you do nothing, some-app-2 can end up linked
indirectly against both libbase.1 and libbase.2, and at runtime, *all*
libbase symbols in the process image will resolve to one copy of
libbase, the other libbase will be completely shadowed.  Which one is
chosen appears to depend on the ordering of libuses-base-foo and
libuses-base-bar in the _LDADD line of some-app-2 -- whichever one is
first wins globally.

Presming that the ordering is such that libbase.2 dominates, I don't
actually know what happens if libbase.2 removes some symbols from the
libbase api.  Do the older libbase.1 versions of those symbols then
"show through"?  I suppose I could test, but I suspect the answer
would only mean something for the particular system I'm testing...

-- 
Rob Browning
rlb @defaultvalue.org, @linuxdevel.com, and @debian.org
Previously @cs.utexas.edu
GPG=1C58 8B2C FB5E 3F64 EA5C  64AE 78FE E5FE F0CB A0AD


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2002-10-13 19:58 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-10-13 17:33 Perhaps we can (and should) just detect dangerous linkages Rob Browning
2002-10-13 19:05 ` Neil Jerram
2002-10-13 19:58   ` Rob Browning

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).