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

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

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

glaubitz at physik dot fu-berlin.de
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.
Reply | Threaded
Open this post in threaded view
|

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

glaubitz at physik dot fu-berlin.de
https://sourceware.org/bugzilla/show_bug.cgi?id=25054

--- Comment #1 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Tankut Baris Aktemur
<[hidden email]>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=099a6354dab7e74c990501929f383394fc8efd02

commit 099a6354dab7e74c990501929f383394fc8efd02
Author: Tankut Baris Aktemur <[hidden email]>
Date:   Fri Dec 20 17:43:06 2019 +0100

    infcall: handle pass-by-reference arguments appropriately

    If an aggregate argument is implicitly pass-by-reference, allocate a
    temporary object on the stack, initialize it via the copy constructor
    (if exists) or trivially by memcpy'ing.  Pass the reference of the
    temporary to the callee function.  After the callee returns, invoke
    the destructor of the temporary.

    gdb/ChangeLog:
    2019-12-20  Tankut Baris Aktemur  <[hidden email]>

        PR gdb/25054
        * infcall.c (call_function_by_hand_dummy): Update the argument-
        passing section for call-by-value parameters.
        (struct destructor_info): New struct.
        (call_destructors): New auxiliary function.

    Change-Id: I18fa5d0df814dfa0defe9e862a88a6dbf1d99d01

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

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

Sourceware - gdb-prs mailing list
In reply to this post by glaubitz at physik dot fu-berlin.de
https://sourceware.org/bugzilla/show_bug.cgi?id=25054

Moinak Bhattacharyya <moinakb001 at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |moinakb001 at gmail dot com

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