Thread overview
__libc_stack_end not done correctly
Jun 02, 2005
evilmrhenry
Jun 02, 2005
Walter
Jun 04, 2005
evilmrhenry
Jun 06, 2005
Walter
Jun 15, 2005
Walter
Jun 19, 2005
evilmrhenry
Jul 16, 2007
Someguy
June 02, 2005
Linux, dmd version 0.106. (Yes, I know. 0.106 is the last dmd version that can compile the program in question. 0.125 has identical code in the relevant areas.)

The reference to __libc_stack_end in std/c/linux/linuxextern.d is not done
correctly. Currently, it reads:
void* __libc_stack_end;
Which prevents compiled programs from working on machines with even slightly
differing glibc versions (even between 2.3.2 and 2.3.4). If a compiled program
attempts to run on a machine with a different glibc version, it will simply give
the error:
symbol __libc_stack_end, version GLIBC_PRIVATE not defined in file ld-linux.so.2
with link time reference

The correct way to do this involves using the dlsym() function at runtime to
determine the value of __libc_stack_end. For example:
handle = dlopen("/lib/libc.so.6", RTLD_NOW);
libc_stack_end = cast(int *)dlsym(handle, "__libc_stack_end");
dlclose(handle);

A quick hack to phobos shows that this method works, (people can now run the binary that weren't able to before) but as I don't actually know how to program in D, my patched version of phobos causes programs compiled with it to crash after a minute or two. Still, for that minute or two, the executable works on a wider range of computers.

Links:
http://www.opengroup.org/onlinepubs/007908799/xsh/dlsym.html
(manual for dlsym function)
http://autopackage.org/forums/viewtopic.php?t=22
(discussion on autopackage board)
http://www.emhsoft.net/ttrooper/
(program in question)
http://www.emhsoft.net/ttrooper/ttrooper_libc2.tar.gz
(executable created with patched version of phobos. Tends to crash.
)


June 02, 2005
It may be crashing because the libc_stack_end found with your method may not actually be the correct end of the stack. Or perhaps it's off by a pointer indirection. If it's not correct, the program will crash when the garbage collector runs.


June 04, 2005
In article <d7nvie$2ctq$1@digitaldaemon.com>, Walter says...
>
>It may be crashing because the libc_stack_end found with your method may not actually be the correct end of the stack. Or perhaps it's off by a pointer indirection. If it's not correct, the program will crash when the garbage collector runs.

The crashing was due to bad pointers in my hack. I have fixed it so it is not as "hackish", and am posting it as an example of how to fix this bug:

(This replaced the function of the same name in gclinux.d; there's another call to __libc_stack_end in thread.d that also needed to be fixed.)

void **libc_stack_end;
void *os_query_stackBottom()
{
if(libc_stack_end != libc_stack_end.init)
{
return *libc_stack_end;
}
HModule_    handle;
handle = dlopen(cast(char *)0, RTLD_NOW);
libc_stack_end = cast(void **)dlsym(handle, "__libc_stack_end");
dlclose(handle);
return *libc_stack_end;
}

I also added the following to linuxextern.d, inside the "extern (C)": const int RTLD_NOW  =   0x00002; /* Correct for Red Hat 8 */

typedef void    *HModule_;

HModule_    dlopen(char *path, int mode);
int         dlclose(HModule_ handle);
void        *dlsym(HModule_ handle, char *symbolName);



This code is in the public domain.

Anyway, this bug still needs to fixed within standard D/phobos.


June 06, 2005
Thanks, I'll fold this stuff in.


June 09, 2005
In article <d80rpv$2p85$3@digitaldaemon.com>, Walter says...
>
>Thanks, I'll fold this stuff in.
>
I just checked 0.126; one more thing:

You have to remove the
void* __libc_stack_end;
from linuxextern.d. Even if the variable is unused, it still breaks
compatibility.



June 15, 2005
"evilmrhenry at the domain of emhsoft.net" <evilmrhenry_member@pathlink.com> wrote in message news:d8ajnm$2ji9$1@digitaldaemon.com...
> In article <d80rpv$2p85$3@digitaldaemon.com>, Walter says...
> >
> >Thanks, I'll fold this stuff in.
> >
> I just checked 0.126; one more thing:
>
> You have to remove the
> void* __libc_stack_end;
> from linuxextern.d. Even if the variable is unused, it still breaks
> compatibility.

It shouldn't. linuxextern isn't even linked in.

Also, your fix is in the library source, but is conditionally compiled out at the moment, because it wouldn't link. Which extra library needs to be linked in?


June 19, 2005
In article <d8q102$oq7$2@digitaldaemon.com>, Walter says...
>
>
>"evilmrhenry at the domain of emhsoft.net" <evilmrhenry_member@pathlink.com> wrote in message news:d8ajnm$2ji9$1@digitaldaemon.com...
>> In article <d80rpv$2p85$3@digitaldaemon.com>, Walter says...
>> >
>> >Thanks, I'll fold this stuff in.
>> >
>> I just checked 0.126; one more thing:
>>
>> You have to remove the
>> void* __libc_stack_end;
>> from linuxextern.d. Even if the variable is unused, it still breaks
>> compatibility.
>
>It shouldn't. linuxextern isn't even linked in.
I was getting that problem with __libc_stack_end even when unused. I commented it out, and it worked. Anyway, it's (should be) unused now, so it wouldn't hurt anything to remove it.

>Also, your fix is in the library source, but is conditionally compiled out at the moment, because it wouldn't link. Which extra library needs to be linked in?
This is a bit odd. I did not need to link any extra libraries in when dealing
with 106. Here's the diff from 106:
http://www.emhsoft.net/phobos_diff.txt
Maybe you'll see something.


July 16, 2007
Check out file: dotgnu-pnet/pnet/libgc/os_dep.c
From: http://www.gnu.org/software/dotgnu/

There is code for libc_stack_end on various OS's.