trinity-devel@lists.pearsoncomputing.net

Message: previous - next
Month: March 2012

Re: [trinity-devel] QT API renaming! Why?!

From: Aleksey Midenkov <midenok@...>
Date: Thu, 8 Mar 2012 13:59:01 +0400
On Wed, Mar 7, 2012 at 9:41 PM, Timothy Pearson
<kb9vqf@...> wrote:
> <snip>
>>> Yes!  I'll pick an obvious example, KHTML.  I would like to replace the
> broken KHTML engine with Webkit using Qt4.  Problem is, I can't link a
> Qt4
>>> library into a TDE library or program due to symbol conflicts.  Even if
> you trick the compiler and linker, the program will crash at runtime
> because the C++ runtime will not know which symbols (Qt3 or Qt4) to use
^^^
> when function names and static members have the same name.
>> But that is what the linker does. Isn't it?
...
>
> Actually the linker creates a reference to a "mangled" symbol--see
> http://en.wikipedia.org/wiki/Name_mangling#Name_mangling_in_C.2B.2B
>
> Let's take a simple example, qWarning.  This becomes _Z8qWarningPKcz in
> libqt-mt.so.3.3.8 (nm -D /usr/lib/libqt-mt.so | grep qWarning), and
> _Z8qWarningPKcz in /usr/lib/libQtCore.so (nm -D /usr/lib/libQtCore.so |
> grep qWarning).  If my program references Z8qWarningPKcz, which library
> will the symbol resolver choose at runtime?  They are not binary
> compatible with each other, and when the symbol resolver chooses the wrong
> one at runtime (which it will do quite often) the entire program will
> crash.

Ok, you are telling about dynamic (or runtime) linking then. That is
not 'C++ runtime'. Saying this had lead me to misunderstanding,
because C++ runtime is exception and type handling.

Well, I understand now that the problem is a bit more complex. But
I've found two solution candidates so far! Obvious one and cunning
one. The obvious is to compile Qt4 in different namespace
(-qtnamespace option).

The cunning one is to make run-time loader to correctly do symbol
mapping. Since ld.so loader yet doesn't support direct binding
(http://en.wikipedia.org/wiki/Direct_binding) this can be done with
dlopen(RTLD_DEEPBIND) at SO init time. I've put some example in bug
900. Please, look at lib_vinegret.tar.gz.

You'll find in 'lib_vinegret' dir the simplified matter of problem:
lib_v1.c: Qt3 library
lib_v1_user.c: Most TDE code
lib_v2.c: Qt4 library
lib_v2_user.c: TDE code that wants to use Qt4

When you intermix 'lib_v1' and 'lib_v2' in one executable you will get
'lib_v2_user' executing 'lib_v1' instead of 'lib_v2'.
Please, type 'make', then './run.sh' to look at the results:

This is v1 user
This is v1 library!
This is v2 user
This is v1 library!

You can examine why this happened in generated rtld.log. The
interesting lines are:

      4885:     object=./lib_v1_user.so [0]
      4885:      scope 0: ./executable ./lib_v1_user.so
./lib_v2_user.so /lib/x86_64-linux-gnu/libc.so.6 ./lib_v1.so
./lib_v2.so /lib64/ld-linux-x86-64.so.2
      4885:
      4885:     object=./lib_v2_user.so [0]
      4885:      scope 0: ./executable ./lib_v1_user.so
./lib_v2_user.so /lib/x86_64-linux-gnu/libc.so.6 ./lib_v1.so
./lib_v2.so /lib64/ld-linux-x86-64.so.2

Note the 'scope 0'. It is same for all objects and called 'global
scope'. The order in this scope shows the actual order of symbol
searches. So the 'lib_function' symbol will be found always from
./lib_v1.so. Further entries in rtld.log confirm that.

Sadly enough, there is no way to force dynamic linker to load
different objects with different lookup scopes. But here comes
RTLD_DEEPBIND to the stage. Please, look at this diff:

http://bugs.pearsoncomputing.net/attachment.cgi?id=468&action=diff

I made some wrapper 'lib_v2_user_scoper' around the code we want to
load with different library. If you run this variant, you should see
this:

This is v1 user
This is v1 library!
This is v2 user
This is v2 library!
This is v1 user
This is v1 library!
This is v2 user
This is v2 library!

Voila! :-)

If per chance you will remove RTLD_DEEPBIND flag you will see the old
flat way of resolution:

This is v1 user
This is v1 library!
This is v2 user
This is v1 library!
This is v1 user
This is v1 library!
This is v2 user
This is v1 library!

Alex

 >
> <snip>
>> I suppose this could be done in more easy way without renaming.
>
> Not really, see above. :-)
>
> And if you want to work on a "pure" KDE 3.5.10 fork you have that right;
> just be aware that you will hit a dead end far before TDE will. ;-)
>
> Tim
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: trinity-devel-unsubscribe@...
> For additional commands, e-mail: trinity-devel-help@...
> Read list messages on the web archive: http://trinity-devel.pearsoncomputing.net/
> Please remember not to top-post: http://trinity.pearsoncomputing.net/mailing_lists/#top-posting
>