Gcov 报告普通函数调用的分支

Gcov reports branches for plain function calls

我正在使用 gcov 来获取我们项目的代码覆盖率,但它经常报告普通函数调用的条件覆盖率为 50%。函数是否接受任何参数或 returns 任何数据都没有任何区别。我将 gcovr 和 Cobertura 与 Jenkins 一起使用,但一个简单的 gcov 文件给出了相同的结果。 实际测试的代码连同存根函数一起附在下面,全部采用 gcov 格式。 知道为什么 gcov 会威胁这些函数调用作为分支吗?

        -:  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;
}

已解决!

在此线程中找到答案: Why gcc 4.1 + gcov reports 100% branch coverage and newer (4.4, 4.6, 4.8) reports 50% for "p = new class;" line?

似乎 gcov 对这些函数调用的某些 "invisible" 异常处理代码做出了反应,因此向 g++ 添加“-fno-exceptions”使所有这些缺失的分支都消失了。