Menu

#108 Available timer clock types not properly identified at runtime

v1.0 (example)
closed-wont-fix
nobody
None
6
2015-12-25
2015-07-03
No

The configure and build on HP-UX 11.11 goes fine, but when running checks in my ClamAV build, Check hits an issue in timer_create(), warning of an invalid argument.

check_run.c:478: Error in call to timer_create: Invalid argument

The line in question is as follows:

if(timer_create(check_get_clockid(),
                NULL /* fire SIGALRM if timer expires */ ,
                &timerid) == 0)
{

The only possible invalid argument would be the return value from check_get_clockid(). This goes to check.c, where because HAVE_LIBRT is defined, it first tries to call create_timer with CLOCK_MONOTONIC and checks for an error return code. CLOCK_MONOTONIC is set to -1 in lib/libcompat.h line 133.

However, when I add an eprintf to check_run.c to determine what value is returned from check_get_clockid(), it gives me a "-1" even though I should get a valid CLOCK_REALTIME value.

Additional debug code within check.c indicates that calling create_timer(-1, NULL, &timerid) returns a nonzero value as expected, and so it falls through to CLOCK_REALTIME. However, this is also set to -1 because of the line in lib/libcompat.h, because the HP-UX system is apparently treating #defines differently from enum keywords. For example:

typedef enum __clockid_t {
    CLOCK_INVALID = 0,
    CLOCK_REALTIME = 1, /* the system-wide "wall clock" */
    CLOCK_VIRTUAL = 2,  /* the per-process user execution clock */
    CLOCK_PROFILE = 4,  /* the per-process execution clock */
    RTTIMER0 = 8,
    RTTIMER1 = 16
} clockid_t;

#ifdef CLOCK_INVALID
#error yes
#else
#error no
#endif

This errors out as "no" during test compile.

So the #ifdef CLOCK_REALTIME in lib/libcompat.h will not detect whether the enum contains the specified clock type.

It looks like this would need to be done as a configure check, i.e., HAVE_CLOCK_MONOTONIC, rather than at run time.

In the meantime, I've hardcoded it to return 1 for clock_realtime which will at least let me get the ClamAV unit tests done.

Related

Bugs: #108

Discussion

  • Michael Pelletier

    The ClamAV unit tests all passed once I increased the timeout to five minutes to accommodate the 500MHz CPU speed on the ten-year-old B2600, so this item is therefore the only thing impacting an HP-UX 11.11 build.

     
    • Branden Archer

      Branden Archer - 2015-07-05

      Michael,

      Thanks for your interest in Check.

      It is interesting that the compiler used on HP-UX treats enums and #defines
      differently, never seen that before.

      Although Check does not officially support HP-UX (as we do not have a
      configured machine to test on), if you were able to create a patch which
      happens to work we would consider adding it into Check.

      Looking around, something similar to the following patch in Haskell may be
      a good starting point:

      https://phabricator.haskell.org/D831?vs=on&id=2745&whitespace=ignore-most#toc

      That patch shows a way of checking for available timers on the system at
      build time by attempting to compile and run a test program. Something
      similar is already being done in Check, take a look at librt_timers.m4.
      That check, however, was to get around an issue on OpenBSD where the high
      resolution timer calls were stubbed out but always set errno to ENOSYS and
      return -1. As long as an alternative timer check maintains that, it should
      be OK. Note though that the current check will disable all high resolution
      timer support if it fails, as opposed to simply determining what timers
      types to use.

      Alternatively, one could use the following configure script flag:

      --enable-timer-replacement

      This will replace all high resolution timer calls with using alarm()
      instead. As long as high resolution timers (sub second precision) is not
      needed, this should be sufficient.

      • Branden

      On Sat, Jul 4, 2015 at 11:51 AM, Michael Pelletier mvpel@users.sf.net
      wrote:

      The ClamAV unit tests all passed once I increased the timeout to five
      minutes to accommodate the 500MHz CPU speed on the ten-year-old B2600, so
      this item is therefore the only thing impacting an HP-UX 11.11 build.


      Status: open
      Group: v1.0 (example)
      Created: Fri Jul 03, 2015 05:58 PM UTC by Michael Pelletier
      Last Updated: Fri Jul 03, 2015 05:58 PM UTC
      Owner: nobody

      The configure and build on HP-UX 11.11 goes fine, but when running checks
      in my ClamAV build, Check hits an issue in timer_create(), warning of an
      invalid argument.

      check_run.c:478: Error in call to timer_create: Invalid argument

      The line in question is as follows:

      if(timer_create(check_get_clockid(),
      NULL / fire SIGALRM if timer expires / ,
      &timerid) == 0)
      {

      The only possible invalid argument would be the return value from
      check_get_clockid(). This goes to check.c, where because HAVE_LIBRT is
      defined, it first tries to call create_timer with CLOCK_MONOTONIC and
      checks for an error return code. CLOCK_MONOTONIC is set to -1 in
      lib/libcompat.h line 133.

      However, when I add an eprintf to check_run.c to determine what value is
      returned from check_get_clockid(), it gives me a "-1" even though I should
      get a valid CLOCK_REALTIME value.

      Additional debug code within check.c indicates that calling
      create_timer(-1, NULL, &timerid) returns a nonzero value as expected, and
      so it falls through to CLOCK_REALTIME. However, this is also set to -1
      because of the line in lib/libcompat.h, because the HP-UX system is
      apparently treating #defines differently from enum keywords. For example:

      typedef enum __clockid_t {
      CLOCK_INVALID = 0,
      CLOCK_REALTIME = 1, / the system-wide "wall clock" /
      CLOCK_VIRTUAL = 2, / the per-process user execution clock /
      CLOCK_PROFILE = 4, / the per-process execution clock /
      RTTIMER0 = 8,
      RTTIMER1 = 16} clockid_t;

      ifdef CLOCK_INVALID#error yes#else#error no#endif

      This errors out as "no" during test compile.

      So the #ifdef CLOCK_REALTIME in lib/libcompat.h will not detect whether
      the enum contains the specified clock type.

      It looks like this would need to be done as a configure check, i.e.,
      HAVE_CLOCK_MONOTONIC, rather than at run time.

      In the meantime, I've hardcoded it to return 1 for clock_realtime which
      will at least let me get the ClamAV unit tests done.


      Sent from sourceforge.net because you indicated interest in
      https://sourceforge.net/p/check/bugs/108/

      To unsubscribe from further messages, please visit
      https://sourceforge.net/auth/subscriptions/

       

      Related

      Bugs: #108

  • Michael Pelletier

    Thanks for pointing out the enable-timer-replacement option. Probably the most expedient fix would be to have configure enable that if it detects an HP-UX target, which would thus require no changes to the source code.

    I found the enum/define distinction a bit odd too, considering that I'm using GCC 4.7.2, but I was able to find this information about the POSIX standard's handling of this situation:

    http://stackoverflow.com/questions/21855326/utility-of-macros-for-enum

    Where a constant is required to be a macro but is also allowed to be another type of constant such as an enumeration constant, on implementations which do define it as another type of constant the macro is typically defined as follows:

    #define macro_name macro_name
    

    This allows applications to use #ifdef, etc. to determine whether the macro is defined, but the macro is not usable in #if preprocessor directives because the preprocessor will treat the unexpanded word macro_name as having the value zero.

    This is undoubtedly from a POSIX standard that post-dates the HP-UX 11.11 operating system's ca. 2000 release, however. I would expect that 11.31, and probably 11.23, handle this situation properly, so configure could probably limit the enable-timer-replacement override to the 11.11 release.

    I'll also take one more look at the OS headers; although I didn't find anything in my first find-grep pass, there's a chance that there's a POSIX-related compatibility define somewhere in there from an OS patch which will implement compliance with the above POSIX version.

     
  • Branden Archer

    Branden Archer - 2015-12-25
    • status: open --> closed-wont-fix
     
  • Branden Archer

    Branden Archer - 2015-12-25

    If you are intersted in following this up further, and adding the --enable-timer-replacement argument to the configure script manually is not sufficient, kindly create a pull request with proposed changes against Check in its new home:

    https://github.com/libcheck/check

     

Log in to post a comment.