Thread: BUG #2162: Same as bug #1679 - finite() - unresolved symbol

BUG #2162: Same as bug #1679 - finite() - unresolved symbol

From
"Francois Laupretre"
Date:
The following bug has been logged online:

Bug reference:      2162
Logged by:          Francois Laupretre
Email address:      flconseil@yahoo.fr
PostgreSQL version: 8.1.1
Operating system:   HP-UX 11.11
Description:        Same as bug #1679 - finite() - unresolved symbol
Details:

Same problem as described in bug report #1679 of 24-MAY-2005.

Same kind of workaround (comment out HAVE_FINITE in
src/include/pg_config.h).

As bug #1679 is more than 6 months old, I'd like to get a status. If it can
help, I confirm that, without modifications, the current stable release of
PostgreSQL does not compile on HP-UX 11.11.

Thanks in advance

François

Re: BUG #2162: Same as bug #1679 - finite() - unresolved symbol

From
Tom Lane
Date:
"Francois Laupretre" <flconseil@yahoo.fr> writes:
> As bug #1679 is more than 6 months old, I'd like to get a status. If it can
> help, I confirm that, without modifications, the current stable release of
> PostgreSQL does not compile on HP-UX 11.11.

It works fine for me anytime I try it on HP's testdrive systems.

If you are building with gcc, one possible theory is that your gcc
installation is broken.  A common way for this to happen is to copy
a gcc installation created on one HPUX version to a machine running
a slightly different HPUX version.  gcc's internal copies of system
header files then fail to match the running system, leading to all
sorts of hard-to-debug problems :-(

            regards, tom lane

Re: BUG #2162: Same as bug #1679 - finite() - unresolved symbol

From
Tom Lane
Date:
"F. Laupretre" <flconseil@yahoo.fr> writes:
> When configure checks to see if we have finite(), it attempts to
> compile a small program containing 'dummy=finite(1.0)'. On my system,
> where I am using gcc 4.0.2, this small program is tested with a '-O2'
> flag, and the gcc optimizer is too smart ! It detects that we are
> writing to a dummy var, and it removes the line !

Argh!  gcc couldn't do that in general, of course --- it must be using
some built-in knowledge that finite() doesn't have side-effects.
I'll have to look at how AC_CHECK_FUNC() avoids that.  Obviously we
are getting bit because our homegrown check for finite() isn't smart
enough.

I'd actually argue that this is a gcc bug: when there is no declaration
of finite() in the system headers (there isn't is there?) it's wrong to
conclude just on the name of the function that it is side-effect-free.
But I don't suppose a fix will be forthcoming quickly, so we'll have to
work around it.

Thanks for taking the trouble to chase this down.

            regards, tom lane

Re: BUG #2162: Same as bug #1679 - finite() - unresolved symbol

From
Tom Lane
Date:
"F. Laupretre" <flconseil@yahoo.fr> writes:
> In order for the check to be done correctly, we have to provide a
> program that the compiler cannot optimize, ie where it cannot detect
> that the call is useless, even if it is very very smart. Here is a
> patch with such a program.

I haven't got a lot of faith in your proposed patch --- with
sufficiently aggressive optimization, the compiler might inline
the is_f() function, no?  After looking at the modern version of
AC_CHECK_FUNC, I'm thinking that the best answer is to make the
finite() result affect the program's exit status.  Would you try
this version of the check and see if it works for you?

AC_TRY_LINK([#include <math.h>],
            [return finite(1.0) ? 0 : 1;],
            [AC_DEFINE(HAVE_FINITE, 1, [Define to 1 if you have finite().])
AC_MSG_RESULT(yes)],
            [AC_MSG_RESULT(no)])

            regards, tom lane

Re: BUG #2162: Same as bug #1679 - finite() - unresolved symbol

From
Bruce Momjian
Date:
Tom Lane wrote:
> "F. Laupretre" <flconseil@yahoo.fr> writes:
> > In order for the check to be done correctly, we have to provide a
> > program that the compiler cannot optimize, ie where it cannot detect
> > that the call is useless, even if it is very very smart. Here is a
> > patch with such a program.
>
> I haven't got a lot of faith in your proposed patch --- with
> sufficiently aggressive optimization, the compiler might inline
> the is_f() function, no?  After looking at the modern version of
> AC_CHECK_FUNC, I'm thinking that the best answer is to make the
> finite() result affect the program's exit status.  Would you try
> this version of the check and see if it works for you?
>
> AC_TRY_LINK([#include <math.h>],
>             [return finite(1.0) ? 0 : 1;],
>             [AC_DEFINE(HAVE_FINITE, 1, [Define to 1 if you have finite().])
> AC_MSG_RESULT(yes)],
>             [AC_MSG_RESULT(no)])

Could any other configure tests fail in this way?

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073

Re: BUG #2162: Same as bug #1679 - finite() - unresolved symbol

From
Tom Lane
Date:
Bruce Momjian <pgman@candle.pha.pa.us> writes:
> Could any other configure tests fail in this way?

Good point.  The isinf() test probably has the same failure mode.

There is also the sigsetjmp() test, but since that has side-effects,
it doesn't seem very much at risk of being aggressively optimized.
I don't see any other cases where we're avoiding AC_CHECK_FUNC.

            regards, tom lane

Re: BUG #2162: Same as bug #1679 - finite() - unresolved symbol

From
Tom Lane
Date:
"F. Laupretre" <flconseil@yahoo.fr> writes:
> Or maybe, if it is really too smart (able to compute the result at
> compile time), we could have not to use a constant argument. Something
> like 'return finite((double)argv) ? 0 : 1'.

If the compiler is able to compute the result without using the external
function, that's fine.  That's equivalent to having a macro-based
implementation, which is exactly what we're going out of our way to
allow here.  All that we have to do is ensure that the compiler can't
discard the expression un-evaluated, so making the exit value depend
on it seems pretty bulletproof to me.

I suppose though that there's some chance of the constant-argument case
being treated differently from not-constant, so your idea has some merit.
We couldn't use argc/argv however because the autoconf skeleton for
main() doesn't declare 'em.

            regards, tom lane

Re: BUG #2162: Same as bug #1679 - finite() - unresolved symbol

From
Peter Eisentraut
Date:
Am Mittwoch, 11. Januar 2006 22:33 schrieb Tom Lane:
> I suppose though that there's some chance of the constant-argument case
> being treated differently from not-constant, so your idea has some merit.

Use a global rather than a local variable.

--
Peter Eisentraut
http://developer.postgresql.org/~petere/

Re: BUG #2162: Same as bug #1679 - finite() - unresolved symbol

From
Tom Lane
Date:
Peter Eisentraut <peter_e@gmx.net> writes:
> Am Mittwoch, 11. Januar 2006 22:33 schrieb Tom Lane:
>> I suppose though that there's some chance of the constant-argument case
>> being treated differently from not-constant, so your idea has some merit.

> Use a global rather than a local variable.

In principle an aggressive compiler could still determine that the
global variable is modified nowhere else in the executable.  In practice
that will probably get the job done ... this year anyway ...

I did like François' idea of using argc, but the present autoconf
infrastructure doesn't seem to allow it :-(

            regards, tom lane

Re: BUG #2162: Same as bug #1679 - finite() - unresolved symbol

From
"F. Laupretre"
Date:
Or maybe, if it is really too smart (able to compute the result at compile =
time), we could have not to use a constant argument. Something like 'return=
 finite((double)argv) ? 0 : 1'.

Re: BUG #2162: Same as bug #1679 - finite() - unresolved symbol

From
flaupretre@free.fr
Date:
> In principle an aggressive compiler could still determine that the
> global variable is modified nowhere else in the executable.

Yes, it can determine that the variable content is constant but what is
important here is that it cannot determine its value at compile time. This way,
either it replaces the call with a macro, and it is OK, or it has to keep the
call. The only problem is to find a global value, which cannot be determined at
compile time.

First, I tested your suggestion : 'return finite(1.0) ? 0 : 1;'. It doesn't
work, the call is removed. With this test, we see that the optimizer does not
remove the line because the result is unused, as I thought, but more probably
because it is able to compute it at compile time. Which means that finite()
becomes a reserved function in gcc, as I checked that the call is removed even
if we don't include <math.h> :-(

Then, I looked for something using a global value, and compatible with the
autoconf skeleton. I tried 'return finite(*((float *)main));'. And it works :
the call is not removed, even with '-O4'. In my opinion, this syntax cannot be
removed by the optimizer, as it should be impossible to determine at compile
time if the float stored at address 'main' is a finite number. So, as it is the
best solution I have so far, I propose it.

About isinf():
The case is more complex, as isinf is a macro in <math.h>.
Actually :
  isinf(x);
is translated to :
  ((sizeof(x)==sizeof(float))?_Isinff(x):_Isinf(x))
And only _Isinff is kept ! But it can be considered as correct, as it is a
sizeof comparison (allowed at compile time). If you want to make it more
robust, it can be replaced by something like above :
   return isinf(*((float *)main));
I tested and it works too.

About sigsetjmp :
I just checked that the symbol is still present with '-O2' and '-O4'. And as I
never use these f... setjmp mechanism, I cannot suggest any more robust test.

Regards

François

Re: BUG #2162: Same as bug #1679 - finite() - unresolved symbol

From
"F. Laupretre"
Date:
Thanks for your suggestion. It could have been the include files but I reco=
mpiled gcc on the system and it didn't change anything. Actually, I found t=
he solution when I tried to understand why configure detects a finite() fun=
ction on a system which does not have it.

First, I checked that there is no finite() function on my system: my libm.s=
l file is a symbolic link to libm.2, which does not contain this function. =
I don't know if it is the case for every HP-UX 11.11 system or if it is the=
 result of a patch (as there is another file in /usr/lib, named libm.1, whi=
ch contains the finite() function, probably for compatibility). And this sy=
mbol is not contained in any shared library under /usr (I checked them all).

When configure checks to see if we have finite(), it attempts to compile a =
small program containing 'dummy=3Dfinite(1.0)'. On my system, where I am us=
ing gcc 4.0.2, this small program is tested with a '-O2' flag, and the gcc =
optimizer is too smart ! It detects that we are writing to a dummy var, and=
 it removes the line ! You can verify it with 'gcc -S -O2' or with 'nm' app=
lied to the 'conftest' resulting executable file. After the call to finite(=
) has been removed, of course, the program compiles fine (it is empty now) =
and configure wrongly concludes that we have finite().

In order for the check to be done correctly, we have to provide a program t=
hat the compiler cannot optimize, ie where it cannot detect that the call i=
s useless, even if it is very very smart. Here is a patch with such a progr=
am. The fact of putting the call in a public function outside of main() for=
ces the compiler to keep it, as it could be referenced from another file at=
 link time.

$ diff configure.in configure.in.new
964c964
<    [int dummy=3Dfinite(1.0);],
---
>    [return 0; } int is_f(number) double number; { return finite(number); ]

After applying this patch on my system, everything works fine, HAVE_FINITE =
is not defined and float.c correctly switches to the isfinite() macro, defi=
ned in <math.h>.

Regards

Fran=E7ois

Re: BUG #2162: Same as bug #1679 - finite() - unresolved symbol

From
"F. Laupretre"
Date:
I will also try these tests with '-O2' tomorrow (compile conftest and look =
if the symbol is still inside). I will even try more aggressive optimizatio=
n.

De : Tom Lane [mailto:tgl@sss.pgh.pa.us]

Bruce Momjian <pgman@candle.pha.pa.us> writes:
> Could any other configure tests fail in this way?

Good point.  The isinf() test probably has the same failure mode.

There is also the sigsetjmp() test, but since that has side-effects,
it doesn't seem very much at risk of being aggressively optimized.
I don't see any other cases where we're avoiding AC_CHECK_FUNC.

Re: BUG #2162: Same as bug #1679 - finite() - unresolved symbol

From
Peter Eisentraut
Date:
Am Donnerstag, 12. Januar 2006 09:57 schrieb Tom Lane:
> In principle an aggressive compiler could still determine that the
> global variable is modified nowhere else in the executable.

I think to do that the compiler would have to prove what the dynamic linker
will do at run time.

> I did like François' idea of using argc, but the present autoconf
> infrastructure doesn't seem to allow it :-(

Maybe their use is unportable. :-)

--
Peter Eisentraut
http://developer.postgresql.org/~petere/

Re: BUG #2162: Same as bug #1679 - finite() - unresolved symbol

From
Tom Lane
Date:
Peter Eisentraut <peter_e@gmx.net> writes:
> Am Donnerstag, 12. Januar 2006 09:57 schrieb Tom Lane:
>> In principle an aggressive compiler could still determine that the
>> global variable is modified nowhere else in the executable.

> I think to do that the compiler would have to prove what the dynamic linker
> will do at run time.

Yeah.  The idea of casting a function pointer to (double *) seems mighty
ugly, and in the absence of evidence that we need it, I think it's
better to stick with less surprising code.  I've committed changes to
make the tests look like this:

AC_TRY_LINK([
#include <math.h>
double glob_double;
],
            [return finite(glob_double) ? 0 : 1;],
            [AC_DEFINE(HAVE_FINITE, 1, [Define to 1 if you have finite().])
AC_MSG_RESULT(yes)],
            [AC_MSG_RESULT(no)])


            regards, tom lane