一、报错lcov和gcov的使用错误
编译使用的gcc版本和gcov的版本对不上的话,使用lcov和gcov的时候会报错
lcov的错误:
[xx@localhost XXX]$ lcov --capture --directory cov --output-file xxx.info --test-name xxx
Capturing coverage data from cov
Found gcov version: 4.8.5
Scanning cov for .gcda files ...
Found 35 data files in cov
Processing XXX.gcda
geninfo: ERROR: XXX.gcno: reached unexpected end of file
gcov的错误:
[xxx@localhost xxx]$ gcov -o cov ./xxx.c
cov/xxx.gcno:版本‘405 ’,首选‘408R’
gcov: out of memory allocating 16030351984 bytes after a total of 135168 bytes
确保gcc和gcov版本一样即可
按照上面说的方法实践,果然搞定
查看了一下:
gcc -v : 4.4.7
g++ -v : 4.4.7
gcov -v :4.4.7
lcov -v :1.10
然后将lcov 版本升级到 1.12,问题搞定
通用代码的覆盖率问题
1、问题描述
公共代码在项目A中被覆盖 30,在项目 B 中覆盖另外 70,怎样才能统计出 100% 的覆盖效果?
2、实验代码
[zhoujinhua@ecs-b0b7 tmp]$ cat common.c
#include <stdio.h>
int myAdd(int a, int b)
{
return a+b;
}
int mySub(int a, int b)
{
return a - b;
}
[zhoujinhua@ecs-b0b7 tmp]$ cat good.c
#include <stdio.h>
#include <execinfo.h>
#include <stdlib.h>
extern int myAdd(int a, int b);
void print_call_stack()
{
int i = 0;
int size =32;
void *array[32];
int stack_num = backtrace(array, size);
char **stacktrace = (char**)backtrace_symbols(array, stack_num);
for (i=0; i<stack_num; i++)
{
printf("func_%d addr:%s\n", i, stacktrace[i]);
}
free(stacktrace);
return;
}
void func_1(){print_call_stack();}
void func_2(){func_1();}
void func_3(){func_2();}
void func_4(){func_3();}
void func_5(){func_4();}
void func_6(){func_5();}
int main(int argc, char **argv)
{
myAdd(3,4);
printf("argc = %d\n", argc);
if (argc < 2)
{
printf("please use at least one parameter!\n");
return 1;
}
func_6();
return 0;
}
[zhoujinhua@ecs-b0b7 tmp]$ cat better.c
#include <stdio.h>
extern int mySub(int a,int b);
int main()
{
return mySub(9, 2);
}
[zhoujinhua@ecs-b0b7 tmp]$
3、实验操作步骤
1、编译第一个项目
gcc -g3 -fprofile-arcs -ftest-coverage good.c common.c -o dir1/good
2、运行第一个项目,产生覆盖率数据
./dir1/good
3、将中间文件放入第一个目录
mv *.gcda ./dir1/
mv *.gcna ./dir1/
mv *.gcov ./dir1/
4、编译第二个项目,同样的操作步骤
gcc -g3 -fprofile-arcs -ftest-coverage better.c common.c -o dir2/better
5、当前目录下的所有覆盖文件进行统计
lcov -d ./ -c -o ./prj_dir/my_prj.info -t 'prj_title' -b ./
说明:-d ./ 表示当前目录下的所有
6、最终生成漂亮的覆盖率网页
genhtml -o prj_dir/ prj_dir/my_prj.info
7、网页查看,不用浏览器,直接在 linux 命令行就能查看,TAB切换、跳转
yum -y install w3m w3m-image
w3m ./prj_dir/index.html
在某些大型项目中,无法随意修改编译、链接参数,怎样实现stacktrace
当编译、链接参数无法正确✔️配置时,尽管如下函数可以运行,但是结果缺不是预想那样
void print_call_stack()
{
int i = 0;
int size =32;
void *array[32];
int stack_num = backtrace(array, size);
char **stacktrace = (char**)backtrace_symbols(array, stack_num);
for (i=0; i<stack_num; i++)
{
printf("func_%d addr:%s\n", i, stacktrace[i]);
}
free(stacktrace);
return;
}
stacktrace[i] 并没有被转换成函数名,仍然是栈中十六进制数的样子。
此时只能自己实现转换。
通过观察发现,array[1],就是上一层函数中的某个地址,一般是函数名离开偏移地址。
如果上层函数是func,责array[1]的值是 func + offset.
可以通过简单的条件判断:
if ((array[1]>func) && ((array[1]-func)<1024)) //限定偏移范围,可以调整
{
return true;
}
但是实际编译是,编译器会报错,提示void*类型不能和函数类型进行减法操作。
需要做一次转换,将两个值都转化为word32:
typedef word32 unsinged int
typedef void (*entryFuncType)()
typedef struct
{
eFuncIdx idx;
entryFuncType func;
}funcMapType;
funcMapType map[]=
{
{eIdx_1, func_1},
{eIdx_2, func_2},
};
BOOL isInFunction(void *stackPos, entryFuncType func)
{
bool ret = false;
int offset=0;
char buf_1[32] = {0};
char buf_2[32] = {0};
word32 stackPosVal=0;
word32 funcVal=0;
sprintf(buf_1, "0x%x",stackPos);
sprintf(buf_2, "0x%x",func);
sscanf(buf_1, "%x", &stackPosVal);
sscanf(buf_2, "%x", &funcVal);
offset=stackPosVal - funcVal;
if ((0<offset) && (offset<1024))
{
ret = true;
}
return ret;
}
void print_call_stack()
{
int i = 0;
int size =32;
void *array[32];
int stack_num = backtrace(array, size);
char **stacktrace = (char**)backtrace_symbols(array, stack_num);
//这个简单的判断,可以替换成一个循环
if(isInFunction(array[1], myFunction))
{
//do something....
}
free(stacktrace);
return;
}
《“gcov_lcov”》 有 1 条评论
The following time I learn a blog, I hope that it doesnt disappoint me as a lot as this one. I imply, I know it was my choice to learn, however I really thought youd have something attention-grabbing to say. All I hear is a bunch of whining about something that you may fix if you happen to werent too busy in search of attention. Billie Hoffstatter