Summary: | nscd gc() segmentation fault by estimation failure of alloca()'s stack usage | ||
---|---|---|---|
Product: | glibc | Reporter: | Jun'ichi Nomura <j-nomura> |
Component: | nscd | Assignee: | Ulrich Drepper <drepper.fsp> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | fweimer, glibc-bugs |
Priority: | P2 | ||
Version: | unspecified | ||
Target Milestone: | --- | ||
Host: | Target: | ||
Build: | Last reconfirmed: |
Description
Jun'ichi Nomura
2009-01-16 11:42:33 UTC
I've fixed that in cvs by using real stack use information for x86-64. 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__"? 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++; } } ---------------------------------------------------------------------------- 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, }; Don't attach comments without keeping the bug FIXED. |