The initial problem was easy to describe: starting XEmacs with absolute
paths was broken (at least it is if you use a separate .dmp file, which
I'm constrained to right now because I'm using the new GC.)
loki 1686 /usr/packages/xemacs/i686-loki% which xemacs
/usr/bin/xemacs
loki 1687 /usr/packages/xemacs/i686-loki% xemacs -vanilla -batch -eval '(message
"foo")'
foo
loki 1685 /usr/packages/xemacs/i686-loki% /usr/bin/xemacs -vanilla -batch -eval
'(message "foo")'
temacs can only be run in -batch mode.
strace and valgrind (and a bit of gdb) pinpoint the cause:
loki 1688 /usr/packages/xemacs/i686-loki% strace -e open /usr/bin/xemacs -vanilla -batch
-eval '(message "foo")'
[...]
open("/lib/libpthread.so.0", O_RDONLY) = 3
open("", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/etc/fonts/fonts.conf", O_RDONLY|O_LARGEFILE) = 3
[...]
==29209== Syscall param open(filename) points to unaddressable byte(s)
==29209== at 0x4D873272: open64 (in /lib/libc-2.4.so)
==29209== Address 0xBEBA0070 is not stack'd, malloc'd or (recently) free'd
If you're unlucky, that "" turns into an -EFAULT, and if you're
*really*
unlucky, you get a segfault.
This is happening because in src/dumper.c:pdump_load(), exe_path is
being sized as (if XEmacs is invoked with an absolute path) one byte
longer than the length of the directory component of the name, or (if
XEmacs is invoked with a relative path) ten bytes longer than the larger
of the name and PATH variable...
... and then pdump_load() calls pdump_file_try(), which proceeds to
sprintf() things on the end of it, like "-21.5-b27-453712b7.dmp". Oops,
there's no room for that. Instant buffer overrun, and because that
structure is alloca()ed a lot of the time, instant stack overrun as
well, which if you're unlucky blows away a pile of variables,
invalidates `exe_path', et seq ad nauseam.
(Probably nobody's noticed this because most of the time XEmacs is
invoked without an absolute path, and most people have a PATH that is
much longer than five characters. I don't know what the ten bytes of
slop are for: it's not even long enough for `-21.4.16.dmp'...)
I've `fixed' this by moving from incorrect dynamic allocation to
arguably inefficient-but-who-cares static allocation: it's way too much
work to realloc() this string, and it's also way too much work to
determine the maximum possible length of that string (plus it's brittle;
the next time someone changes the filename construction method,
*boom*). This necessitated a tiny fix to text.h before PATH_MAX_EXTERNAL
could be used on non-Windows systems at all...
You may want to fix the fix if using PATH_MAX_{INTERNAL,EXTERNAL} is
really as bad as all that.
(This patch is against CVS HEAD.)
2006-10-26 Nix <nix(a)esperi.org.uk>
* dumper.c (pdump_load): Statically allocate a large enough
exe_path for all conceivable uses. Fixes a buffer overrun.
* text.h (MAX_XETCHAR_SIZE): Define, for PATH_MAX_EXTERNAL.
Index: 21.5/src/dumper.c
===================================================================
--- 21.5.orig/src/dumper.c 2006-10-26 00:29:53.000000000 +0100
+++ 21.5/src/dumper.c 2006-10-26 00:30:21.000000000 +0100
@@ -2658,7 +2658,7 @@
wext_strcpy (exe_path, wexe);
}
#else /* !WIN32_NATIVE */
- Wexttext *exe_path;
+ Wexttext exe_path[PATH_MAX_EXTERNAL];
Wexttext *w;
const Wexttext *dir, *p;
@@ -2692,8 +2692,7 @@
if (p != dir)
{
/* invocation-name includes a directory component -- presumably it
- is relative to cwd, not $PATH */
- exe_path = alloca_array (Wexttext, 1 + wext_strlen (dir));
+ is relative to cwd, not $PATH. */
wext_strcpy (exe_path, dir);
}
else
@@ -2701,9 +2700,6 @@
const Wexttext *path = wext_getenv ("PATH"); /* not egetenv --
not yet init. */
const Wexttext *name = p;
- exe_path = alloca_array (Wexttext,
- 10 + max (wext_strlen (name),
- wext_strlen (path)));
for (;;)
{
p = path;
Index: 21.5/src/text.h
===================================================================
--- 21.5.orig/src/text.h 2006-10-26 00:29:53.000000000 +0100
+++ 21.5/src/text.h 2006-10-26 00:30:21.000000000 +0100
@@ -2988,6 +2988,7 @@
/* Extra indirection needed in case of manifest constant as arg */
#define WEXTSTRING_1(arg) L##arg
#define WEXTSTRING(arg) WEXTSTRING_1(arg)
+#define MAX_XETCHAR_SIZE sizeof (WCHAR)
#define wext_strlen wcslen
#define wext_strcmp wcscmp
#define wext_strncmp wcsncmp
@@ -3013,6 +3014,7 @@
#else
#define WEXTTEXT_ZTERM_SIZE sizeof (char)
#define WEXTSTRING(arg) arg
+#define MAX_XETCHAR_SIZE sizeof (char)
#define wext_strlen strlen
#define wext_strcmp strcmp
#define wext_strncmp strncmp
--
`When we are born we have plenty of Hydrogen but as we age our
Hydrogen pool becomes depleted.'
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://calypso.tux.org/cgi-bin/mailman/listinfo/xemacs-patches