This is sources Bugzilla
Bugzilla Version 2.17.5
Bugzilla Bug 9750
  nscd gc() segmentation fault by estimation failure of alloca()'s stack usage Last modified: 2009-02-07 04:29
     Query page      Enter new bug
Bug#: 9750   Hardware:   Reporter: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
Host: Target: Build:
Product:     Add CC:
Component:   Version:   CC:
Remove selected CCs
Status: RESOLVED   Priority:  
Resolution: FIXED   Severity:  
Assigned To: Ulrich Drepper <drepper@redhat.com>   Target Milestone:  
Flags: Requestee:
  backport ()
  examined ()
  testsuite ()
Summary:
Keywords:

Attachment Description Type Created Actions
Create a New Attachment (proposed patch, testcase, etc.) View All

Bug 9750 depends on: Show dependency tree
Show dependency graph
Bug 9750 blocks:

Additional Comments:


Leave as RESOLVED FIXED
Reopen bug
Mark bug as VERIFIED

View Bug Activity   |   Format For Printing


Description:   Last confirmed: 0000-00-00 00:00 Opened: 2009-01-16 11:42
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().
http://sourceware.org/cgi-bin/cvsweb.cgi/libc/nscd/mem.c.diff?r1=1.3.2.8&r2=1.3.2.9&cvsroot=glibc
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.

------- Additional Comment #1 From Ulrich Drepper 2009-01-29 00:18 -------
I've fixed that in cvs by using real stack use information for x86-64.

------- Additional Comment #2 From Jun'ichi Nomura 2009-01-29 04:31 -------
Thank you for the fix on x86_64, but I confirmed the same problem occurs on i386
system.
(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?
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/x86_64/stackinfo.h.diff?r1=1.1&r2=1.2&cvsroot=glibc

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__); })
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/include/alloca.h.diff?r1=1.8&r2=1.9&cvsroot=glibc

Should "s__" be "size__"?

------- Additional Comment #3 From Jun'ichi Nomura 2009-01-29 05:24 -------
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__); })
#endif

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

void
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");
	else
		printf("PASS\n");
	printf("\n");
}

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

	while (test_alloc_size[n]) {
		test_alloca(test_alloc_size[n]);
		n++;
	}
}
----------------------------------------------------------------------------

------- Additional Comment #4 From Jun'ichi Nomura 2009-01-29 05:27 -------
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, };

------- Additional Comment #5 From Ulrich Drepper 2009-02-07 04:29 -------
Don't attach comments without keeping the bug FIXED.

     Query page      Enter new bug
Actions: New | Query | bug # | Reports | Requests   New Account | Log In