This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Code coverage for _constructor()/_destructor()'s?



(CC'ing this to the gcc-help list .. and retaining some of the previous quoted text for context, as this thread was so far held privately between Ian and myself..)


On 07/01/2010 05:13 PM, Ian Lance Taylor wrote:
Jay Vaughan<jay.vaughan@thalesgroup.com> writes:
The coverage code runs a constructor at the default initialization
priority.  Since your code is running at a higher priority, it runs
before coverage has been initialized.


I can change the priority - I tried using 65535 (lowest priority?) but still I get no coverage for code executed during the constructor phase.

Please send replies to the list, not just to me. Thanks.



(Sorry about that Ian.. Done.)


For the purposes of informing the list, this thread is about the GNU coverage method not being useful for the purposes of covering library/other code which uses the constructor/destructor attributes on functions.

Context: I have written a library - lets call it libguardian - which is used to control the launching of applications on the basis of internal qualifier calls made by the library in the constructor/destructor functions. The idea is that this libguardian is LD_PRELOAD'ed around most of the application binaries in my custom system, and serves to govern the continued launching of apps at runtime. If my constructor() method fails to meet the conditions required for launch, it exit()'s - prior to main() of the application being called.

The problem is that the gcov functions do not properly insert themselves in and account for the priorities of the chain of previous constructors/destructors in the code being covered, which means that it is not possible to adequately capture coverage information for this libguardian library.

Although I *know* the code is being executed, and can allow for exceptions in the coverage mechanism, it is definitely worthwhile to investigate how to get coverage in the circumstances where constructor/destructor attributes are used on functions .. and Ian Lance Taylor has correctly identified the problem: it seems that something about the design of gcov does not account for constructor/destructor priorities in the insertion of its own constructor.

If my constructor() function exit()'s due to non-optimal conditions at its determination, coverage information about that run path is lost.


All constructors with any priority run before constructors with no
priority.  That is, constructors with no priority have the lowest
priority of all.


I see that the gcov constructor, which is being dynamically built by gcov, is using the lowest priority of all - 65535.

Would it be better to have the highest priority in use, so that gcov is always the first and last to be called in the chain, and thus coverage information is not lost? I will attempt this fix locally.

>>> Ian Lance Taylor said:
Ideally you could call __gcov_init (info) at the start of your
constructor.  The problem is that __gcov_init takes an argument, a
pointer to a struct gcov_info, and you should really pass the same
pointer as the default constructor will pass.  But there is no way for
your code to get that value.

This seems like a real oversight in the design of the coverage system .. I wonder if there is any chance to fix this, easily, to allow for coverage of constructor/destructor code in libraries? I'm not familiar with who is wearing the coverage hat for GCC, maybe you know? I should report this issue, if it can be fixed in future releases.. do you think its feasible?

It's an oversight, yes. Constructor priorities are not widely used. Please do go ahead and open a bug report about this. It should not be too hard to make it possible for constructor priority code to arrange for coverage. I think the developers would be reluctant to require the coverage constructors to use a priority, since many systems do not support constructor priorities.


I have created a bug report about this here:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44779

And I will contribute additional findings as I note them in my work.


I've been unable to find the gcov constructor code in our gcc sources
(4.4.4) .. if a constructor is being used, I can adjust my priority so
that it gets executed after coverage constructor, but I can't see
where the constructor is created .. got any hints here?  Maybe I could
solve my problem with constructor priorities, after all ..

The constructor is created directly by the compiler. In gcc 4.4 it's done by the call to cgraph_build_static_cdtor in gcc/coverage.c. Ian


Thank you Ian, I have seen this now, and understand that gcov constructs its own callgraph at runtime to handle this insertion - but it appears that this method does not allow _constructor()'s to exit(), while allowing gcov to capture the coverage information ..

Suggested fix?

Option A: Add a means by which an application/library "attribute(constructor)" function can directly begin and control coverage information processing - akin to __gcov_init() but with some ideal public gcov_info struct being available from the gcov library, as Ian describes.

Option B: Re-work the coverage constructor_ itself so that it accounts for previous priorities in the constructor chain and can wrap exit()'s that may occur in outer constructor priorities.

I confess that I do not yet have a handle on this myself to attempt a patch, but hopefully after continued discussion it can be considered for future work, as necessary.

--
;                                                           Thales Austria GmbH
Jay Vaughan, Programmer                                     Scheydgasse 41
jay.vaughan@thalesgroup.com                                 1210 Vienna AUSTRIA
===============================================================================


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]