From bfe8fda504df2faa8792364f4181846de1f9e704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?agentzh=20=28=E7=AB=A0=E4=BA=A6=E6=98=A5=29?= Date: Thu, 7 Jun 2012 19:42:07 +0800 Subject: [PATCH] bugfix: the no-pool patch might leak memory. now we have updated the no-pool patch to the latest version that is a thorough rewrite. --- patches/nginx-1.0.15-no_pool.patch | 391 ++++++++++++++--------------- 1 file changed, 194 insertions(+), 197 deletions(-) diff --git a/patches/nginx-1.0.15-no_pool.patch b/patches/nginx-1.0.15-no_pool.patch index 094024c..eaa943e 100644 --- a/patches/nginx-1.0.15-no_pool.patch +++ b/patches/nginx-1.0.15-no_pool.patch @@ -10,17 +10,19 @@ diff -ur nginx-1.0.15/src/core/nginx.h nginx-1.0.15-patched/src/core/nginx.h +#define NGINX_VER "ngx_openresty/" NGINX_VERSION ".unknown (no pool)" #define NGINX_VAR "NGINX" -diff -ur nginx-1.0.15/src/core/ngx_array.c nginx-1.0.15-patched/src/core/ngx_array.c ---- nginx-1.0.15/src/core/ngx_array.c 2008-06-17 23:00:30.000000000 +0800 -+++ nginx-1.0.15-patched/src/core/ngx_array.c 2011-09-14 12:02:56.263128538 +0800 -@@ -39,13 +39,7 @@ +diff -urx '*~' -x '*.swp' nginx-1.0.15/src/core/ngx_array.c nginx-1.0.15-patched/src/core/ngx_array.c +--- nginx-1.0.15/src/core/ngx_array.c 2012-02-06 04:02:59.000000000 +0800 ++++ nginx-1.0.15-patched/src/core/ngx_array.c 2012-06-04 20:11:32.494144287 +0800 +@@ -40,13 +40,11 @@ p = a->pool; - if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) { - p->d.last -= a->size * a->nalloc; -- } -- ++ if (a->elts) { ++ ngx_pfree(p, a->elts); + } + - if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) { - p->d.last = (u_char *) a; - } @@ -28,7 +30,7 @@ diff -ur nginx-1.0.15/src/core/ngx_array.c nginx-1.0.15-patched/src/core/ngx_arr } -@@ -64,29 +58,17 @@ +@@ -65,29 +63,19 @@ p = a->pool; @@ -62,13 +64,15 @@ diff -ur nginx-1.0.15/src/core/ngx_array.c nginx-1.0.15-patched/src/core/ngx_arr } + + ngx_memcpy(new, a->elts, size); ++ ++ ngx_pfree(p, a->elts); ++ + a->elts = new; + a->nalloc *= 2; -+ } elt = (u_char *) a->elts + a->size * a->nelts; -@@ -100,43 +82,25 @@ +@@ -101,43 +89,28 @@ ngx_array_push_n(ngx_array_t *a, ngx_uint_t n) { void *elt, *new; @@ -116,28 +120,30 @@ diff -ur nginx-1.0.15/src/core/ngx_array.c nginx-1.0.15-patched/src/core/ngx_arr } + + ngx_memcpy(new, a->elts, a->nelts * a->size); ++ ++ ngx_pfree(p, a->elts); ++ + a->elts = new; + a->nalloc = nalloc; } elt = (u_char *) a->elts + a->size * a->nelts; -diff -ur nginx-1.0.15/src/core/ngx_palloc.c nginx-1.0.15-patched/src/core/ngx_palloc.c ---- nginx-1.0.15/src/core/ngx_palloc.c 2009-12-17 20:25:46.000000000 +0800 -+++ nginx-1.0.15-patched/src/core/ngx_palloc.c 2011-09-14 12:03:41.663126519 +0800 -@@ -8,24 +8,31 @@ +diff -urx '*~' -x '*.swp' nginx-1.0.15/src/core/ngx_palloc.c nginx-1.0.15-patched/src/core/ngx_palloc.c +--- nginx-1.0.15/src/core/ngx_palloc.c 2012-02-06 04:02:59.000000000 +0800 ++++ nginx-1.0.15-patched/src/core/ngx_palloc.c 2012-06-04 20:02:26.667925891 +0800 +@@ -9,32 +9,23 @@ #include -static void *ngx_palloc_block(ngx_pool_t *pool, size_t size); - static void *ngx_palloc_large(ngx_pool_t *pool, size_t size); - - +-static void *ngx_palloc_large(ngx_pool_t *pool, size_t size); +- +- ngx_pool_t * ngx_create_pool(size_t size, ngx_log_t *log) { - ngx_pool_t *p; -+ ngx_pool_t *p; -+ ngx_pool_data_t *d; ++ ngx_pool_t *p; - p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log); + size = sizeof(ngx_pool_t); @@ -150,126 +156,107 @@ diff -ur nginx-1.0.15/src/core/ngx_palloc.c nginx-1.0.15-patched/src/core/ngx_pa - p->d.end = (u_char *) p + size; - p->d.next = NULL; - p->d.failed = 0; -+ d = ngx_alloc(sizeof(ngx_pool_data_t), log); -+ -+ if (d == NULL) { -+ return NULL; -+ } -+ -+ d->next = d; -+ d->prev = d; -+ d->alloc = NULL; -+ p->d = d; ++ ngx_memzero(p, size); size = size - sizeof(ngx_pool_t); p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL; -@@ -43,7 +50,7 @@ + + p->current = p; +- p->chain = NULL; +- p->large = NULL; +- p->cleanup = NULL; + p->log = log; + + return p; +@@ -44,8 +35,7 @@ void ngx_destroy_pool(ngx_pool_t *pool) { - ngx_pool_t *p, *n; +- ngx_pool_large_t *l; + ngx_pool_data_t *d, *n; - ngx_pool_large_t *l; ngx_pool_cleanup_t *c; -@@ -55,7 +62,7 @@ + for (c = pool->cleanup; c; c = c->next) { +@@ -56,13 +46,9 @@ } } - for (l = pool->large; l; l = l->next) { -+ for (l = pool->large; l ; l = l->next) { +- +- ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc); +- +- if (l->alloc) { +- ngx_free(l->alloc); +- } ++ if (pool->d == NULL) { ++ ngx_free(pool); ++ return; + } - ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc); - -@@ -71,34 +78,45 @@ - * so we can not use this log while the free()ing the pool + #if (NGX_DEBUG) +@@ -72,9 +58,9 @@ + * so we cannot use this log while free()ing the pool */ - for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) { + for (d = pool->d, n = d->next; ; d = n, n = n->next) { ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0, - "free: %p, unused: %uz", p, p->d.end - p->d.last); -+ "free: %p", d); ++ "free: %p, unused: %d", d, 0); -- if (n == NULL) { -+ if (n == pool->d) { + if (n == NULL) { break; - } - } +@@ -83,172 +69,82 @@ #endif -+ if (pool->d->next == pool->d) { -+ ngx_free(pool->d); -+ } else { -+ for (d = pool->d, n = d->next; ; d = n, n = n->next) { -+ if (d->alloc) { -+ ngx_free(d->alloc); -+ } -+ ngx_free(d); - for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) { - ngx_free(p); -- -- if (n == NULL) { -- break; -+ if (n == pool->d) { -+ break; -+ } ++ for (d = pool->d, n = d->next; ; d = n, n = n->next) { ++ ngx_free(d->alloc); ++ ngx_free(d); + + if (n == NULL) { + break; } } -+ +-} + ++ pool->d = NULL; + +-void +-ngx_reset_pool(ngx_pool_t *pool) +-{ +- ngx_pool_t *p; +- ngx_pool_large_t *l; +- +- for (l = pool->large; l; l = l->next) { +- if (l->alloc) { +- ngx_free(l->alloc); +- } +- } +- +- pool->large = NULL; +- +- for (p = pool; p; p = p->d.next) { +- p->d.last = (u_char *) p + sizeof(ngx_pool_t); +- } + ngx_free(pool); } - void - ngx_reset_pool(ngx_pool_t *pool) - { -- ngx_pool_t *p; -- ngx_pool_large_t *l; -+ ngx_pool_data_t *p, *tmp; -+ ngx_pool_large_t *l; -+ -+ for (l = pool->large; l ; l = l->next) { -+ -+ ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc); - -- for (l = pool->large; l; l = l->next) { - if (l->alloc) { - ngx_free(l->alloc); - } -@@ -106,109 +124,65 @@ - - pool->large = NULL; - -- for (p = pool; p; p = p->d.next) { -- p->d.last = (u_char *) p + sizeof(ngx_pool_t); -+ p = pool->d->next; -+ while (p != pool->d) { -+ tmp = p; -+ ngx_free(p->alloc); -+ p->prev->next = p->next; -+ p->next->prev = p->prev; -+ p = p->next; -+ ngx_free(tmp); - } --} - -+ ngx_free(pool->d->alloc); -+ pool->d->alloc = NULL; -+ -+} - - void * +-void * -ngx_palloc(ngx_pool_t *pool, size_t size) -+ngx_malloc(ngx_pool_t *pool, size_t size) ++void ++ngx_reset_pool(ngx_pool_t *pool) { - u_char *m; - ngx_pool_t *p; - - if (size <= pool->max) { -+ ngx_pool_data_t *new; -+ void *m; ++ ngx_pool_data_t *d, *n; ++ ngx_pool_data_t *saved = NULL; - p = pool->current; - @@ -280,37 +267,29 @@ diff -ur nginx-1.0.15/src/core/ngx_palloc.c nginx-1.0.15-patched/src/core/ngx_pa - p->d.last = m + size; - - return m; -- } -- ++ if (pool->d) { ++ for (d = pool->d, n = d->next; ; d = n, n = n->next) { ++ if (d->alloc == pool->log) { ++ saved = d; ++ continue; + } + - p = p->d.next; - - } while (p); -+ m = ngx_alloc(size, pool->log); -+ if (m == NULL) { -+ return NULL; -+ } - -- return ngx_palloc_block(pool, size); -+ new = ngx_alloc(sizeof(ngx_pool_data_t), pool->log); -+ if (new == NULL){ -+ ngx_free(m); -+ return NULL; - } - -- return ngx_palloc_large(pool, size); -+ new->alloc = m; -+ new->next = pool->d; -+ new->prev = pool->d->prev; -+ pool->d->prev->next = new; -+ pool->d->prev = new; -+ return m; - } - - - void * +- return ngx_palloc_block(pool, size); +- } +- +- return ngx_palloc_large(pool, size); +-} +- ++ ngx_free(d->alloc); ++ ngx_free(d); + +-void * -ngx_pnalloc(ngx_pool_t *pool, size_t size) -+ngx_palloc(ngx_pool_t *pool, size_t size) - { +-{ - u_char *m; - ngx_pool_t *p; - @@ -325,37 +304,42 @@ diff -ur nginx-1.0.15/src/core/ngx_palloc.c nginx-1.0.15-patched/src/core/ngx_pa - p->d.last = m + size; - - return m; -- } -- ++ if (n == NULL) { ++ break; + } ++ } + - p = p->d.next; - - } while (p); - - return ngx_palloc_block(pool, size); -+ if (size <= 1024) { -+ return ngx_malloc(pool, size); ++ pool->d = saved; } - - return ngx_palloc_large(pool, size); +- +- return ngx_palloc_large(pool, size); } -static void * -ngx_palloc_block(ngx_pool_t *pool, size_t size) +void * -+ngx_pnalloc(ngx_pool_t *pool, size_t size) ++ngx_malloc(ngx_pool_t *pool, size_t size) { - u_char *m; - size_t psize; - ngx_pool_t *p, *new, *current; -- ++ ngx_pool_data_t *new; ++ void *m; + - psize = (size_t) (pool->d.end - (u_char *) pool); - - m = ngx_memalign(NGX_POOL_ALIGNMENT, psize, pool->log); -- if (m == NULL) { -- return NULL; -- } -- ++ m = ngx_alloc(size, pool->log); + if (m == NULL) { + return NULL; + } + - new = (ngx_pool_t *) m; - - new->d.end = m + psize; @@ -372,31 +356,37 @@ diff -ur nginx-1.0.15/src/core/ngx_palloc.c nginx-1.0.15-patched/src/core/ngx_pa - if (p->d.failed++ > 4) { - current = p->d.next; - } -+ if (size <= 1024) { -+ return ngx_malloc(pool, size); ++ new = ngx_alloc(sizeof(ngx_pool_data_t), pool->log); ++ if (new == NULL){ ++ ngx_free(m); ++ return NULL; } - p->d.next = new; - - pool->current = current ? current : new; - -- return m; -+ return ngx_palloc_large(pool, size); ++ new->alloc = m; ++ new->next = pool->d; ++ pool->d = new; + return m; } -@@ -216,7 +190,6 @@ - ngx_palloc_large(ngx_pool_t *pool, size_t size) +-static void * +-ngx_palloc_large(ngx_pool_t *pool, size_t size) ++void * ++ngx_palloc(ngx_pool_t *pool, size_t size) { - void *p; +- void *p; - ngx_uint_t n; - ngx_pool_large_t *large; - - p = ngx_alloc(size, pool->log); -@@ -224,20 +197,7 @@ - return NULL; - } - +- ngx_pool_large_t *large; +- +- p = ngx_alloc(size, pool->log); +- if (p == NULL) { +- return NULL; +- } +- - n = 0; - - for (large = pool->large; large; large = large->next) { @@ -411,11 +401,26 @@ diff -ur nginx-1.0.15/src/core/ngx_palloc.c nginx-1.0.15-patched/src/core/ngx_pa - } - - large = ngx_palloc(pool, sizeof(ngx_pool_large_t)); -+ large = ngx_malloc(pool, sizeof(ngx_pool_large_t)); - if (large == NULL) { - ngx_free(p); - return NULL; -@@ -262,7 +222,7 @@ +- if (large == NULL) { +- ngx_free(p); +- return NULL; +- } ++ return ngx_malloc(pool, size); ++} + +- large->alloc = p; +- large->next = pool->large; +- pool->large = large; + +- return p; ++void * ++ngx_pnalloc(ngx_pool_t *pool, size_t size) ++{ ++ return ngx_malloc(pool, size); + } + + +@@ -263,7 +159,7 @@ return NULL; } @@ -424,62 +429,55 @@ diff -ur nginx-1.0.15/src/core/ngx_palloc.c nginx-1.0.15-patched/src/core/ngx_pa if (large == NULL) { ngx_free(p); return NULL; -@@ -279,17 +239,41 @@ +@@ -278,16 +174,27 @@ + + ngx_int_t - ngx_pfree(ngx_pool_t *pool, void *p) +-ngx_pfree(ngx_pool_t *pool, void *p) ++ngx_pfree(ngx_pool_t *pool, void *data) { - ngx_pool_large_t *l; -+ ngx_pool_large_t *l; -+ ngx_pool_large_t *ll; -+ ngx_pool_data_t *d, *n; ++ ngx_pool_data_t *p, *d; - for (l = pool->large; l; l = l->next) { -+ for (l = pool->large, ll = l; l; ll = l, l = l->next) { - if (p == l->alloc) { - ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, - "free: %p", l->alloc); - ngx_free(l->alloc); - l->alloc = NULL; -+ if (l == pool->large) { -+ pool->large = NULL; -+ } +- if (p == l->alloc) { +- ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, +- "free: %p", l->alloc); +- ngx_free(l->alloc); +- l->alloc = NULL; ++ p = NULL; ++ for (d = pool->d; d; p = d, d = d->next) { ++ if (data == d->alloc) { + -+ ll->next = l->next; -+ p = l; -+ break; -+ } -+ } - -+ for (d = pool->d, n = d->next; ; d = n, n = d->next) { -+ if (p == d->alloc) { + ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", d->alloc); -+ if (d->alloc) { -+ ngx_free(d->alloc); -+ } ++ ++ ngx_free(d->alloc); + d->alloc = NULL; -+ d->prev->next = d->next; -+ d->next->prev = d->prev; ++ ++ if (p) { ++ p->next = d->next; ++ ++ } else { ++ pool->d = d->next; ++ } ++ + ngx_free(d); + return NGX_OK; } -+ if (d->next == pool->d) { -+ break; -+ } - } - - return NGX_DECLINED; -diff -ur nginx-1.0.15/src/core/ngx_palloc.h nginx-1.0.15-patched/src/core/ngx_palloc.h ---- nginx-1.0.15/src/core/ngx_palloc.h 2009-12-17 20:25:46.000000000 +0800 -+++ nginx-1.0.15-patched/src/core/ngx_palloc.h 2011-09-13 12:11:03.155622101 +0800 -@@ -38,6 +38,7 @@ +diff -urx '*~' -x '*.swp' nginx-1.0.15/src/core/ngx_palloc.h nginx-1.0.15-patched/src/core/ngx_palloc.h +--- nginx-1.0.15/src/core/ngx_palloc.h 2012-02-06 04:02:59.000000000 +0800 ++++ nginx-1.0.15-patched/src/core/ngx_palloc.h 2012-06-04 19:39:32.803578356 +0800 +@@ -39,6 +39,8 @@ typedef struct ngx_pool_large_s ngx_pool_large_t; +typedef struct ngx_pool_data_s ngx_pool_data_t; ++ struct ngx_pool_large_s { ngx_pool_large_t *next; -@@ -45,16 +46,15 @@ +@@ -46,16 +48,14 @@ }; @@ -489,10 +487,9 @@ diff -ur nginx-1.0.15/src/core/ngx_palloc.h nginx-1.0.15-patched/src/core/ngx_pa - ngx_pool_t *next; - ngx_uint_t failed; -} ngx_pool_data_t; -+struct ngx_pool_data_s{ -+ ngx_pool_data_t *next; -+ ngx_pool_data_t *prev; -+ void *alloc; ++struct ngx_pool_data_s { ++ ngx_pool_data_t *next; ++ void *alloc; +};