简体   繁体   English

如何为模板函数调用解释gcov结果

[英]How to interpret gcov results for a template-function call

Question 1: How do I decipher the function names, like _ZN21CircularBufferManager4readIlEEmPT_m ? 问题1:如何解密函数名称,例如_ZN21CircularBufferManager4readIlEEmPT_m? I'm guessing the second character after "read" in those long function names (ie l, t, h, d) must have something to do with type. 我猜在那些长函数名(即l,t,h,d)中,“读取”之后的第二个字符必须与类型有关。 I use unsigned char, unsigned short, signed long, double. 我使用unsigned char,unsigned short,signed long,double。

Question 2: In line #227, I see 16 branches. 问题2:在第227行中,我看到16个分支。 Why 16? 为什么是16? On the other hand, line #222 has 8 branches, which makes sense to me because 2 states (true or false) times 4 functions makes 8 branches. 另一方面,第222行有8个分支,这对我来说很有意义,因为2个状态(正确或错误)乘以4个函数将得出8个分支。

        -:  216:    template<typename Type>
function _ZN21CircularBufferManager4readIlEEmPT_m called 2 returned 100% blocks executed 63%
function _ZN21CircularBufferManager4readItEEmPT_m called 2 returned 100% blocks executed 50%
function _ZN21CircularBufferManager4readIhEEmPT_m called 10 returned 100% blocks executed 94%
function _ZN21CircularBufferManager4readIdEEmPT_m called 8 returned 100% blocks executed 94%
       22:  217:    uint32 read(Type* data, uint32 element_count)
        -:  218:    {
       22:  219:        uint32 size(sizeof(Type)*element_count);
        -:  220:
       22:  221:        uint32 write_pos_alias(this->write_pos);
       22:  222:        if (this->read_pos > this->write_pos) {
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
branch  2 taken 0% (fallthrough)
branch  3 taken 100%
branch  4 taken 20% (fallthrough)
branch  5 taken 80%
branch  6 taken 13% (fallthrough)
branch  7 taken 88%
        3:  223:            write_pos_alias += this->allocated_size;
        -:  224:        }
        -:  225:        assert(write_pos_alias >= this->read_pos);
       22:  226:        uint32 n(write_pos_alias - this->read_pos); // number of bytes to reach the write position
       22:  227:        if (n==0 && this->stored_count==0) // <=> buffer is empty
branch  0 taken 50% (fallthrough)
branch  1 taken 50%
branch  2 taken 100% (fallthrough)
branch  3 taken 0%
branch  4 taken 0% (fallthrough)
branch  5 taken 100%
branch  6 never executed
branch  7 never executed
branch  8 taken 30% (fallthrough)
branch  9 taken 70%
branch 10 taken 0% (fallthrough)
branch 11 taken 100%
branch 12 taken 38% (fallthrough)
branch 13 taken 63%
branch 14 taken 0% (fallthrough)
branch 15 taken 100%
        -:  228:        {
        -:  229:            // no data read
        1:  230:            return 0;
        -:  231:        }
       21:  232:        else if (0<n && n<size) // read is stopped before read_pos crosses over write_pos.
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
branch  2 taken 0% (fallthrough)
branch  3 taken 100%
branch  4 taken 100% (fallthrough)
branch  5 taken 0%
branch  6 taken 0% (fallthrough)
branch  7 taken 100%
branch  8 taken 70% (fallthrough)
branch  9 taken 30%
branch 10 taken 14% (fallthrough)
branch 11 taken 86%
branch 12 taken 63% (fallthrough)
branch 13 taken 38%
branch 14 taken 20% (fallthrough)
branch 15 taken 80%
        -:  233:        {
        2:  234:            return read(reinterpret_cast<uint8*>(data), n); //less data than required.
call    0 never executed
call    1 never executed
call    2 returned 100%
call    3 returned 100%
        -:  235:        }
        -:  236:        // It is guaranteed here and below that read_pos never crosses-over write_pos.
        -:  237:
       19:  238:        if (this->read_pos + size > this->allocated_size) // going beyond the end of buffer
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
branch  2 taken 0% (fallthrough)
branch  3 taken 100%
branch  4 taken 11% (fallthrough)
branch  5 taken 89%
branch  6 taken 43% (fallthrough)
branch  7 taken 57%
        -:  239:        {
        4:  240:            uint32 n(this->allocated_size - this->read_pos); // number of bytes to reach the end of buffer
        -:  241:            return this->read(reinterpret_cast<uint8*>(data), n)
        4:  242:                 + this->read(reinterpret_cast<uint8*>(data)+n, size-n);
call    0 never executed
call    1 never executed
call    2 never executed
call    3 never executed
call    4 returned 100%
call    5 returned 100%
call    6 returned 100%
call    7 returned 100%
        -:  243:        }
       15:  244:        memcpy(reinterpret_cast<void*>(data), reinterpret_cast<void*>(this->buf+this->read_pos), size);
       15:  245:        incrementReadPos(size);
call    0 returned 100%
call    1 returned 100%
call    2 returned 100%
call    3 returned 100%
       15:  246:        return size;
        -:  247:    }

For your first question, you can pipe this output through the c++filt command to demangle the identifiers. 对于第一个问题,您可以通过c++filt命令将此输出通过管道传递,以使标识符脱散。

For your second question, apparently gcov doesn't care if the false gets short circuited, it still counts three ways to get to false, and only one way to get to true. 对于您的第二个问题,显然gcov不在乎错误是否被短路,它仍然通过三种方式来实现错误,而只有一种方式可以实现。

  • true => n==0 && this->stored_count==0 true => n==0 && this->stored_count==0
  • false => n!=0 && this->stored_count==0 false => n!=0 && this->stored_count==0
  • false => n!=0 && this->stored_count!=0 false => n!=0 && this->stored_count!=0
  • false => n==0 && this->stored_count!=0 false => n==0 && this->stored_count!=0

Since you expand your template function 4 ways, that makes sixteen. 由于您以4种方式扩展了模板功能,因此共有16种。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM