* elf/Versions (ld): Export _dl_out_of_memory for GLIBC_2.2.
* dlfcn/dlerror.c (dlerror): Don't free the error string if it is the
report that we are out of memory.
* elf/dl-deps.c (_dl_map_object_deps): Likewise.
* elf/dl-libc.c (dlerror_run): Likewise.
* elf/dl-open.c (_dl_open): Likewise.
* elf/rtld.c (dl_main): Likewise.
* elf/dl-error.c: Define _dl_out_of_memory.
(_dl_signal_error): Return _dl_signal_error if we cannot duplicate
the error string.
* sysdeps/generic/ldsodefs.h: Declare _dl_out_of_memory.
* dlfcn/dlerror.c (free_key_mem): Also free error string.
* iconv/loop.c: Fix comment.
2000-07-13 Ulrich Drepper <drepper@redhat.com>
+ * elf/Versions (ld): Export _dl_out_of_memory for GLIBC_2.2.
+ * dlfcn/dlerror.c (dlerror): Don't free the error string if it is the
+ report that we are out of memory.
+ * elf/dl-deps.c (_dl_map_object_deps): Likewise.
+ * elf/dl-libc.c (dlerror_run): Likewise.
+ * elf/dl-open.c (_dl_open): Likewise.
+ * elf/rtld.c (dl_main): Likewise.
+ * elf/dl-error.c: Define _dl_out_of_memory.
+ (_dl_signal_error): Return _dl_signal_error if we cannot duplicate
+ the error string.
+ * sysdeps/generic/ldsodefs.h: Declare _dl_out_of_memory.
+
+ * dlfcn/dlerror.c (free_key_mem): Also free error string.
+
+ * iconv/loop.c: Fix comment.
+
* malloc/mtrace.c (tr_freehook): Return immediately if ptr is NULL.
2000-07-13 Andreas Jaeger <aj@suse.de>
static struct dl_action_result last_result;
static struct dl_action_result *static_buf;
-
/* This is the key for the thread specific memory. */
static __libc_key_t key;
/* We can now free the string. */
if (result->errstring != NULL)
{
- free ((char *) result->errstring);
+ if (strcmp (result->errstring, "out of memory") != 0)
+ free ((char *) result->errstring);
result->errstring = NULL;
}
buf = NULL;
strerror (result->errcode)) != -1)
{
/* We don't need the error string anymore. */
- free ((char *) result->errstring);
+ if (strcmp (result->errstring, "out of memory") != 0)
+ free ((char *) result->errstring);
result->errstring = buf;
}
{
/* Free the error string from the last failed command. This can
happen if `dlerror' was not run after an error was found. */
- free ((char *) result->errstring);
+ if (strcmp (result->errstring, "out of memory") != 0)
+ free ((char *) result->errstring);
result->errstring = NULL;
}
static void
free_key_mem (void *mem)
{
+ struct dl_action_result *result = (struct dl_action_result *) mem;
+
+ if (result->errstring != NULL
+ && strcmp (result->errstring, "out of memory") != 0)
+ free (result->errstring);
+
free (mem);
__libc_setspecific (key, NULL);
}
# this is defined in ld.so and overridden by libc
_dl_init_first;
+
+ # variables used elsewhere
+ _dl_out_of_memory;
}
}
{
/* We are not interested in the error message. */
assert (errstring != NULL);
- free ((char *) errstring);
+ if (errstring != _dl_out_of_memory)
+ free ((char *) errstring);
/* Simply ignore this error and continue the work. */
continue;
#define tsd_setspecific(data) __libc_tsd_set (DL_ERROR, (data))
+/* This message we return as a last resort. We define the string in a
+ variable since we have to avoid freeing it and so have to enable
+ a pointer comparison. See below and in dlfcn/dlerror.c. */
+const char _dl_out_of_memory[] = "out of memory";
+
+
/* This points to a function which is called when an continuable error is
received. Unlike the handling of `catch' this function may return.
The arguments will be the `errstring' and `objname'.
stack. The object name is always a string constant. */
lcatch->objname = objname;
lcatch->errstring = strdup (errstring);
+ if (lcatch->errstring == NULL)
+ lcatch->errstring = _dl_out_of_memory;
longjmp (lcatch->env, errcode ?: -1);
}
else
(void) _dl_catch_error (&objname, &last_errstring, operate, args);
result = last_errstring != NULL;
- if (result)
+ if (result && last_errstring != _dl_out_of_memory)
free ((char *) last_errstring);
return result;
/* Make a local copy of the error string so that we can release the
memory allocated for it. */
local_errstring = strdupa (errstring);
- free ((char *) errstring);
+ if (errstring != _dl_out_of_memory)
+ free ((char *) errstring);
/* Reraise the error. */
_dl_signal_error (errcode, objname, local_errstring);
(void) _dl_catch_error (&objname, &err_str, map_doit, &args);
if (__builtin_expect (err_str != NULL, 0))
{
- free ((char *) err_str);
+ if (err_str != _dl_out_of_memory)
+ free ((char *) err_str);
_exit (EXIT_FAILURE);
}
}
while (inptr != inend)
{
/* `if' cases for MIN_NEEDED_OUTPUT ==/!= 1 is made to help the
- compiler generating better code. It will optimized away
+ compiler generating better code. They will be optimized away
since MIN_NEEDED_OUTPUT is always a constant. */
if ((MIN_NEEDED_OUTPUT != 1
&& __builtin_expect (outptr + MIN_NEEDED_OUTPUT > outend, 0))
/* Nonzero if references should be treated as weak during runtime linking. */
extern int _dl_dynamic_weak;
+/* The array with message we print as a last resort. */
+extern const char _dl_out_of_memory[];
+
/* OS-dependent function to open the zero-fill device. */
extern int _dl_sysdep_open_zero_fill (void); /* dl-sysdep.c */