Messages in this thread Patch in this message | | | Date | Tue, 19 Oct 2004 19:17:43 +0200 | From | Ingo Molnar <> | Subject | Re: [patch] Real-Time Preemption, -RT-2.6.9-rc4-mm1-U6 |
| |
* Ingo Molnar <mingo@elte.hu> wrote:
> enabling 8K stacks ought to help this one. I've made the limit a bit > too conservative - there's still 1000 bytes left and the assert hits. > Here's the full trace, the large footprint seems to be in zlib > initialization: > > mcount: stack overflow: 1008
i've added a stackframe-size field to the end of every stack trace entry:
mcount: stack overflow: 1008 [<c012cdaf>] ___trace+0x105/0x117 (12) [<c012cde7>] __mcount+0x1d/0x1f (32) [<c013e025>] cache_grow+0xe/0x1ab (4) [<c013e3dd>] cache_alloc_refill+0x21b/0x253 (4) [<c010effc>] mcount+0x14/0x18 (8) [<c013e025>] cache_grow+0xe/0x1ab (20) [<c013e3dd>] cache_alloc_refill+0x21b/0x253 (52) [<c013e740>] __kmalloc+0x82/0x9f (48) [<c03607c8>] malloc+0x1e/0x20 (28) [<c01008c9>] huft_build+0x309/0x5e8 (16) [<c0101bec>] inflate+0x4c/0xb0 (1444) [<c010effc>] mcount+0x14/0x18 (8) [<c0101279>] inflate_fixed+0xcb/0x1a4 (20) [<c0101bec>] inflate+0x4c/0xb0 (1212) [<c010effc>] mcount+0x14/0x18 (12) [<c0101eae>] gunzip+0x1d4/0x396 (20) [<c036130e>] unpack_to_rootfs+0x162/0x225 (28) [<c010effc>] mcount+0x14/0x18 (8) [<c0100434>] init+0x0/0x124 (4) [<c03613fe>] populate_rootfs+0x2d/0x3f (16) [<c010046b>] init+0x37/0x124 (20) [<c0102365>] kernel_thread_helper+0x5/0xb (20)
as suspected, zlib's huft_build() is fun:
lib/inflate.c:
#define N_MAX 288 /* maximum number of codes in any set */
STATIC int huft_build( ... {
unsigned v[N_MAX]; /* values in order of bit length */
a whopping 1152 bytes for this local variable alone! The patch below fixes this, but there are other overflows as well, later in the bootup.
Ingo
--- linux/lib/inflate.c.orig +++ linux/lib/inflate.c @@ -300,7 +300,7 @@ STATIC int huft_build( register struct huft *q; /* points to current table */ struct huft r; /* table entry for structure assignment */ struct huft *u[BMAX]; /* table stack */ - unsigned v[N_MAX]; /* values in order of bit length */ + unsigned *v; /* values in order of bit length */ register int w; /* bits before this table == (l * h) */ unsigned x[BMAX+1]; /* bit offsets, then code stack */ unsigned *xp; /* pointer into x */ @@ -309,6 +309,10 @@ STATIC int huft_build( DEBG("huft1 "); + /* allocate new table */ + v = (unsigned *)malloc(sizeof(unsigned)*N_MAX); + if (!v) + return 3; /* not enough memory */ /* Generate counts for each bit length */ memzero(c, sizeof(c)); p = b; i = n; @@ -322,6 +326,7 @@ DEBG("huft1 "); { *t = (struct huft *)NULL; *m = 0; + free(v); return 0; } @@ -347,10 +352,14 @@ DEBG("huft3 "); /* Adjust last length count to fill out codes, if needed */ for (y = 1 << j; j < i; j++, y <<= 1) - if ((y -= c[j]) < 0) + if ((y -= c[j]) < 0) { + free(v); return 2; /* bad input: more codes than bits */ - if ((y -= c[i]) < 0) + } + if ((y -= c[i]) < 0) { + free(v); return 2; + } c[i] += y; DEBG("huft4 "); @@ -422,6 +431,7 @@ DEBG1("3 "); { if (h) huft_free(u[0]); + free(v); return 3; /* not enough memory */ } DEBG1("4 "); @@ -485,6 +495,7 @@ DEBG("h6f "); DEBG("huft7 "); + free(v); /* Return true (1) if we were given an incomplete table */ return y != 0 && g != 1; } - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |