[Bug c++/26326] New: C++ trivial destructor support when calling function from GDB

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

[Bug c++/26326] New: C++ trivial destructor support when calling function from GDB

Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26326

            Bug ID: 26326
           Summary: C++ trivial destructor support when calling function
                    from GDB
           Product: gdb
           Version: 9.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c++
          Assignee: unassigned at sourceware dot org
          Reporter: moinakb001 at gmail dot com
  Target Milestone: ---

This problem is fundamentally one of small struct optimization and its
interaction with C++. The fundamental problem here is that GDB doesn't
recognize that C++ trivially destructible classes can become POD (Plain Old
Data, C structs - this applies to C as well as C++), which in turn can be
reclassified as INTEGER instead of MEMORY when the data is small enough (16B,
size of 2 x86_64 registers). We can prove this with the following C++ code:


struct small_struct{
    long long x[2];
};
struct small_struct small_test(int a){
    struct small_struct s{{a}};
    return s;
}
struct large_struct{
    long long x[3];
};
struct large_struct large_test(int a){
    struct large_struct s{{a}};
    return s;
}
class class_without_destructor{
    private:
    int x;
    public:
    class_without_destructor(int z): x(z){}
    ~class_without_destructor() = default;
};
class_without_destructor test_trivial_destructor(int p){
    class_without_destructor ret(p);
    return ret;
}
class class_with_destructor{
    private:
    int x;
    public:
    class_with_destructor(int z): x(z){}
    ~class_with_destructor(){}
};

class_with_destructor test_nontrivial_destructor(int p){
    class_with_destructor ret(p);
    return ret;
}


GDB has no trouble recognizing in small_test that it shouldn't pass anything
through rdi as the function will return values through rax and rdx, and it
recognizes as well that it does have to pass in a memory location through rdi
in large_test and in test_nontrivial_destructor:


(gdb) p/x small_test(1)
$1 = {x = {0x1, 0x0}}
(gdb) p/x large_test(2)
$2 = {x = {0x2, 0x0, 0x0}}
(gdb) p/x test_nontrivial_destructor(3)
$3 = {x = 0x3}


However, GDB does not work correctly with test_trivial_destructor. It thinks
that the program uses rdi values that it passes in to the function for storage
and thus shows the stale value from the previous test:


(gdb) p/x test_trivial_destructor(4)
$4 = {x = 0x3}


Relevant registers:


rsi            0x4      4
rdi            0x7ffffffedeb0   140737488281264


It shifts the argument, and passes the first argument in rsi, just as it does
in the nontrivial destructor case. This is because if doesn't recognize the
following C++ behavior regarding trivial destructors, and expects that the
values are passed back in memory through rdi. I'm not sure where the problem
is, but it seems related to
https://sourceware.org/bugzilla/show_bug.cgi?id=25054

--
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++/26326] C++ trivial destructor support when calling function from GDB

Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26326

Moinak Bhattacharyya <moinakb001 at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Version|9.1                         |9.2

--
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++/26326] C++ trivial destructor support when calling function from GDB

Sourceware - gdb-prs mailing list
In reply to this post by Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26326

Tom Tromey <tromey at sourceware dot org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |tromey at sourceware dot org
   Last reconfirmed|                            |2020-08-09
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |WAITING

--- Comment #1 from Tom Tromey <tromey at sourceware dot org> ---
When I try this with git gdb, it seems to work ok.

(gdb) p/x test_trivial_destructor(5)
$1 = {
  x = 0x5
}
(gdb) p test_trivial_destructor(97)
$2 = {
  x = 97
}


So, I tend to think this is fixed in git.
Can you try it?

--
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++/26326] C++ trivial destructor support when calling function from GDB

Sourceware - gdb-prs mailing list
In reply to this post by Sourceware - gdb-prs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26326

--- Comment #2 from Moinak Bhattacharyya <moinakb001 at gmail dot com> ---
I'm still getting the same error on git:

(gdb) p/x small_test(1)
$1 = {x = {0x1, 0x0}}
(gdb) p/x large_test(2)
$2 = {x = {0x2, 0x0, 0x0}}
(gdb) p/x test_nontrivial_destructor(3)
$3 = {x = 0x3}
(gdb) p/x test_trivial_destructor(4)
$4 = {x = 0x3}

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