www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - __libc_stack_end not done correctly

reply evilmrhenry dontyajusthatespamemhsoft.net writes:
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.
)
Jun 02 2005
parent reply "Walter" <newshound digitalmars.com> writes:
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.
Jun 02 2005
parent reply evilmrhenry deathofspamemhsoft.net writes:
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.
Jun 04 2005
parent reply "Walter" <newshound digitalmars.com> writes:
Thanks, I'll fold this stuff in.
Jun 05 2005
parent reply evilmrhenry at the domain of emhsoft.net <evilmrhenry_member pathlink.com> writes:
In article <d80rpv$2p85$3 digitaldaemon.com>, Walter says...
Thanks, I'll fold this stuff in.

You have to remove the void* __libc_stack_end; from linuxextern.d. Even if the variable is unused, it still breaks compatibility.
Jun 09 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"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.

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?
Jun 15 2005
next sibling parent evilmrhenry <evilmrhenry_member pathlink.com> writes:
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.

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.

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?

with 106. Here's the diff from 106: http://www.emhsoft.net/phobos_diff.txt Maybe you'll see something.
Jun 18 2005
prev sibling parent Someguy <someguy somewhere.org> writes:
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.
Jul 16 2007