<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? Looks at symbolic names and
puts addresses instead. Therefore you shouldn't have name
conflicts at runtime. The crash you may encounter is because the linker
chosen wrong symbols to link together in one algorithm. But this have obvious solution. Put the code you want to link with Qt4 in separate module and link only with Qt4. I still don't understand how is renaming better solves this. Could you please refer exact source file and function?
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.
<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
On 03/07/2012 11:41 AM, Timothy Pearson wrote:
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. ;-)
No doubt. That just makes all the more impressive what Ilya has done for opensuse.
My primary desktops are TDE 3.5.12 (on Arch) and KDE 3.5.10 on opensuse 11.4. To be honest - from a user and function standpoint (sftp aside), they both work phenomenally. TDE R13 & R14 will as well, but, at least for Arch, there is tons of work to do to get all the features building.
Renaming/separate Qt4 modules -- it doesn't really matter to the user. However, it probably matters a lot from a long-term maintainability standpoint. From what I can tell at this point, tqt3 is doing a fine job. So much so, that when I opened konqueror for the first time in 'tree view' the (Name, Size, File Type, and Modified) columns all fit neatly inside the file list window while (Permissions, Owner, Group, Link) all neatly scrolled off the right-side and were easily viewable via the horizontal scroll. That is something that Qt4 has never been able to accomplish without the existing column sizes going all to hell.
From what I've seen, if TQt3 is maintainable, that should be the long-term solution for the foreseeable future -- until (and more importantly, if) Qt4 matures to the point that it can provide a workable replacement. It is far from there yet and IMHO most widgets still look like they were created by some teenager hopped up on Jolt soda saying "look Bevis -- see what I can make it do!" ;-)
On Wed March 7 2012 09:41:23 Timothy Pearson wrote:
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.
Could the problem you describe be addressed more easily with C++ namespaces?
--Mike Bird
On Wed March 7 2012 09:41:23 Timothy Pearson wrote:
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.
Could the problem you describe be addressed more easily with C++ namespaces?
--Mike Bird
No, unfortunately. The methods and variables that are in conflict are either static global or due to identical class and method naming. Also, using namespaces that heavily will introduce other problems.
Tim
On Wed, Mar 7, 2012 at 9:41 PM, Timothy Pearson kb9vqf@pearsoncomputing.net 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@lists.pearsoncomputing.net For additional commands, e-mail: trinity-devel-help@lists.pearsoncomputing.net 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