Chen, Yuanfang via llvm-dev
2020-Jun-02 23:43 UTC
[llvm-dev] Code coverage for member functions that are defined inside the class
Hello, We have a user that wants to get the code coverage report for his library without turning on instrumentation for the library clients or change how they are built (only the library is instrumented). It seems like the inline member functions defined in headers are not instrumented in this case because the clients are not instrumented. The library itself does not have a copy of the inline methods either. In below example,> clang++ -fprofile-instr-generate -fcoverage-mapping -c foobar.cpp -o foobar.o > clang++ main.cpp foobar.o -o foobar > LLVM_PROFILE_FILE="foo.profraw" ./foobar > llvm-profdata merge -sparse foo.profraw -o foo.profdata > llvm-cov show ./foobar -instr-profile=foo.profdata""" 1| |#include "foobar.h" 2| | 3| | 4| |void FooBar::foo(void) 5| 1|{ 6| 1| printf("foo\n"); 7| 1|} 8| | """ foobar.h """ #pragma once #include <stdio.h> class FooBar { public: void foo(void); void bar(void) { printf("bar\n"); } }; """ foobar.cpp """ #include "foobar.h" void FooBar::foo(void) { printf("foo\n"); } """ main.cpp """ #include "foobar.h" int main(int argc, const char *argv[]) { FooBar foobar; foobar.foo(); foobar.bar(); return 0 } """ My question are: - Is there an existing solution to this use case? - If not, is there a compiler switch to use when compiling foobar library to make inline function methods behave like an out-of-line non-inline function? (there are hundreds of inline function methods which makes doing this manually hard) - Is there some function attribute such as [[instrument-for-coverage]] to say: I want this function to be instrumented no matter what the command switches are? If not, is it a good idea? Thanks, - Yuanfang
Vedant Kumar via llvm-dev
2020-Jun-04 18:11 UTC
[llvm-dev] Code coverage for member functions that are defined inside the class
Hey Yuanfang, It seems like you’re looking for -femit-all-decls (https://godbolt.org/z/3uw-wF <https://godbolt.org/z/3uw-wF>). This interoperates just fine with -fcoverage-mapping. Any duplicate coverage mapping records for functions emitted in multiple TUs will be merged by the linker. best, vedant> On Jun 2, 2020, at 4:43 PM, Chen, Yuanfang via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > Hello, > > We have a user that wants to get the code coverage report for his library without turning on instrumentation for the library clients or change how they are built (only the library is instrumented). It seems like the inline member functions defined in headers are not instrumented in this case because the clients are not instrumented. The library itself does not have a copy of the inline methods either. > > In below example, >> clang++ -fprofile-instr-generate -fcoverage-mapping -c foobar.cpp -o foobar.o >> clang++ main.cpp foobar.o -o foobar >> LLVM_PROFILE_FILE="foo.profraw" ./foobar >> llvm-profdata merge -sparse foo.profraw -o foo.profdata >> llvm-cov show ./foobar -instr-profile=foo.profdata > > """ > 1| |#include "foobar.h" > 2| | > 3| | > 4| |void FooBar::foo(void) > 5| 1|{ > 6| 1| printf("foo\n"); > 7| 1|} > 8| | > """ > > > > foobar.h > """ > #pragma once > #include <stdio.h> > > class FooBar { > public: > void foo(void); > void bar(void) { > printf("bar\n"); > } > }; > """ > > foobar.cpp > """ > #include "foobar.h" > void FooBar::foo(void) { > printf("foo\n"); > } > """ > > main.cpp > """ > #include "foobar.h" > int main(int argc, const char *argv[]) { > FooBar foobar; > foobar.foo(); > foobar.bar(); > return 0 > } > """ > > My question are: > - Is there an existing solution to this use case? > - If not, is there a compiler switch to use when compiling foobar library to make inline function methods behave like an out-of-line non-inline function? (there are hundreds of inline function methods which makes doing this manually hard) > - Is there some function attribute such as [[instrument-for-coverage]] to say: I want this function to be instrumented no matter what the command switches are? If not, is it a good idea? > > > Thanks, > - Yuanfang > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200604/3ea6766c/attachment.html>
Chen, Yuanfang via llvm-dev
2020-Jun-05 01:20 UTC
[llvm-dev] Code coverage for member functions that are defined inside the class
Hi Vedant,
Thanks for the pointer. I gave the `-femit-all-decls` flag a try. It seems it
makes foobar.o contain a copy of the instrumented `bar` but this copy of `bar`
is not called anywhere else. Clients of `bar` will still get their own copy of
instrumented `bar`(inlined or not). I checked the coverage report, the counter
of `bar` is still 0. Right now, we're just instrumenting everything and
filtering out non-interesting results.
- Yuanfang
________________________________________
From: Vedant Kumar <vsk at apple.com>
Sent: Thursday, June 4, 2020 11:11 AM
To: Chen, Yuanfang
Cc: llvm-dev at lists.llvm.org
Subject: Re: [llvm-dev] Code coverage for member functions that are defined
inside the class
Hey Yuanfang,
It seems like you’re looking for -femit-all-decls
(https://godbolt.org/z/3uw-wF). This interoperates just fine with
-fcoverage-mapping. Any duplicate coverage mapping records for functions emitted
in multiple TUs will be merged by the linker.
best,
vedant
On Jun 2, 2020, at 4:43 PM, Chen, Yuanfang via llvm-dev <llvm-dev at
lists.llvm.org<mailto:llvm-dev at lists.llvm.org>> wrote:
Hello,
We have a user that wants to get the code coverage report for his library
without turning on instrumentation for the library clients or change how they
are built (only the library is instrumented). It seems like the inline member
functions defined in headers are not instrumented in this case because the
clients are not instrumented. The library itself does not have a copy of the
inline methods either.
In below example,
clang++ -fprofile-instr-generate -fcoverage-mapping -c foobar.cpp -o foobar.o
clang++ main.cpp foobar.o -o foobar
LLVM_PROFILE_FILE="foo.profraw" ./foobar
llvm-profdata merge -sparse foo.profraw -o foo.profdata
llvm-cov show ./foobar -instr-profile=foo.profdata
"""
1| |#include "foobar.h"
2| |
3| |
4| |void FooBar::foo(void)
5| 1|{
6| 1| printf("foo\n");
7| 1|}
8| |
"""
foobar.h
"""
#pragma once
#include <stdio.h>
class FooBar {
public:
void foo(void);
void bar(void) {
printf("bar\n");
}
};
"""
foobar.cpp
"""
#include "foobar.h"
void FooBar::foo(void) {
printf("foo\n");
}
"""
main.cpp
"""
#include "foobar.h"
int main(int argc, const char *argv[]) {
FooBar foobar;
foobar.foo();
foobar.bar();
return 0
}
"""
My question are:
- Is there an existing solution to this use case?
- If not, is there a compiler switch to use when compiling foobar library to
make inline function methods behave like an out-of-line non-inline function?
(there are hundreds of inline function methods which makes doing this manually
hard)
- Is there some function attribute such as [[instrument-for-coverage]] to say: I
want this function to be instrumented no matter what the command switches are?
If not, is it a good idea?
Thanks,
- Yuanfang
_______________________________________________
LLVM Developers mailing list
llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Seemingly Similar Threads
- llvm-cov: Combined report for multiple executables
- llvm-cov: Combined report for multiple executables
- [LLVMdev] Coverage mapping issue: Malformed profile data
- [PGO] Thoughts on adding a key-value store to profile data formats
- [PGO] Thoughts on adding a key-value store to profile data formats