我正在尝试获取Android上所有C ++代码的代码覆盖率报告,并使用CLANG编译工具链。据我所知,它实际上是在编译器标志中添加--coverage -fprofile-arcs -ftest-coverage
并使用libprofile_rt
静态链接。然后在所有链接到主服务应用程序的库的所有退出路径中添加 __gcov_flush()
。
这就是我要改进的地方。我想避免修改所有库。有没有一种方法可以确定性地调用所有链接库的__gcov_flush()
(例如,在收到信号时),以便能够转储配置文件数据?进行
arm-linux-androideabi-gcc-nm -D $OUT/vendor/lib/liba.so |grep -i gcov
我明白了
00011bf8 T __gcov_flush
00011c40 T llvm_gcov_init
我认为这意味着上述符号在库的文本部分中。
我尝试了以下代码
#include <dlfcn.h>
#include <signal.h>
#include <link.h>
static int walk_callback(struct dl_phdr_info *info, size_t size, void *data)
{
void (*func)();
if (strlen(info->dlpi_name) == 0) return 0;
ALOGE("lib is %s\n", info->dlpi_name);
void *handle = dlopen(info->dlpi_name, RTLD_NOW | RTLD_GLOBAL);
if(handle) {
*(void **)(&func) = dlsym(handle, "__gcov_flush");
if (func) {
ALOGE("Calling GCOV_FLUSH of %s\n",
info->dlpi_name);
func();
}
}
return 0;
}
void sig_handler(int signum)
{
ALOGE("Received signal %d\n", signum);
dl_iterate_phdr(walk_callback, NULL);
}
int main(int argc, char** argv)int main(int argc, char** argv)
{
argc,argv; argc,argv;
signal(SIGRTMIN + 3, sig_handler);
ALOGE("Registered for %d", SIGRTMIN + 3);
在向进程发送信号时,它确实转储了日志中所有链接的库,并且能够解析该符号并调用gcov_flush,但这似乎并未为库中的文件生成GCDA文件。这是可行的尝试方法吗?如果是,我该如何尝试生成GCDA文件?如果没有,还有其他可行的方法吗?