List:Commits« Previous MessageNext Message »
From:V Narayanan Date:June 25 2009 7:01am
Subject:Re: bzr commit into mysql-pe branch (v.narayanan:3391) Bug#43572
View as plain text  
Hi Ingo,

Thank you for following up on this bug and giving your comments on the
test case attached! Please see some comments below.

Ingo Strüwing wrote:
> Hi VN,
>
> thank you for implementing error injection to test your bug fix. Please
> find below some thoughts for improvement.
>
> V Narayanan, 24.06.2009 10:57:
>
> ...
>   
>>  3391 V Narayanan	2009-06-24
>>       Bug#43572 Handle failures from hash_init
>>       
>>       The bug needs to be tested with error injection. This
>>       patch adds error injection tests, for, testing failure
>>       of hash_init, caused by memory allocation failure in
>>       the dynamic array used in the hash.
>>      @ mysql-test/r/hash_error_injection.result
>>         Bug#43572 Handle failures from hash_init
>>         
>>         Result file for error injection testing in hash_init
>>      @ mysql-test/t/hash_error_injection.test
>>         Bug#43572 Handle failures from hash_init
>>         
>>         sets the debug flag to simulate a dynamic array allocation
>>         failure while initializing the hash. After setting the flag
>>         create hash indexes on memory tables and test the queries to
>>         ensure that, failure in the dynamic array allocation in hash_init
>>         does not causes these queries, that exercise the hash_init 
>>         function to fail.
>>      @ mysys/hash.c
>>         Bug#43572 Handle failures from hash_init
>>         
>>         Contains the changes needed to add error injection
>>         in the hash_init function. Test a debug flag to determine
>>         if the dynamic array needs to be reset, thus, simulating
>>         an memory allocation failure.
>>
>>     
> ...
>   
>> === added file 'mysql-test/r/hash_error_injection.result'
>>     
> ...
>   
>> +#
>> +# Reset the debug flag to stop error injection
>> +#
>> +#
>> +# Perform error injection
>> +#
>>     
>
>
> (I wonder about this comment. You stopped error injection above and
> claim to perform it here?)
>   

Sorry, Mea Culpa!, Should have been "Perform Cleanup". Will correct it!

> I am puzzled that I don't see any result of the error injection in the
> result file. I understand that your original patch had the goal to
> circumvent a problem in allocation during hash_init. So it is fine that
> all statements succeed. But since there isn't even a warning, how can
> you be sure that the error injection has an effect at all?
>   

Ingo, I verified that the error injection does indeed happen by single 
stepping.
I single stepped to ensure that the control does indeed reach the error 
injection
code.

Everything is supposed to work fine even if hash_init fails. The dynamic 
array
will be initialized at a later stage during my_hash_insert. Hence not 
seeing even
a warning is expected, it just shows that hash_init failure does not 
affect normal
operation at all.

> If you follow my suggestion below, you would force my_malloc() to report
> an error. This should show up as a warning and not make the statements
> fail. I must admit that I'm not sure what will happen. It is possible
> that the error, reported by my_malloc() will make some statements fail
> with EE_OUTOFMEMORY or alike. But then it's something that might need to
> be solved. We could discuss that if it happens. The other possibility is
> that we see just warnings. And that is the way it should be, I think.
> The third possibility would be that we still don't see anything. But
> then I'd like to see, where the malloc error is suppressed. In this case
> we need to discuss again.
>
> Anyway, if the effect of error injection does not show up in the result
> file, we don't need to run the test in the test suite. It would do to
> run it manually once in a debugger and verify that it works as expected.
>
> However, I hope we can make warnings come up by the change I suggest below.
>
> ...
>   

Ingo, *After this fix* causing a memory allocation failure in malloc 
will not
cause hash_init to fail, instead it will cause my_hash_insert to fail.

Pls see that I have raised Bug#45613 as for this.

The errors that arise will not be due to hash_init but instead due to 
my_hash_insert,
so we would in effect be writing a test case for a existing bug that has 
not been fixed.

>> === added file 'mysql-test/t/hash_error_injection.test'
>>     
> ...
>   
>> +--echo #
>> +--echo # Reset the debug flag to stop error injection
>> +--echo #
>> +--disable_query_log
>> +eval SET debug= '$debug';
>> +--enable_query_log
>> +
>> +--echo #
>> +--echo # Perform error injection
>> +--echo #
>> +DROP INDEX c1_index ON t1;
>> +DROP INDEX c2_index ON t1;
>> +DROP INDEX c4_index ON t1;
>> +
>> +DROP TABLE t1;
>> +DROP TABLE t2;
>>     
>
>
> Here is, what I meant above. After resetting "debug", why would we
> "perform error injection" here?
>   

