[Bug c++/25054] New: GDB passes incorrect values for call-by-value parameters when infcall'ing C++ functions

tankut.baris.aktemur at intel dot com sourceware-bugzilla@sourceware.org
Wed Oct 2 08:42:00 GMT 2019


https://sourceware.org/bugzilla/show_bug.cgi?id=25054

            Bug ID: 25054
           Summary: GDB passes incorrect values for call-by-value
                    parameters when infcall'ing C++ functions
           Product: gdb
           Version: HEAD
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c++
          Assignee: unassigned at sourceware dot org
          Reporter: tankut.baris.aktemur at intel dot com
  Target Milestone: ---

Consider the sample C++ program below where we have two classes, Custom and
Defaulted, and two functions that have call-by-value arguments of types Custom
and Defaulted, respectively.

~~~
#include <iostream>

class Custom {
public:
  Custom () { x = 10; }
  Custom (const Custom &arg) { x = 20; }
  int x;
};

class Defaulted {
public:
  Defaulted () { x = 30; }
  Defaulted (const Defaulted &arg) = default;
  int x;
};

void cbv_custom (Custom c) {
  c.x += 1;
  std::cout << c.x << std::endl;
}

void cbv_defaulted (Defaulted d) {
  d.x += 1;
  std::cout << d.x << std::endl;
}

int main () {
  Custom custom;
  Defaulted def;

  cbv_custom (custom);
  cbv_defaulted (def);

  return 0;
}
~~~

"Custom" has a user-defined copy-constructor.  For this reason it is a
non-trivial type and should be passed implicitly by reference.  "Defaulted" is
a trivial type and should be passed by value.

~~~
$ gdb -q ./sample
Reading symbols from ./sample...
(gdb) b 38
Breakpoint 1 at 0x1276: file sample.cpp, line 38.
(gdb) run
Starting program: /path/to/sample
21
31

Breakpoint 1, main () at sample.cpp:38
38        return 0;
(gdb) p custom
$1 = {x = 10}
(gdb) p def
$2 = {x = 30}
~~~

Let us now call cbv_custom. The expected output is 21.

~~~
(gdb) p cbv_custom(custom)
11
$3 = void
(gdb) p custom
$4 = {x = 11}
~~~

Here, GDB should have created a clone of the 'custom' object via the copy ctor
and passed that clone to the function. However, GDB passed the 'custom' object
itself, even without creating a naive copy.

Let's now call the cbv_defaulted function. The expected output is 31.

~~~
(gdb) p cbv_defaulted(def)
-11295
$5 = void
~~~

The return value seems like garbage at first sight, but it's not.

~~~
(gdb) p/x -11295
$6 = 0xffffd3e1
(gdb) p &def
$7 = (Defaulted *) 0x7fffffffd3e0
~~~

Here, GDB incorrectly inferred that Defaulted is non-trivial. Hence, it decided
to pass the reference of the 'def' object as the argument, but it should've
passed the argument by value.

A set of patches that addresses this problem and its vicinity is available at
https://sourceware.org/ml/gdb-patches/2019-06/msg00517.html

-- 
You are receiving this mail because:
You are on the CC list for the bug.


More information about the Gdb-prs mailing list