2

EDIT: I am on Linux Mint 18.3 (Ubuntu 16.04) X64

I have read in a number of other questions that the best way to execute arbitrary functions in gdb is to ensure the input / output variables are cast properly.

The expression p ((double(*)())floor)(2.12) yields $1 = 2.1200000000000001 as does the expression p ((double(*)())ceil)(2.12)

but the other functions in the math library seem to work, e.g. p ((double(*)())fmod)(12.,5.) gives 2; p ((double(*)())sqrt)(64.) gives 8. p ((double(*)())pow)(2.,2.) gives 4 as expected.

So my question is what is the difference for the double / ceil functions which don't give the right value. It also appears the trigonometrical functions also don't return the proper values for some reason. They all seem to have the same or similar function signatures, so I am confused what is going wrong.

The math.h c library is the header being included, but the code is also linking to c++ libraries - not sure if that would make a difference.

Stev_k
  • 2,118
  • 3
  • 22
  • 36
  • 3
    Works for me. Can you specify your platform, and a sample program that reproduces the problem? – jxh Aug 27 '18 at 22:32
  • 2
    **NOTE**: This might work properly for C++ but it is **error prone in C**. This is because C++ supports overloading and the casting should select the proper overloaded function... however, in C the casting does nothing except **hide possible errors**. – Myst Aug 27 '18 at 23:05
  • 4
    Try `p ((double(*)(double))ceil)(2.12)`. With `p ((double(*)())ceil)(2.12)`, code incorrectly calls the function. With `p ((double(*)())fmod)(12.,5.)`, you are just "lucky". – chux - Reinstate Monica Aug 28 '18 at 00:18
  • 2
    @Myst: Well, even for C++, it is not quite right, since the cast says the function takes no arguments. – jxh Aug 28 '18 at 00:19
  • https://stackoverflow.com/questions/5122570/why-does-gdb-evaluate-sqrt3-to-0 maybe same issue – Matthew Fisher Aug 28 '18 at 00:45
  • `p floor(2.12)` works perfectly well. Don't know why you need a cast at all. What is it supposed prevent? (Apart from finishing a 3 second job in 3 seconds, that is). – n. m. could be an AI Aug 28 '18 at 15:10
  • @n.m. The math library symbols may be stripped. – jxh Aug 28 '18 at 16:56
  • @jxh it is most definitely stripped on my system, bit this doesn't affect anything. If it's statically linked and the executable is then stropped, this will not work, but what do you want to achieve by running a stripped executable in gdb in the first place? – n. m. could be an AI Aug 28 '18 at 16:57
  • @n.m. Perhaps you have installed debuginfo for the C runtime on your system? – jxh Aug 28 '18 at 17:09
  • @jxh i'm sorry but that makes no sense whatsoever. If the linker and the dynamic loader are able to find `floor` by name in libm.so, then gdb is also perfectly capable of this feat. No need to invoke magic or conspiracy theories. Just realise that there are symbols in *stripped* shared libraries (otherwise they would be totally unusable). Try `nm -D libm.so` (or whatever the real name is). – n. m. could be an AI Aug 28 '18 at 17:15
  • @n.m. On my system, gdb only knew the symbol existed. It didn't have any type info. I extended my test with `auto f = floor;` and discovered that the pointer needed to be resolved through the PLT. – jxh Aug 28 '18 at 18:04
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/178955/discussion-between-n-m-and-jxh). – n. m. could be an AI Aug 28 '18 at 18:09

1 Answers1

1

This:

p ((double(*)())floor)(2.12)

asks GDB to call a function floor which takes no arguments.

Since on many platforms (including Linux/x86_64) argument passing depends on the type of the argument (integer parameters are passed in RDI, RSI, etc. double parameters in XMM0, XMM1, etc.), you must tell GDB what type of parameter the function expects (unless libm debug info is present, in which case no cast would be necessary). Try

p ((double(*)(double))floor)(2.12)
Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • This didn't work on its own, I had to upgrade to GCC 8.x for anything to work as expected, as discussed in the chat in the question. – Stev_k Aug 28 '18 at 22:56