Mea Culpa! Sorry! Will fix it!

>   
>> === modified file 'mysys/hash.c'
>> --- a/mysys/hash.c	2009-06-22 12:38:37 +0000
>> +++ b/mysys/hash.c	2009-06-24 08:57:25 +0000
>> @@ -77,9 +77,16 @@ _my_hash_init(HASH *hash, uint growth_si
>>                my_hash_get_key get_key,
>>                void (*free_element)(void*), uint flags CALLER_INFO_PROTO)
>>  {
>> +  /* Set to TRUE if error injection is enabled */
>> +  my_bool hash_init_error_injection= FALSE;
>> +
>>    DBUG_ENTER("my_hash_init");
>>    DBUG_PRINT("enter",("hash: %p  size: %u", hash, (uint) size));
>>  
>> +  /* Error injection for coverage testing. */
>> +  DBUG_EXECUTE_IF("hash_init_allocation_failure_err_inj",
>> +                  hash_init_error_injection= TRUE;);
>> +
>>    hash->records=0;
>>    hash->key_offset=key_offset;
>>    hash->key_length=key_length;
>> @@ -88,6 +95,19 @@ _my_hash_init(HASH *hash, uint growth_si
>>    hash->free=free_element;
>>    hash->flags=flags;
>>    hash->charset=charset;
>> +
>> +  /* 
>> +    If error injection is enabled simulate failure to allocate 
>> +    the dynamic array
>> +  */
>> +  if (hash_init_error_injection)
>> +  {
>> +    my_init_dynamic_array_ci(&hash->array,
>> +                             sizeof(HASH_LINK), size, growth_size);
>> +    hash->array.buffer= 0;
>> +    hash->array.max_element= 0;
>> +    DBUG_RETURN(FALSE);
>> +  }
>>    DBUG_RETURN(my_init_dynamic_array_ci(&hash->array, 
>>                                         sizeof(HASH_LINK), size, growth_size));
>>     
>
>
> IMHO it is not acceptable to insert this error injection code
> unconditionally. It would be present in a production server too.
>
> One way to avoid this would be to include it in "#ifndef DBUG_OFF ...
> #endif", or in IF_DBUG(...).
>   

Agree! Will do!

> OTOH, you could use the malloc error injection
> "my_malloc_error_inject=1". That would produce an allocation error
> inside of my_init_dynamic_array_ci(). And it would avoid to have an
> extra branch here. I suggest the following:
>
> DBUG_EXECUTE_IF("hash_init_allocation_failure_err_inj",
> my_malloc_error_inject=1);
>
> If you replace your similar statement with this, the extra branch isn't
> required at all (neither the hash_init_error_injection variable). The
> allocation will fail inside my_init_dynamic_array_ci() and you should
> get the same result.
>   

The extra branch is required if you want to test hash_init failures alone.
One we fix the bug in my_hash_insert we can add error injection for a
malloc failure and ensure that failures during memory allocation for the
dynamic array do not affect any operation on the hash.

The error injection case is useful for testing that *failures in 
hash_init* do not
cause critical failures in the server operation (e.g. crashes). But this 
testing
is limited to hash_init alone. Adding a case for malloc as you suggest above
is a generalization for testing every place where malloc is used in an 
hash operation.
This case has not been handled yet and will be handled when Bug#45613 is 
fixed.
> Regards
> Ingo
>   

Thanks once again for the comments,
Narayanan
Thread
bzr commit into mysql-pe branch (v.narayanan:3391) Bug#43572V Narayanan24 Jun
  • Re: bzr commit into mysql-pe branch (v.narayanan:3391) Bug#43572Ingo Strüwing24 Jun
    • Re: bzr commit into mysql-pe branch (v.narayanan:3391) Bug#43572V Narayanan25 Jun
      • Re: bzr commit into mysql-pe branch (v.narayanan:3391) Bug#43572Ingo Strüwing25 Jun
        • Re: bzr commit into mysql-pe branch (v.narayanan:3391) Bug#43572V Narayanan25 Jun