From: Eli Zaretskii <eliz@gnu.org>
To: YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>,
Stefan Monnier <monnier@iro.umontreal.ca>,
Chong Yidong <cyd@gnu.org>, Kenichi Handa <handa@m17n.org>
Cc: 12242@debbugs.gnu.org, jca@wxcvbn.org
Subject: bug#12242: Emacs 24.2 RC1 build fails on OpenBSD
Date: Wed, 22 Aug 2012 19:58:12 +0300 [thread overview]
Message-ID: <83y5l6amor.fsf@gnu.org> (raw)
In-Reply-To: <wlmx1naaaw.wl%mituharu@math.s.chiba-u.ac.jp>
> Date: Wed, 22 Aug 2012 12:13:27 +0900
> From: YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
> Cc: jca@wxcvbn.org,
> 12242@debbugs.gnu.org
>
> >>>>> On Wed, 22 Aug 2012 06:02:06 +0300, Eli Zaretskii <eliz@gnu.org> said:
>
> >> Date: Wed, 22 Aug 2012 11:35:26 +0900 From: YAMAMOTO Mitsuharu
> >> <mituharu@math.s.chiba-u.ac.jp> Cc: jca@wxcvbn.org,
> >> 12242@debbugs.gnu.org
> >>
> >> I took a look at ralloc.c a bit, and I thought that the variable
> >> `use_relocatable_buffers' is not designed to be changed temporarily
> >> in the first place.
>
> > Why not? Can you tell what led you to that conclusion?
>
> > My reading of the code is that inhibiting relocation just means that
> > ralloc.c always asks for more memory when it cannot find a large
> > enough block in the existing heaps.
>
> For example, `virtual_break_value' is not updated in that case. It
> can lead to an inconsistent state as reported if r_alloc_sbrk is
> called with a positive argument via malloc when
> use_relocatable_buffers <= 0, and then it is called with a negative
> argument via free when use_relocatable_buffers > 0.
I see your point.
Unfortunately, using r_alloc_freeze/r_alloc_thaw doesn't seem to be
workable in practice, either. I tried to use it, and the best patch I
could come up with (got me through several bootstraps with different
compiler switches) is below. It is (a) butt-ugly, and (b) very
fragile, for the reasons I explain below.
Basically, the difficulty is to know which number to pass to
r_alloc_freeze. The only place that knows how much memory is to be
allocated is the code that actually allocates it. So I cannot put the
call to r_alloc_freeze in maybe_unify_char, where we now call
r_alloc_inhibit_buffer_relocation, because the memory allocations are
in the functions called from there, and the amount of memory is not
known to the caller in advance. Moreover, at least one of the
functions called from maybe_unify_char via load_charset allocates
memory in a data-dependent loop, so I think it is in principle
impossible to know how much memory it can ask for.
What's worse, malloc (at least the implementation in gmalloc.c) will
actually allocate more than it was asked for, and sometimes allocates
an additional chunk of memory on top of that to expand its internal
tables where it maintains information about the arena. The size of
this additional chunk is also data-dependent, so the value I add in
r_alloc_freeze in the patch below is not guaranteed to work, it's
based on what I saw during a bootstrap, with some safety margin added
for good measure.
So it sounds like the only practical way out of this mess is to step
back one notch and talk about bug #11519, which was the cause for
inhibiting relocations while maybe_unify_char is in progress. At the
time, Handa-san promised to work on removing unify_char, but I guess
that job is not yet done, since it isn't even on the trunk. Ken'ichi,
what would it take to do this now?
Another alternative would be to rewrite load_charset_map_from_file and
load_charset_map_from_vector so as not to allocate the large structs
they do now. (These functions also create char-tables, but I think a
char-table is enlarged 256 elements at a time, which doesn't cross the
threshold of "large" allocations that can trigger relocation in
ralloc.c. Am I missing something?)
Yet another possibility is to disable relocations entirely on all
platforms but MS-Windows (where the crash which triggered this bug
report doesn't happen, probably because there we reserve the memory at
startup in one contiguous block).
Any other suggestions and thoughts are welcome.
Last, but not least: I'm very sorry for this obstacle to making an
emergency release. It always bewilders me how such problems can lie
dormant for so long, until the most un-opportune moment.
Here's the patch that I DON'T recommend to install:
--- src/ralloc.c~0 2012-06-29 17:50:48.000000000 +0300
+++ src/ralloc.c 2012-08-22 16:59:32.511794000 +0300
@@ -1022,12 +1022,22 @@ r_re_alloc (POINTER *ptr, SIZE size)
void
r_alloc_freeze (long int size)
{
if (! r_alloc_initialized)
r_alloc_init ();
/* If already frozen, we can't make any more room, so don't try. */
if (r_alloc_freeze_level > 0)
size = 0;
+ else
+ {
+ /* malloc will usually ask for more than its callers, so ensure
+ we have some extra room. */
+ size += (max (__malloc_extra_blocks, 64) + 1) * 4096;
+ /* gmalloc will sometimes need to enlarge its internal tables,
+ which asks for yet more memory. */
+ size += size / 4;
+ }
/* If we can't get the amount requested, half is better than nothing. */
while (size > 0 && r_alloc_sbrk (size) == 0)
size /= 2;
--- src/charset.c~0 2012-06-29 17:50:48.000000000 +0300
+++ src/charset.c 2012-08-22 14:41:55.981714000 +0300
@@ -214,6 +214,10 @@ static struct
text and a string data may be relocated. */
int charset_map_loaded;
+/* Flag used to signal to load_charset_* that it is unsafe to relocate
+ buffers (indirectly via calls to rel_alloc_* functions in ralloc.c). */
+static int in_maybe_unify_char;
+
struct charset_map_entries
{
struct {
@@ -293,7 +297,20 @@ load_charset_map (struct charset *charse
else
{
if (! temp_charset_work)
- temp_charset_work = xmalloc (sizeof (*temp_charset_work));
+ {
+#ifdef REL_ALLOC
+ /* Allocating heap memory screws callers of this
+ function through STRING_CHAR_* macros that hold C
+ pointers to buffer text, if REL_ALLOC is used. */
+ if (in_maybe_unify_char)
+ r_alloc_freeze (sizeof (*temp_charset_work));
+#endif
+ temp_charset_work = xmalloc (sizeof (*temp_charset_work));
+#ifdef REL_ALLOC
+ if (in_maybe_unify_char)
+ r_alloc_thaw ();
+#endif
+ }
if (control_flag == 1)
{
memset (temp_charset_work->table.decoder, -1,
@@ -498,8 +515,19 @@ load_charset_map_from_file (struct chars
/* Use SAFE_ALLOCA instead of alloca, as `charset_map_entries' is
large (larger than MAX_ALLOCA). */
+#ifdef REL_ALLOC
+ /* The calls to SAFE_ALLOCA below can allocate heap memory, which
+ screws callers of this function through STRING_CHAR_* macros that
+ hold C pointers to buffer text, if REL_ALLOC is used. */
+ if (in_maybe_unify_char)
+ r_alloc_freeze (sizeof (struct charset_map_entries));
+#endif
SAFE_ALLOCA (head, struct charset_map_entries *,
sizeof (struct charset_map_entries));
+#ifdef REL_ALLOC
+ if (in_maybe_unify_char)
+ r_alloc_thaw ();
+#endif
entries = head;
memset (entries, 0, sizeof (struct charset_map_entries));
@@ -530,8 +558,16 @@ load_charset_map_from_file (struct chars
if (n_entries > 0 && (n_entries % 0x10000) == 0)
{
+#ifdef REL_ALLOC
+ if (in_maybe_unify_char)
+ r_alloc_freeze (sizeof (struct charset_map_entries));
+#endif
SAFE_ALLOCA (entries->next, struct charset_map_entries *,
sizeof (struct charset_map_entries));
+#ifdef REL_ALLOC
+ if (in_maybe_unify_char)
+ r_alloc_thaw ();
+#endif
entries = entries->next;
memset (entries, 0, sizeof (struct charset_map_entries));
}
@@ -566,8 +602,19 @@ load_charset_map_from_vector (struct cha
/* Use SAFE_ALLOCA instead of alloca, as `charset_map_entries' is
large (larger than MAX_ALLOCA). */
+#ifdef REL_ALLOC
+ /* The calls to SAFE_ALLOCA below can allocate heap memory, which
+ screws callers of this function through STRING_CHAR_* macros that
+ hold C pointers to buffer text, if REL_ALLOC is used. */
+ if (in_maybe_unify_char)
+ r_alloc_freeze (sizeof (struct charset_map_entries));
+#endif
SAFE_ALLOCA (head, struct charset_map_entries *,
sizeof (struct charset_map_entries));
+#ifdef REL_ALLOC
+ if (in_maybe_unify_char)
+ r_alloc_thaw ();
+#endif
entries = head;
memset (entries, 0, sizeof (struct charset_map_entries));
@@ -603,8 +650,16 @@ load_charset_map_from_vector (struct cha
if (n_entries > 0 && (n_entries % 0x10000) == 0)
{
+#ifdef REL_ALLOC
+ if (in_maybe_unify_char)
+ r_alloc_freeze (sizeof (struct charset_map_entries));
+#endif
SAFE_ALLOCA (entries->next, struct charset_map_entries *,
sizeof (struct charset_map_entries));
+#ifdef REL_ALLOC
+ if (in_maybe_unify_char)
+ r_alloc_thaw ();
+#endif
entries = entries->next;
memset (entries, 0, sizeof (struct charset_map_entries));
}
@@ -1641,13 +1696,9 @@ maybe_unify_char (int c, Lisp_Object val
return c;
CHECK_CHARSET_GET_CHARSET (val, charset);
-#ifdef REL_ALLOC
- /* The call to load_charset below can allocate memory, whcih screws
- callers of this function through STRING_CHAR_* macros that hold C
- pointers to buffer text, if REL_ALLOC is used. */
- r_alloc_inhibit_buffer_relocation (1);
-#endif
+ in_maybe_unify_char++;
load_charset (charset, 1);
+ in_maybe_unify_char--;
if (! inhibit_load_charset_map)
{
val = CHAR_TABLE_REF (Vchar_unify_table, c);
@@ -1662,9 +1713,6 @@ maybe_unify_char (int c, Lisp_Object val
if (unified > 0)
c = unified;
}
-#ifdef REL_ALLOC
- r_alloc_inhibit_buffer_relocation (0);
-#endif
return c;
}
next prev parent reply other threads:[~2012-08-22 16:58 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-20 19:53 bug#12242: Emacs 24.2 RC1 build fails on OpenBSD Jérémie Courrèges-Anglas
2012-08-21 3:03 ` Eli Zaretskii
2012-08-21 16:49 ` Eli Zaretskii
2012-08-21 19:23 ` Jérémie Courrèges-Anglas
2012-08-22 2:35 ` YAMAMOTO Mitsuharu
2012-08-22 3:02 ` Eli Zaretskii
2012-08-22 3:13 ` YAMAMOTO Mitsuharu
2012-08-22 16:58 ` Eli Zaretskii [this message]
2012-08-22 23:12 ` YAMAMOTO Mitsuharu
2012-08-23 16:06 ` Eli Zaretskii
2012-08-23 14:24 ` Chong Yidong
2012-08-23 16:16 ` Eli Zaretskii
2012-08-24 3:25 ` Chong Yidong
2012-08-24 8:46 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=83y5l6amor.fsf@gnu.org \
--to=eliz@gnu.org \
--cc=12242@debbugs.gnu.org \
--cc=cyd@gnu.org \
--cc=handa@m17n.org \
--cc=jca@wxcvbn.org \
--cc=mituharu@math.s.chiba-u.ac.jp \
--cc=monnier@iro.umontreal.ca \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).