How to invoke math functions from dbx?

Is there an easy way to invoke math functions from dbx? If I try, for example, to call sqrt I get meaningless results:

(dbx) print sqrt(4.0)

sqrt(4) = 1074790400

(dbx)

This is from code which uses sqrt, so sqrt should be accessible. Does this need some kind of cast?

[299 byte] By [DieterRupperta] at [2007-11-27 10:29:25]
# 1

No, no cast is required. It looks like wrong sqrt is called or bug in dbx. I just tried it on Solaris 10 x64 machine and dbx 7.6:

(dbx:main) p sqrt(4.0)

sqrt(4) = 2.0

What is your configuration (OS, arch, dbx)?

MaximKartasheva at 2007-7-28 17:57:21 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 2

And we need to make sure that sqrt() is actually what you expect it to be: please issue

whatis sqrt

which sqrt

in dbx and post output here.

MaximKartasheva at 2007-7-28 17:57:21 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 3

This happens with dbx 7.5 on Solaris 10, Sparc (the dbx version from Studio 11).

Output of dbx -V:

Sun Dbx Debugger 7.5 Patch 121023-01 2006/02/09

Output of uname -a:

SunOS fiji 5.10 Generic_118833-36 sun4u sparc SUNW,Sun-Blade-1500

The output of whereis/whatis/which:

(dbx) whereis sqrt

function:`libm.so.2`sqrt

(dbx) whatis sqrt

sqrt (0x0):

(dbx) which sqrt

`libm.so.2`sqrt

(dbx)

DieterRupperta at 2007-7-28 17:57:21 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 4

This is not right:

(dbx) whatis sqrt

sqrt (0x0):

And I guess its the reason why call gives strange result: dbx doesn't know this function prototype and treats return value as int (presumably).

Ah, now I understand what's going on: apparently, you don't _use_ sqrt in your code, which resulted in sqrt prototype missing from a.out's debug info. I don't know if that can be helped, though other than making a fake call to sqrt in your program.

MaximKartasheva at 2007-7-28 17:57:21 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 5

No, this can't be the reason; I invoke sqrt in a small test program on the very line where sqrt is used.

But I just found that it depends on the fact that this is C++ code (sorry, I forgot to mention this). If I compile the same small test program with cc, I can invoke sqrt and get correct results. With CC, i.e. as C++ code, this does not work, and the obvious idea to use std::sqrt does not work either:

(dbx) print std::sqrt(4.0)

dbx: "sqrt" is not defined as a function or procedure in std

