Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gcov reports branches for plain function calls

I'm using gcov to get code coverage for our project, but it frequently reports 50% conditional coverage for plain function calls. It doesn't make any difference if the function takes any parameters or returns any data or not. I'm using gcovr and Cobertura with Jenkins, but a simple gcov file gives the same result. The actual tested code is attached below together with the stubbed functions, all in gcov format. Any ideas why gcov threats these function calls as branches?

        -:  146:/*****************************************************************************/
function _Z12mw_log_clearv called 2 returned 100% blocks executed 100%
        2:  147:void mw_log_clear( void )
        2:  147-block  0
        -:  148:{
        2:  149:    uint8_t i = 0;
        2:  150:    uint8_t clear_tuple[EE_PAGE_SIZE] = { 0xff };
        -:  151:    
       66:  152:    for (i = 0; i < (int16_t)EE_PAGE_SIZE; i++)
        2:  152-block  0
       64:  152-block  1
       66:  152-block  2
branch  0 taken 97%
branch  1 taken 3% (fallthrough)
        -:  153:    {
       64:  154:        clear_tuple[i] = 0xff;
        -:  155:    }
        -:  156:    
        -:  157:    /* Write pending data */
        2:  158:    mw_eeprom_write_blocking();
        2:  158-block  0
call    0 returned 100%
branch  1 taken 100% (fallthrough)    <---- This is a plain function call, not a branch
branch  2 taken 0% (throw)            <---- This is a plain function call, not a branch
        -:  159:    
       26:  160:    for (i = 0; i < (RESERVED_PAGES_PER_PAREMETER_SET - POPULATED_PAGES_PER_PAREMETER_SET); i++)
        2:  160-block  0
       24:  160-block  1
       26:  160-block  2
branch  0 taken 96%
branch  1 taken 4% (fallthrough)
        -:  161:    {
       25:  162:        if (status_ok != mw_eeprom_write(LOG_TUPLE_START_ADDRESS + i * EE_PAGE_SIZE, clear_tuple, sizeof(clear_tuple)))
       25:  162-block  0
call    0 returned 100%
branch  1 taken 100% (fallthrough)    <---- This is a plain function call, not a branch
branch  2 taken 0% (throw)            <---- This is a plain function call, not a branch
       25:  162-block  1
branch  3 taken 4% (fallthrough)
branch  4 taken 96%
        -:  163:        {
        1:  164:            mw_error_handler_add(mw_error_eeprom_busy);
        1:  164-block  0
call    0 returned 100%
branch  1 taken 100% (fallthrough)    <---- This is a plain function call, not a branch
branch  2 taken 0% (throw)            <---- This is a plain function call, not a branch
        1:  165:            break;
        1:  165-block  0
        -:  166:        }
        -:  167:        
       24:  168:        mw_eeprom_write_blocking();
       24:  168-block  0
call    0 returned 100%
branch  1 taken 100% (fallthrough)   <---- This is a plain function call, not a branch
branch  2 taken 0% (throw)           <---- This is a plain function call, not a branch
        -:  169:    }
        2:  170:}
        2:  170-block  0
        -:  171:
        -:  172:/*****************************************************************************/

/*****************************************************************************/

void mw_eeprom_write_blocking(void)
{
    stub_data.eeprom_write_blocking_calls++;
}

/*****************************************************************************/

void mw_error_handler_add(mw_error_code_t error_code)
{
    EXPECT_EQ(error_code, stub_data.expected_error_code);
    stub_data.registered_error_code = error_code;
}

/*****************************************************************************/

status_t mw_eeprom_write(
        const uint32_t eeprom_start_index,
        void *const source_start_address,
        const uint32_t length)
{
    stub_data.eeprom_write_start_index = eeprom_start_index;
    stub_data.eeprom_write_length = length;
    stub_data.eeprom_write_called = true;

    EXPECT_NE(NULL, (uint32_t)source_start_address);
    EXPECT_NE(0, length);
    EXPECT_LE(eeprom_start_index + length, EEPROM_SIZE);

    if (status_ok == stub_data.eeprom_write_status)
        memcpy(&stub_data.eeprom[eeprom_start_index], source_start_address, length);

    return stub_data.eeprom_write_status;
}
like image 542
MrDanne Avatar asked Sep 29 '22 10:09

MrDanne


1 Answers

Solved!

Found the answer in this thread: Why gcc 4.1 + gcov reports 100% branch coverage and newer (4.4, 4.6, 4.8) reports 50% for "p = new class;" line?

Seems like gcov reacted on some "invisible" exception handling code for these function calls, so adding "-fno-exceptions" to g++ made all these missing branches to disappear.

like image 93
MrDanne Avatar answered Oct 23 '22 12:10

MrDanne