Bug 9750 - nscd gc() segmentation fault by estimation failure of alloca()'s stack usage
Summary: nscd gc() segmentation fault by estimation failure of alloca()'s stack usage
Alias: None
Product: glibc
Classification: Unclassified
Component: nscd (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Ulrich Drepper
Depends on:
Reported: 2009-01-16 11:42 UTC by Jun'ichi Nomura
Modified: 2014-07-01 21:19 UTC (History)
2 users (show)

See Also:
Last reconfirmed:


Note You need to log in before you can comment on or make changes to this bug.
Description Jun'ichi Nomura 2009-01-16 11:42:33 UTC
The garbage collection function, gc(), estimates the stack usage
to switch the allocation method.

For the allocation of 'struct moveinfo', it adds the size given to alloca().
In fucntion gc():
          new_move = alloca (sizeof (*new_move));
          stack_used += sizeof (*new_move);

However, alloca() seems to allocate additional +16 bytes for each allocation
in my case (Fedora 9, x86_64).
As a result, the estimation gets wrong and gc() ends up to segmentation fault.

Simply summing up the extra 16 bytes to the estimation would solve the problem.

Or if there is a better method to determine the current stack usage,
it might be better to switch the whole estimation stuff to use that.
Comment 1 Ulrich Drepper 2009-01-29 00:18:28 UTC
I've fixed that in cvs by using real stack use information for x86-64.
Comment 2 Jun'ichi Nomura 2009-01-29 04:31:19 UTC
Thank you for the fix on x86_64, but I confirmed the same problem occurs on i386
(alloca() pads the extra 16 bytes on Fedora 9 i386, too.
 May also on other archs but I don't have machines to check with.)

Could you put a "%%esp" version of the stackinfo_get_sp/stackinfo_sub_sp macros
to sysdeps/i386, too?

Also, the following fallback macro in alloca.h doesn't compile anyway:
  # define alloca_account(size, avar) \
    ({ size_t s__ = (size);                   \
       avar += size__;                        \
       __alloca (size__); })

Should "s__" be "size__"?
Comment 3 Jun'ichi Nomura 2009-01-29 05:24:31 UTC
In case anyone have archs other than i386/x86_64, try the following test program
to see whether the default alloca_account works.

#include <stdio.h>
#include <alloca.h>

#if !defined(alloca_account)
#define alloca_account(size, avar) \
  ({ size_t size__ = (size);       \
     avar += size__;               \
     alloca (size__); })

int test_alloc_size[] = { 4, 8, 16, 32, 48, 64, 100, };

test_alloca(size_t sz)
	int i;
	char *cur, *prev;
	int stk_usage = 0, stk_usage_real = 0;

	printf("unit allocation size = %d\n", sz);

	prev = alloca(sz);

	for (i = 0; i < 3; i++) {
		cur = alloca_account(sz, stk_usage);
		stk_usage_real += prev - cur;
		prev = cur;
		printf("#  [%d] stack used: %d (accounted as %d)\n",
			i, stk_usage_real, stk_usage);

	if (stk_usage != stk_usage_real)
		printf("FAIL: accounted usage differs from the real usage\n");

main(int argc, char **argv)
	int n = 0;

	while (test_alloc_size[n]) {
Comment 4 Jun'ichi Nomura 2009-01-29 05:27:56 UTC
Oops, sorry.

In the previous comment, this:
  int test_alloc_size[] = { 4, 8, 16, 32, 48, 64, 100, };
should be:
  int test_alloc_size[] = { 4, 8, 16, 32, 48, 64, 100, 0, };
Comment 5 Ulrich Drepper 2009-02-07 04:29:35 UTC
Don't attach comments without keeping the bug FIXED.