dbx: see `help scope' for details

(dbx)

BTW: this seems to be the same with CC/dbx from Studio 12.

DieterRupperta at 2007-7-28 17:57:21 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 6

Yeah, it is definitely C++-specific.

As a workaround, try using __sqrtf and __sqrtl instead of sqrt; they both work:

(dbx:main) p __sqrtf(4.0)

__sqrtf(4) = 2.0

(dbx:main) p __sqrtl(4.0)

__sqrtl(4) = 2.00000000000000000000000000000000000e+00

Apparently, C and C++ compilers generate different debug info:

$ cc -g -lm a.c

$ dwarfdump a.out | grep sqrt

DW_AT_namesqrt

and

$ CC -g -lm a.c

$ dwarfdump a.out | grep sqrt

DW_AT_SUN_part_link_namei__sqrtf

DW_AT_name__sqrtf

DW_AT_SUN_part_link_namei__sqrtl

DW_AT_name__sqrtl

As you can see, when compiled with C++ compiler, sqrt is not mentioned in debug information and thus dbx can't see it.

The question is why...

This is probably because, when compiled with CC, math.h defines sqrt as 'extern "C++" inline ...', but this needs more investigation. I'll try to ask around.

MaximKartasheva at 2007-7-28 17:57:21 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 7

Thanks for the investigation. I tried myself with dumpstabs (CC from Studio 11 uses stabs), and arrived at the same conclusion. Strangely, fabs and pow are present in the debug info, as well as these float and long double variants with leading "__", but sqrt is not. fabs and pow consequently can be used from dbx.

Out of curiosity: would it be possible to coerce dbx into calling sqrt, with sqrt being casted to a "function pointer with argument type double, returning double"? I tried, but I only manage to produce syntax errors:

(dbx) print ((double)(*)(double))sqrt)(4.0)

dbx: syntax error on "((double)(*)"

Does dbx not support this kind of feature, or did I somehow get the cast wrong?

This would be very useful for functions compiled without debug info.

DieterRupperta at 2007-7-28 17:57:21 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 8

> Out of curiosity: would it be possible to coerce dbx into calling sqrt, with sqrt being casted

> to a "function pointer with argument type double, returning double"? I tried, but I only

> manage to produce syntax errors:

I tried that, too, in the first place and I think function pointers are not supported by dbx. That's (partly) understandable -- dbx is not a compiler. But I'd suggest you file an RFE (Request For Enhancement) through bugs.sun.com since it would indeed be a useful feature.

Thanks for reporting this problem, by the way.

I managed to create smaller testcase that demonstrates problem with sqrt and will probably file a bug if no one convince me that this is expected behaviour. Test looks like this:

$ cat test.c

namespace MY

{

extern double sqrt ( double );

}

using MY::sqrt;

void foo()

{

double d = 0;

d = sqrt(4);

}

There are two key words: namespace and extern. If either of them is omitted, sqrt appears in debug info all right.

MaximKartasheva at 2007-7-28 17:57:21 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 9

>

> I tried that, too, in the first place and I think

> function pointers are not supported by dbx. That's

> (partly) understandable -- dbx is not a compiler. But

> I'd suggest you file an RFE (Request For Enhancement)

> through bugs.sun.com since it would indeed be a

> useful feature.

>

For the record: I got the cast wrong (of course). Trying again:

(dbx) print (( double (*)(double))sqrt)(4.0)

((double (*)(double)) sqrt)(4) = &(noname) at 0x40100000

(dbx)

Now the syntax is accepted, but the output is useless.

gcc/gdb, on the other hand, apparently support this feature. I tried, just to try out my cast syntax, the same small example on a linux box and got, with the same expression (with gdb 6.1)

(gdb) p (( double (*)(double))sqrt)(4.0)

$1 = 2

(gdb)

Plain "p sqrt(4.0)" does not work there either:

(gdb) whatis sqrt

type = <text variable, no debug info>

(gdb) p sqrt(4.0)

$3 = 0

(gdb)

Is it really possible that such a time proven tool like dbx can't invoke a function by function pointer? If so, I will indeed file a RFE.

DieterRupperta at 2007-7-28 17:57:21 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 10

> If so, I will indeed file a RFE.

Please, do.

As to missing sqrt die (debug info entry), I'll file a bug in an hour or so and post its ID here.

MaximKartasheva at 2007-7-28 17:57:21 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 11

Okay, bug 6580813 (external symbols declared in non-global namespace is not present in debug info) has been filed. It should become visible on bugs.sun.com in a day or so.

MaximKartasheva at 2007-7-28 17:57:21 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 12

It turns out that this is a bit different than it looks: dbx is indeed able to invoke functions invoked in this way correctly; dbx just fails to print a sensible return value.

I tried with the following small function:

#include <stdio.h>

int printme(double x) {

printf("This is %g\n",x);

return (int)2*x;

}

Compiling this without -g, linking this with some hello world program and invoking the function from dbx gives

(dbx) print ((int (*)(double))printme)(4.0)

This is 4

((int (*)(double)) printme)(4) = &(noname)(double) at 0x8

(dbx)

The line "This is 4" clearly indicates that the function has been invoked correctly. Just the printed return value is meaningless. In this case, it is even possible to construct expressions with the return value:

(dbx) print 5 + ((int (*)(double))printme)(4.0)

This is 4

5+((int (*)(double)) printme)(4) = 13

i.e. dbx "knows" the correct return value 8. This does, however, apparently not work with return values of type double (i.e. in the original sqrt-Example).

I have therefore submitted a bug report with bugs.sun.com; I will post the BugID when (and if) this has been accepted.

DieterRupperta at 2007-7-28 17:57:21 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 13

The last item became Bug Id 6584396.

DieterRupperta at 2007-7-28 17:57:21 > top of Java-index,Development Tools,Solaris and Linux Development Tools...