Board index » kylix » Changing Libc

Changing Libc


2005-06-11 04:20:41 AM
kylix2
I've made a simple application that opens 50 threads, each of these
threads open 1000 threads. When executed, the application stop in 2304
threads.
So I created a Java application that do the same. The java application
gots 4893 threads until my system stopped (Pentium 4 3.0Ghz
Hyperthreading, 512MB, running a Fedora Core 3 with kernel 2.6.9-SMP).
So I asked myself: "why java gots more threads?". So I did a ldd on my
app and on the java app. The diference is that my kylix app is linked
with libc on /lib/libc.so.6 and the java executable is linked with libc
in /lib/tls/libc.so.6 ( this probably is a newer version with nptl
support, but I'm not sure ).
I'm trying change the Kylix RTL to support the new libc. I edited the
Libc.pas and the System.pas and changed the references to libc.so.6 to a
/lib/tls/libc.so.6. But I don't know how do I do to recompile the Kylix RTL.
Is this the correct way?
Do you know how to recompile the RTL of Kylix ?
Thanks
 
 

Re:Changing Libc

Filipe Niero Felisbino wrote:
Quote
Is this the correct way?
Do you know how to recompile the RTL of Kylix ?
- Change to kylix3/source/rtl
- Open the GNUmakefile in an editor and adjust the
line "BINDIR = /usr/local/kylix" to the correct kylix3 path.
- start "make -fGNUmakefile"
--
Regards,
Andreas Hausladen
(www.kylix-patch.de.vu - unofficial Kylix 3 patches)
(andy.jgknet.de/blog)
 

Re:Changing Libc

OK, I've recompiled the RTL and my program, but when I do a ldd Project2
I got the same as before:
/lib/libNoVersion.so.1 (0x55018000)
libpthread.so.0 =>/lib/libpthread.so.0 (0x5502f000)
libdl.so.2 =>/lib/libdl.so.2 (0x55082000)
libc.so.6 =>/lib/libc.so.6 (0x55086000)
/lib/ld-linux.so.2 (0x55000000)
But in my Libc.pas and System.pas I've already changed it from
'libc.so.6' to '/lib/tls/libc.so.6'. What I'm doing wrong?
Thanks
Andreas Hausladen wrote:
Quote
Filipe Niero Felisbino wrote:


>Is this the correct way?
>Do you know how to recompile the RTL of Kylix ?


- Change to kylix3/source/rtl
- Open the GNUmakefile in an editor and adjust the
line "BINDIR = /usr/local/kylix" to the correct kylix3 path.
- start "make -fGNUmakefile"


 

{smallsort}

Re:Changing Libc

Filipe Niero Felisbino wrote:
Quote
OK, I've recompiled the RTL and my program, but when I do a ldd Project2
Maybe the compiler changes this (what I cannot believe because if you
write: external '/lib/tls/libc.6.so' , the compiler should use this
library. Maybe the Linux dynamic linker treats libc in a special way.
--
Regards,
Andreas Hausladen
(www.kylix-patch.de.vu - unofficial Kylix 3 patches)
(andy.jgknet.de/blog)
 

Re:Changing Libc

Andreas Hausladen wrote:
Quote
Filipe Niero Felisbino wrote:


>OK, I've recompiled the RTL and my program, but when I do a ldd Project2


Maybe the compiler changes this (what I cannot believe because if you
write: external '/lib/tls/libc.6.so' , the compiler should use this
library. Maybe the Linux dynamic linker treats libc in a special way.
If it does this, it's a big problem. Another way to do that is to
writing a procedure to start threads. Borland RTL gives a way to do this
on linux by assigning a procedure to de global variable BeginThreadProc.
So I tryed to create my specific function to start threads like this:
function myBeginThread (Attribute: PThreadAttr;
ThreadFunc: TThreadFunc; Parameter: Pointer;
var ThreadId: Cardinal): Integer;
And I also declared the my_pthread_create function that is to be called
by myBeginThread. In the myBeginThread function I called
my_pthread_create to create a thread on the OS.
function my_pthread_create(var ThreadID: Cardinal; Attr: PThreadAttr;
TFunc: TThreadFunc; Arg: Pointer): Integer; cdecl;
external '/lib/tls/libc.so.6' name 'pthread_create';
The code works, the threads are being created and running correctly, but
the for my surprise, my application continues being linked to /lib/libc.so.6
This is a really big problem, I cannot use the newer version of libc.
Borland must pay more attention to kylix, here in Brazil for 2 or 3
months borland has sold more kylix copies that delphi copies.
But now, everybody that bought Kylix is revolted with the Borland's
position to don't continue with Kylix....
 

Re:Changing Libc

Filipe Niero Felisbino wrote:
Quote
If it does this, it's a big problem.
I wrote a small program to test this. I used the original Libc.pas:
program test;
uses
Libc;
begin
WriteLn('Hallo World!');
end.
After compiling this with "dcc test.dpr" I got this result on a SuSE 9.2
ldd test
/lib/libNoVersion.so.1 =>/lib/libNoVersion.so.1 (0x40000000)
linux-gate.so.1 =>(0xffffe000)
libpthread.so.0 =>/lib/tls/libpthread.so.0 (0x4126b000)
libdl.so.2 =>/lib/libdl.so.2 (0x41132000)
libc.so.6 =>/lib/tls/libc.so.6 (0x4101a000)
/lib/ld-linux.so.2 =>/lib/ld-linux.so.2 (0x41000000)
Regards,
Andreas Hausladen
 

Re:Changing Libc

My god, how do we can understand this? I wrote this code also in my
Fedora Core 3 and the result of the ldd is:
/lib/libNoVersion.so.1 (0x55018000)
libpthread.so.0 =>/lib/libpthread.so.0 (0x5502f000)
libdl.so.2 =>/lib/libdl.so.2 (0x55082000)
libc.so.6 =>/lib/libc.so.6 (0x55086000)
/lib/ld-linux.so.2 (0x55000000)
Another thing that is different is that the compiled in your system uses
linux-gate that my doesn't uses.
Maybe any configuration of environment (env. variables or anything )?
I tryed to force the linux to load /lib/tls/libc.so.6 by using export
LD_PRELOAD=/lib/tls/libc.so.6, but I got the following message:
ERROR: ld.so: object '/lib/tls/libc.so.6' from LD_PRELOAD cannot be
preloaded: ignored.
My environment is attached in env.txt.
May you post your environment ?
May you send your compiled executable to me? So I'll do a ldd here to
see if this is fixed in the binary or is dinamically bound.
I'm thinking in install SuSE 9.2 to test this.
Thanks
Andreas Hausladen wrote:
Quote
Filipe Niero Felisbino wrote:


>If it does this, it's a big problem.


I wrote a small program to test this. I used the original Libc.pas:

program test;
uses
Libc;
begin
WriteLn('Hallo World!');
end.

After compiling this with "dcc test.dpr" I got this result on a SuSE 9.2

ldd test
/lib/libNoVersion.so.1 =>/lib/libNoVersion.so.1 (0x40000000)
linux-gate.so.1 =>(0xffffe000)
libpthread.so.0 =>/lib/tls/libpthread.so.0 (0x4126b000)
libdl.so.2 =>/lib/libdl.so.2 (0x41132000)
libc.so.6 =>/lib/tls/libc.so.6 (0x4101a000)
/lib/ld-linux.so.2 =>/lib/ld-linux.so.2 (0x41000000)



Regards,

Andreas Hausladen
 

Re:Changing Libc

Filipe Niero Felisbino wrote:
Quote
My god, how do we can understand this?
It's Linux :-)
Quote
Fedora Core 3 and the result of the ldd is:
Are there any other applications that use /lib/tls/libc.so.6 on your system?
Or does your kernel not use NPTL ?
Quote
Another thing that is different is that the compiled in your system uses
linux-gate that my doesn't uses.
The ELF does not include this, that is a library the dynamic linker
automatically adds when the application starts.
Quote
My environment is attached in env.txt.
Borland Newsgroup servers remove attachments. Attachments should go to
borland.public.attachments.
Regards,
Andreas Hausladen
 

Re:Changing Libc

Andreas Hausladen wrote:
Quote
Are there any other applications that use /lib/tls/libc.so.6 on your system?
Or does your kernel not use NPTL ?

Yes, my kernel uses NPTL but I think that only applications that are
linked to /lib/tls/libc.so.6 because if I execute /lib/tls/libc.so.6 I
get this:
# /lib/tls/libc.so.6
GNU C Library stable release version 2.3.5, by Roland McGrath et al.
Copyright (C) 2005 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 3.4.3 20050227 (Red Hat 3.4.3-22).
Compiled on a Linux 2.4.20 system on 2005-04-07.
Available extensions:
GNU libio by Per Bothner
crypt add-on version 2.1 by Michael Glad and others
Native POSIX Threads Library by Ulrich Drepper et al
The C stubs add-on version 2.1.2.
BIND-8.2.3-T5B
NIS(YP)/NIS+ NSS modules 0.19 by Thorsten Kukuk
Glibc-2.0 compatibility add-on by Cristian Gafton
GNU Libidn by Simon Josefsson
Thread-local storage support included.
For bug reporting instructions, please see:
<www.gnu.org/software/libc/bugs.html>.
But If I execute /lib/libc.so.6 I get this:
# /lib/libc.so.6
GNU C Library stable release version 2.3.5, by Roland McGrath et al.
Copyright (C) 2005 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 3.4.3 20050227 (Red Hat 3.4.3-22).
Compiled on a Linux 2.4.20 system on 2005-04-07.
Available extensions:
GNU libio by Per Bothner
crypt add-on version 2.1 by Michael Glad and others
linuxthreads-0.10 by Xavier Leroy
The C stubs add-on version 2.1.2.
BIND-8.2.3-T5B
NIS(YP)/NIS+ NSS modules 0.19 by Thorsten Kukuk
Glibc-2.0 compatibility add-on by Cristian Gafton
GNU Libidn by Simon Josefsson
libthread_db work sponsored by Alpha Processor Inc
Thread-local storage support included.
For bug reporting instructions, please see:
<www.gnu.org/software/libc/bugs.html>.
I tested some binarys from my system and all that I've tested are linked
to /lib/tls/libc.so.6. I tested thunderbird, gaim, http and others.
Following is the output of ldd /usr/sbin/httpd
libpcre.so.0 =>/lib/libpcre.so.0 (0x5506e000)
libpcreposix.so.0 =>/usr/lib/libpcreposix.so.0 (0x5507f000)
libaprutil-0.so.0 =>/usr/lib/libaprutil-0.so.0 (0x55082000)
libldap-2.2.so.7 =>/usr/lib/libldap-2.2.so.7 (0x55096000)
liblber-2.2.so.7 =>/usr/lib/liblber-2.2.so.7 (0x550c7000)
libdb-4.2.so =>/lib/tls/i686/libdb-4.2.so (0x550d3000)
libexpat.so.0 =>/usr/lib/libexpat.so.0 (0x551a1000)
libapr-0.so.0 =>/usr/lib/libapr-0.so.0 (0x551c1000)
librt.so.1 =>/lib/tls/librt.so.1 (0x551e3000)
libm.so.6 =>/lib/tls/libm.so.6 (0x551f7000)
libcrypt.so.1 =>/lib/libcrypt.so.1 (0x5521a000)
libpthread.so.0 =>/lib/tls/libpthread.so.0 (0x55248000)
libdl.so.2 =>/lib/libdl.so.2 (0x5525a000)
libc.so.6 =>/lib/tls/libc.so.6 (0x5525f000)
libresolv.so.2 =>/lib/libresolv.so.2 (0x55389000)
libsasl2.so.2 =>/usr/lib/libsasl2.so.2 (0x5539d000)
libssl.so.4 =>/lib/libssl.so.4 (0x553b1000)
libcrypto.so.4 =>/lib/libcrypto.so.4 (0x553e5000)
/lib/ld-linux.so.2 (0x55043000)
libgssapi_krb5.so.2 =>/usr/lib/libgssapi_krb5.so.2 (0x554cf000)
libkrb5.so.3 =>/usr/lib/libkrb5.so.3 (0x554e3000)
libcom_err.so.2 =>/lib/libcom_err.so.2 (0x55548000)
libk5crypto.so.3 =>/usr/lib/libk5crypto.so.3 (0x5554b000)
libz.so.1 =>/usr/lib/libz.so.1 (0x5556c000)
Note that both libc and libpthread that httpd is using is in /lib/tls. I
think that must be a way to define this ( maybe on the compile-time or
on runtime ). Probably your SuSE is already correctly configured to run
this way, but my Fedora not.
May you send your compiled binary to my e-mail address (
XXXX@XXXXX.COM ) ?
Thanks
 

Re:Changing Libc

Quote
The ELF does not include this, that is a library the dynamic linker
automatically adds when the application starts.

I think that is in the ELF file because the Sun's Java VM was recompiled
to support the nptl because the JVM 1.4.1 and before doesn't support the
nptl but the version 1.4.2 ( that is linked to /lib/tls/libc.so.6 )
works OK with nptl.
Thanks
 

Re:Changing Libc

Quote
Is this the correct way?
No. The problem is that most current Linux distributions now decide whichs libs to use
based on the OS ABI Tag inside the ELF executable.
Here is a description:
people.redhat.com/drepper/assumekernel.html
The issue is: The Kylix compiler/linker does not set an OS ABI Tag at all, so most version
of the dynamic linker seem to resort to "the oldest possible" here.
Here is a little breakdown I once wrote:
----------
- On Red Hat (and some Red-Hat-Like) distro, NPTL is around for quite
some time. Red Hat even backported it to the 2.4 kernel. By default
binaries running on Red Hat will get a NPTL-aware libc. If you do not
wish to have NPTL, you may use LD_ASSUME_KERNEL to force a different
ABI version. Kylix compiled ELFs don't have any ABI version tag, still
Red Hat uses NPTL for them. All is fine here.
The same seems to be the case with Suse (but not really tested from my
side)
- On Debian 3.1, things work completely different. To get NPTL, you have
to install an additional libc package, which will be installed to
/lib/tls/. Also you need to run a 2.6 kernel. ld will now examine the
ELF, and depending on $unknown, it will choose to either use the NPTL
libc from /lib/tls, or the regular one from /lib. As I understood it,
to find out which to use, it checks out the ABI-Tag of the ELF (some
section called .note.ABI-tag) to decide that. Kylix compiled
applications don't have that, and Debian 3.1 will use the regular
/lib/ libc. So: On Debian 3.1 Kylix applications work fine, but they
don't use NPTL. And up to now I have not found a way to force the
usage of NPTL. Sad, but at least Kylix applications work.
----------
If I'm not mistaken, the only real solution to the problem will
be getting the OS ABI Tag into Kylix-produced executables. Sadly this
can't easily be done, as changing the ELF file this way really would
need a re-link. I plan to investigate if there is an ugly way to find
a few unused bytes inside Kylix ELFs where the OS ABI entry could be
hacked in, but until now I haven't come round to it.
Simon
 

Re:Changing Libc

It's a very bad notice to me. Borland is really leaving it's developers
alone. This is not a good marketing to Borland. I spent too many time on
trying to solve this problem, wich is not my problem.
From now, I'll be looking at freepascal/lazarus project. I'll try to
port my applcation to the FreePascal compiler wich is free and fully
support more than 20 platforms.
This decision is bad to me, that decided to buy Borland's tools in past.
But from now on, I have a position when anyone ask me if it's a good
thing to buy borland's products.
Simon Kissel wrote:
Quote

No. The problem is that most current Linux distributions now decide whichs libs to use
based on the OS ABI Tag inside the ELF executable.

Here is a description:
people.redhat.com/drepper/assumekernel.html

The issue is: The Kylix compiler/linker does not set an OS ABI Tag at all, so most version
of the dynamic linker seem to resort to "the oldest possible" here.

Here is a little breakdown I once wrote:

----------
- On Red Hat (and some Red-Hat-Like) distro, NPTL is around for quite
some time. Red Hat even backported it to the 2.4 kernel. By default
binaries running on Red Hat will get a NPTL-aware libc. If you do not
wish to have NPTL, you may use LD_ASSUME_KERNEL to force a different
ABI version. Kylix compiled ELFs don't have any ABI version tag, still
Red Hat uses NPTL for them. All is fine here.

The same seems to be the case with Suse (but not really tested from my
side)

- On Debian 3.1, things work completely different. To get NPTL, you have
to install an additional libc package, which will be installed to
/lib/tls/. Also you need to run a 2.6 kernel. ld will now examine the
ELF, and depending on $unknown, it will choose to either use the NPTL
libc from /lib/tls, or the regular one from /lib. As I understood it,
to find out which to use, it checks out the ABI-Tag of the ELF (some
section called .note.ABI-tag) to decide that. Kylix compiled
applications don't have that, and Debian 3.1 will use the regular
/lib/ libc. So: On Debian 3.1 Kylix applications work fine, but they
don't use NPTL. And up to now I have not found a way to force the
usage of NPTL. Sad, but at least Kylix applications work.
----------

If I'm not mistaken, the only real solution to the problem will
be getting the OS ABI Tag into Kylix-produced executables. Sadly this
can't easily be done, as changing the ELF file this way really would
need a re-link. I plan to investigate if there is an ugly way to find
a few unused bytes inside Kylix ELFs where the OS ABI entry could be
hacked in, but until now I haven't come round to it.

Simon

 

Re:Changing Libc

Dear Filipe,
The situation you sketched seems pretty much like the problems I have using
plain Delphi.
After googling/asking for the solution I found the following:
On Windows using Delphi thread are created like so:
BeginThread(nil, 0, @ThreadProc, Pointer(Self), CREATE_SUSPENDED,
FThreadID);
which in turn calls:
CreateThread(SecurityAttributes, StackSize, @ThreadWrapper, P,
CreationFlags, ThreadID);
However, the call to createthread is always executed with StackSize=0,
meaning that the thread will receive a stacksize same as the applications
default stacksize (defaults to 1Mb).
Simple conclusion: a windows process receives a max stack of 2Gb. Now
threads are created with a stack of 1Mb, pushing the limit as soon as you
hit a 2000+ threads. Although the thread doesn't have to USE the 1Mb, it
WILL reserve it from the stack.
Looking at the Linux side of things, the call is slightly different:
BeginThread(nil, @ThreadProc, Pointer(Self), FThreadID);
which in turn calls:
_pthread_create(ThreadID, Attribute, @ThreadWrapper, P);
Here, the Attribute var (containing the neccesary thread info like stack
etc) is initializaed with nil in the BeginThread call...
My assumption is that Linux does the same as Windows does, and initializes
the thread with the app's stack size (probably 1Mb too).
Funny though that you Kylix app is able to create more that 2048 threads!!!
This would mean that you've already reached the max app stack long ago, so
I'm unsure wether my assumption is correct.
Worth looking into I suppose...
Hope this helps,
Rory Vieira
 

Re:Changing Libc

Rory Vieira wrote:
Quote
Funny though that you Kylix app is able to create more that 2048
threads!!! This would mean that you've already reached the max app stack
long ago, so I'm unsure wether my assumption is correct.
Worth looking into I suppose...
under linux you can set/see available max. threads in
/proc/sys/kernel/threads-max
eg:
[linda@houston kernel]# cat threads-max
32766