GCC's instrumentation and the target environment

Martin Liška mliska@suse.cz
Thu Nov 21 12:43:00 GMT 2019


On 11/20/19 4:14 PM, David Taylor wrote:
> Sorry for not responding sooner.
> 
> Thanks Martin.
> 
> Like Joel we have a third party solution to instrumentation.  Part of
> my objection to the third party solution is freedom.  There are
> customizations we would like, but not having source we're at the mercy
> of the vendor both for whether it gets done and the timing.  Part of
> the objection is the massive amount of changes I had to make to our
> build system to integrate it and the resulting feeling of fragility.
> They are reportedly addressing the latter in a future release.
> 
> By contrast, looking at GCC based instrumentation, the changes
> required to our build system are very small and easy.

Hello.

That sounds promising to me!

> 
> Part of my purpose in posting was the belief that this problem --
> wanting to instrument embedded code -- is not uncommon and has likely
> been solved already.  And the hope that one of the solvers would feel
> that their existing solution was in a good enough shape to contribute
> back.  Or that someone would point out that there is already an
> existing {Free | Open} source solution that I am overlooking.

Well, one quite similar usage will be usage of gcov in linux kernel,
please take a look at kernel/gcov subfolder.

> 
> Since no one has mentioned an existing solution, here is a first draft
> of a proposed solution to GCC instrumentation not playing well with
> embedded...
> 
> NOTE: *NONE* of the following has been implemented as yet.  I would
> ulimately like this to be something that once implemented would be
> considered for becoming part of standard GCC.  So, if you see something
> that would impede that goal or if changed would improve its chances,
> please speak up.
> 
> Add a new configure options --{with|without}-libgcov-standalone-env
> 
> Default: without (i.e., hosted)
> 
> Question: should hosted libgcov be the default for all configuration
> tuples?  Or should it only be the default when there are headers?
> Or...?

That's a detail, so let's say we'll have an option that will come up
with a wrappers (__gcov_ # fn).

> 
> When standalone, when building libgcov.a files, suppress
> -Dinhibit_libc and add -DLIBGCOV_STANDALONE_ENV to the command line
> switches.
> 
> Then in libgcov-driver.c, libgcov-driver-system.c, gcov-io.c, replace
> 
> all calls of fopen    with calls of __gcov_open_int
>               fread                  __gcov_read_int
> 	     fwrite                 __gcov_write_int
> 	     fclose                 __gcov_close_int
> 	     fseek                  __gcov_seek_int
> 	     ftell                  __gcov_tell_int
> 
> 	     setbuf                 __gcov_setbuf_int
> 
> 	         Probably belongs inside __gcov_open_int instead of as
> 	         a separate routine.
> 
> 	     getenv                 __gcov_getenv_int
> 
> 	     abort                  __gcov_abort_int
> 
>                   When the application is 'the kernel' or 'the system',
>                   abort isn't really an option.
> 
> 	     fprintf                __gcov_fprintf_int
> 
>                   This is called in two places -- gcov_error and
>                   gcov_exit_open_gcda_file.  The latter hard codes the
>                   stream as stderr; the former calls get_gcov_error_file
>                   to get the stream (which defaults to stderr but can be
>                   overridded via an environment variable).
> 
> 		 I think that get_gcov_error_file should be renamed to
> 		 __gcov_get_error_file, be made non-static, and be
> 		 called by gcov_exit_open_gcda_file instead of hard
> 		 coding stderr.
> 
> 		 For that matter, I feel that gcov_exit_open_gcda_file
> 		 should just call __gcov_error instead of doing it's
> 		 own error reporting.  And __gcov_get_error_file and
> 		 __gcov_error should be a replacable routines as
> 		 embedded systems might well have a different way of
> 		 reporting errors.
> 
> 	     vfprintf               __gcov_vfprintf_int
> 
> 	     	 If gcov_open_gcda_file is altered to call
> 	     	 __gcov_error and __gcov_error becomes a replacable
> 	     	 routine, then fprintf and vfprintf do not need to be
> 	     	 wrapped.
> 
> 	     malloc                 __gcov_malloc_int
> 	     free                   __gcov_free_int
> 
> 	         Embedded applications often do memory allocation
> 	         differently.
> 	
> While I think that the above list is complete, I wouldn't be surprised
> if I missed one or two.

That seams reasonable to me and can be easily achieved by a macro that
will either expand to __gcov # fn _ int, or to fn. I can imagine that.

> 
> Other than __gcov_open_int, there would be no conflict if the _int was
> left off the end.  I put it on to emphasize that these routines were
> not meant to be called by the user, but rather are provided by the
> user.  Some other naming convention might be better.
> 
> There would be a new header file, included as appropriate.  If the
> normal (hosted) build was in effect, then some new (potentially one
> line static inline) functions would be defined for each of the above
> functions that just call the expected standard libc function.  If the
> embedded (standalone) build was in effect, then there would be extern
> declarations for each of the above, but *NO* definition -- the
> definition would be the reposibility of the application.

As mentioned, a macro expansion can do that. And the last missing step,
which you will use, will be linking with additional library that will
implement all the __gcov_fn_int functions.

The suggested approach will need only quite minimal changes to the current
libgcov.

Martin

> 
> Comments?
> 
> David
> 



More information about the Gcc mailing list