From: Marc Alff Date: May 13 2011 4:04pm Subject: bzr commit into mysql-5.5 branch (marc.alff:3383) Bug#12552516 List-Archive: http://lists.mysql.com/commits/137345 X-Bug: 12552516 Message-Id: <201105131605.p4DG5HMX021217@acsmt357.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============9090941597213910526==" --===============9090941597213910526== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///Users/malff/BZR_TREE/mysql-5.5-bug12552516/ based on revid:bjorn.munch@stripped 3383 Marc Alff 2011-05-13 Bug#12552516 LF_HASH REQUIRES MY_THREAD_INIT() Before this fix, a thread instrumented for the performance schema, that would perform file io operations, could crash inside the LF_HASH implementation, in cases when my_thread_init is not called. The crash itself has not been reported in 5.5 but similar crashes have been found in 5.6-based development branches, using LF_HASH for more instrumentation. The possibility of a crash in 5.5 is confirmed by code analysis. The problem is that, when my_thread_init() is not called, which can happen for threads in storage engines or thirs party code, my_thread_var is NULL. Using my_thread_var->stacks_ends_here in mysys/lf_alloc-pin.c is unsafe. Given that my_thread_var is used: - only for stacks_ends_here - only on platform with HAVE_ALLOCA - only when there is enough room on the stack and given that the LF_HASH implementation has a fallback algorythm implemented already when using alloca is not possible, using my_thread_var->stacks_ends_here is in fact not a strict requirement, and can be relaxed. The fix is to: - test explicitly if my_thread_var is NULL, to account for cases when my_thread_init() is not used by the calling thread. - not use alloca in this case, and rely on the fall back code already in place. so that the LF_HASH can be supported even without my_thread_init(). The implementation of mysys/lf_alloc-pin.c has been fixed to support this new usage. The units tests in unittest/mysys/lf-t.c have been adjusted accordingly. modified: mysys/lf_alloc-pin.c unittest/mysys/lf-t.c === modified file 'mysys/lf_alloc-pin.c' --- a/mysys/lf_alloc-pin.c 2010-07-23 20:13:36 +0000 +++ b/mysys/lf_alloc-pin.c 2011-05-13 16:04:49 +0000 @@ -146,6 +146,7 @@ void lf_pinbox_destroy(LF_PINBOX *pinbox */ LF_PINS *_lf_pinbox_get_pins(LF_PINBOX *pinbox) { + struct st_my_thread_var *var; uint32 pins, next, top_ver; LF_PINS *el; /* @@ -188,7 +189,12 @@ LF_PINS *_lf_pinbox_get_pins(LF_PINBOX * el->link= pins; el->purgatory_count= 0; el->pinbox= pinbox; - el->stack_ends_here= & my_thread_var->stack_ends_here; + var= my_thread_var; + /* + Threads that do not call my_thread_init() should still be + able to use the LF_HASH. + */ + el->stack_ends_here= (var ? & var->stack_ends_here : NULL); return el; } @@ -327,34 +333,37 @@ static int match_pins(LF_PINS *el, void */ static void _lf_pinbox_real_free(LF_PINS *pins) { - int npins, alloca_size; - void *list, **addr; + int npins; + void *list; + void **addr= NULL; void *first= NULL, *last= NULL; LF_PINBOX *pinbox= pins->pinbox; npins= pinbox->pins_in_array+1; #ifdef HAVE_ALLOCA - alloca_size= sizeof(void *)*LF_PINBOX_PINS*npins; - /* create a sorted list of pinned addresses, to speed up searches */ - if (available_stack_size(&pinbox, *pins->stack_ends_here) > alloca_size) + if (pins->stack_ends_here != NULL) { - struct st_harvester hv; - addr= (void **) alloca(alloca_size); - hv.granary= addr; - hv.npins= npins; - /* scan the dynarray and accumulate all pinned addresses */ - _lf_dynarray_iterate(&pinbox->pinarray, - (lf_dynarray_func)harvest_pins, &hv); - - npins= hv.granary-addr; - /* and sort them */ - if (npins) - qsort(addr, npins, sizeof(void *), (qsort_cmp)ptr_cmp); + int alloca_size; + alloca_size= sizeof(void *)*LF_PINBOX_PINS*npins; + /* create a sorted list of pinned addresses, to speed up searches */ + if (available_stack_size(&pinbox, *pins->stack_ends_here) > alloca_size) + { + struct st_harvester hv; + addr= (void **) alloca(alloca_size); + hv.granary= addr; + hv.npins= npins; + /* scan the dynarray and accumulate all pinned addresses */ + _lf_dynarray_iterate(&pinbox->pinarray, + (lf_dynarray_func)harvest_pins, &hv); + + npins= hv.granary-addr; + /* and sort them */ + if (npins) + qsort(addr, npins, sizeof(void *), (qsort_cmp)ptr_cmp); + } } - else #endif - addr= 0; list= pins->purgatory; pins->purgatory= 0; === modified file 'unittest/mysys/lf-t.c' --- a/unittest/mysys/lf-t.c 2009-11-18 02:31:40 +0000 +++ b/unittest/mysys/lf-t.c 2011-05-13 16:04:49 +0000 @@ -27,6 +27,8 @@ int32 inserts= 0, N; LF_ALLOCATOR lf_allocator; LF_HASH lf_hash; +int with_my_thread_init=0; + /* pin allocator - alloc and release an element in a loop */ @@ -36,7 +38,8 @@ pthread_handler_t test_lf_pinbox(void *a int32 x= 0; LF_PINS *pins; - my_thread_init(); + if (with_my_thread_init) + my_thread_init(); pins= lf_pinbox_get_pins(&lf_allocator.pinbox); @@ -49,7 +52,10 @@ pthread_handler_t test_lf_pinbox(void *a pthread_mutex_lock(&mutex); if (!--running_threads) pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); - my_thread_end(); + + if (with_my_thread_init) + my_thread_end(); + return 0; } @@ -68,7 +74,8 @@ pthread_handler_t test_lf_alloc(void *ar int32 x,y= 0; LF_PINS *pins; - my_thread_init(); + if (with_my_thread_init) + my_thread_init(); pins= lf_alloc_get_pins(&lf_allocator); @@ -101,7 +108,9 @@ pthread_handler_t test_lf_alloc(void *ar } if (!--running_threads) pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); - my_thread_end(); + + if (with_my_thread_init) + my_thread_end(); return 0; } @@ -112,7 +121,8 @@ pthread_handler_t test_lf_hash(void *arg int32 x,y,z,sum= 0, ins= 0; LF_PINS *pins; - my_thread_init(); + if (with_my_thread_init) + my_thread_init(); pins= lf_hash_get_pins(&lf_hash); @@ -152,14 +162,15 @@ pthread_handler_t test_lf_hash(void *arg } if (!--running_threads) pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); - my_thread_end(); + if (with_my_thread_init) + my_thread_end(); return 0; } void do_tests() { - plan(4); + plan(7); lf_alloc_init(&lf_allocator, sizeof(TLA), offsetof(TLA, not_used)); lf_hash_init(&lf_hash, sizeof(int), LF_HASH_UNIQUE, 0, sizeof(int), 0, @@ -168,9 +179,15 @@ void do_tests() bad= my_atomic_initialize(); ok(!bad, "my_atomic_initialize() returned %d", bad); - test_concurrently("lf_pinbox", test_lf_pinbox, N= THREADS, CYCLES); - test_concurrently("lf_alloc", test_lf_alloc, N= THREADS, CYCLES); - test_concurrently("lf_hash", test_lf_hash, N= THREADS, CYCLES/10); + with_my_thread_init= 1; + test_concurrently("lf_pinbox (with my_thread_init)", test_lf_pinbox, N= THREADS, CYCLES); + test_concurrently("lf_alloc (with my_thread_init)", test_lf_alloc, N= THREADS, CYCLES); + test_concurrently("lf_hash (with my_thread_init)", test_lf_hash, N= THREADS, CYCLES/10); + + with_my_thread_init= 0; + test_concurrently("lf_pinbox (without my_thread_init)", test_lf_pinbox, N= THREADS, CYCLES); + test_concurrently("lf_alloc (without my_thread_init)", test_lf_alloc, N= THREADS, CYCLES); + test_concurrently("lf_hash (without my_thread_init)", test_lf_hash, N= THREADS, CYCLES/10); lf_hash_destroy(&lf_hash); lf_alloc_destroy(&lf_allocator); --===============9090941597213910526== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/marc.alff@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: marc.alff@stripped # target_branch: file:///Users/malff/BZR_TREE/mysql-5.5-bug12552516/ # testament_sha1: a0ebca8c135b65a69ec72d73293d371a4db639f6 # timestamp: 2011-05-13 18:04:54 +0200 # base_revision_id: bjorn.munch@stripped\ # yrg2lnt4tqrqyfyd # # Begin bundle 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 /i7kinChIZw7C4o= --===============9090941597213910526==--