Bug 27757

Summary: -var-list-children coredump
Product: gdb Reporter: Elmot <ilia.motornyi>
Component: varobjAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: ahmedsayeed1982, ampva300, donipah907, focixujo, gexed96894, glassmtech, gulsenenginar, ilia.motornyi, jaj058080, joyruth102798, kimolsun2020, mark, mehmetgelisin, okedf, phillipsaeverett84, progonsaytu, simark, svitvitraga, tesaso8237, tromey
Priority: P2    
Version: 10.1   
Target Milestone: 10.2   
Host: win 64 Target: win 64
Build: Last reconfirmed: 2021-04-21 00:00:00
Attachments: main.c
gdb transcript
compiled binary
Ubuntu/x86_64 the bug reproduction

Description Elmot 2021-04-20 08:18:50 UTC
Created attachment 13387 [details]
main.c

Coredump report from our customer
GDB 10.1
GCC 9.2
Comment 1 Elmot 2021-04-20 08:19:31 UTC
Created attachment 13388 [details]
gdb transcript
Comment 2 Elmot 2021-04-20 08:20:38 UTC
Created attachment 13389 [details]
compiled binary
Comment 3 Elmot 2021-04-20 08:21:47 UTC
-var-list-children coredumps GDB
Comment 4 Tom Tromey 2021-04-21 20:03:39 UTC
If I set a breakpoint at line 13 and run, then this command

0-interpreter-exec --thread 1 --frame 0 mi2 "-var-create var1_b * \"b\""

causes a crash for me.
Comment 5 Tom Tromey 2021-04-21 20:10:23 UTC
Now I think that the crash I see is new & different
from the one reported in this bug.
Comment 6 Tom Tromey 2021-04-21 20:13:54 UTC
... but now I see this new crash in 10.x, so I think we're in trouble.
Comment 7 Tom Tromey 2021-04-21 20:15:55 UTC
FWIW if I remove the "interpreter-exec" wrapper stuff (which is
a bit surprising to see...), I can't reproduce the original bug
on Linux anyway.  I didn't try Windows.
Comment 8 Elmot 2021-04-21 20:44:31 UTC
Might the crash be related to some pretty printer?
Comment 9 Simon Marchi 2021-04-21 21:13:38 UTC
(In reply to Tom Tromey from comment #4)
> If I set a breakpoint at line 13 and run, then this command
> 
> 0-interpreter-exec --thread 1 --frame 0 mi2 "-var-create var1_b * \"b\""
> 
> causes a crash for me.

What interpreter do you start GDB with?  If I start it with -i=mi (equivalent to -i=mi3), I get a crash too.  So it seems GDB doesn't like that you use interpreter-exec with a different MI interpreter than the current one.
Comment 10 Simon Marchi 2021-04-21 21:16:25 UTC
(In reply to Elmot from comment #0)
> Created attachment 13387 [details]
> main.c
> 
> Coredump report from our customer
> GDB 10.1
> GCC 9.2

I would like to investigate this, especially since it hits an assert that I introduced (it may be a bug introduced by my patch, or my patch might just uncover an existing bug).  But I am really not nicely set up to develop on Windows, so it will take some time.  If you find a way to reproduce on Linux, please share!
Comment 11 Elmot 2021-04-22 07:07:29 UTC
In fact the original reporter (a CLion user) run into the bug on Linux
CLion works as a gdb frontend, so that's why -mi is used and some commands look not so humanoid
https://youtrack.jetbrains.com/issue/CPP-24874

I have reproduced that on Win, that's why I did not report the OS.
I'll try to reproduce the same under Linux or at least under WSL.
Comment 12 Elmot 2021-04-22 08:15:08 UTC
Created attachment 13395 [details]
Ubuntu/x86_64 the bug reproduction

Here you are, apparently gdb crashes in pretty-printers
Comment 13 Simon Marchi 2021-04-22 13:50:21 UTC
(In reply to Elmot from comment #12)
> Created attachment 13395 [details]
> Ubuntu/x86_64 the bug reproduction
> 
> Here you are, apparently gdb crashes in pretty-printers

Thanks, I can reproduce with this.

(gdb) 
-var-list-children --all-values "var1_b" -1 -1
~"/home/simark/src/binutils-gdb/gdb/gdbtypes.h:435: internal-error: LONGEST dynamic_prop::const_val() const: Assertion `m_kind == PROP_CONST' failed.\nA problem internal to GDB has been detected,\nfurther debugging may prove unreliable.\nQuit this debugging session? (y or n) "
Comment 14 Simon Marchi 2021-04-22 14:13:41 UTC
Ok, so the problem is quite simple: the flexible array member strikes again.

The reproducer can be simplified as:

struct foo {
    int len;
    int items[];
};

struct foo *p;

int main() {
    return 0;
}


and:

$ ./gdb -q -nx --data-directory=data-directory ./test -ex 'python gdb.parse_and_eval("p").type.target()["items"].type.range()'
Reading symbols from ./test...
/home/simark/src/binutils-gdb/gdb/gdbtypes.h:435: internal-error: LONGEST dynamic_prop::const_val() const: Assertion `m_kind == PROP_CONST' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Quit this debugging session? (y or n) 

A similar fix with a test case was added here:

https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=5b56203a7cadd545b33713e98e274e582242e090

But a similar thing needs to be done for Python, I'll prepare a patch.
Comment 15 Sourceware Commits 2021-04-22 19:02:54 UTC
The master branch has been updated by Simon Marchi <simark@sourceware.org>:

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

commit e25d6d93c4a0d597da2521c2c38cb1ce6e51feb8
Author: Simon Marchi <simon.marchi@polymtl.ca>
Date:   Thu Apr 22 15:01:28 2021 -0400

    gdb: fix getting range of flexible array member in Python
    
    As reported in bug 27757, we get an internal error when doing:
    
        $ cat test.c
        struct foo {
            int len;
            int items[];
        };
    
        struct foo *p;
    
        int main() {
            return 0;
        }
        $ gcc test.c -g -O0 -o test
        $ ./gdb -q -nx --data-directory=data-directory ./test -ex 'python gdb.parse_and_eval("p").type.target()["items"].type.range()'
        Reading symbols from ./test...
        /home/simark/src/binutils-gdb/gdb/gdbtypes.h:435: internal-error: LONGEST dynamic_prop::const_val() const: Assertion `m_kind == PROP_CONST' failed.
        A problem internal to GDB has been detected,
        further debugging may prove unreliable.
        Quit this debugging session? (y or n)
    
    This is because the Python code (typy_range) blindly reads the high
    bound of the type of `items` as a constant value.  Since it is a
    flexible array member, it has no high bound, the property is undefined.
    Since commit 8c2e4e0689 ("gdb: add accessors to struct dynamic_prop"),
    the getters check that you are not getting a property value of the wrong
    kind, so this causes a failed assertion.
    
    Fix it by checking if the property is indeed a constant value before
    accessing it as such.  Otherwise, use 0.  This restores the previous GDB
    behavior: because the structure was zero-initialized, this is what was
    returned before.  But now this behavior is explicit and not accidental.
    
    Add a test, gdb.python/flexible-array-member.exp, that is derived from
    gdb.base/flexible-array-member.exp.  It tests the same things, but
    through the Python API.  It also specifically tests getting the range
    from the various kinds of flexible array member types (AFAIK it wasn't
    possible to do the equivalent through the CLI).
    
    gdb/ChangeLog:
    
            PR gdb/27757
            * python/py-type.c (typy_range): Check that bounds are constant
            before accessing them as such.
            * guile/scm-type.c (gdbscm_type_range): Likewise.
    
    gdb/testsuite/ChangeLog:
    
            PR gdb/27757
            * gdb.python/flexible-array-member.c: New test.
            * gdb.python/flexible-array-member.exp: New test.
            * gdb.guile/scm-type.exp (test_range): Add test for flexible
            array member.
            * gdb.guile/scm-type.c (struct flex_member): New.
            (main): Use it.
    
    Change-Id: Ibef92ee5fd871ecb7c791db2a788f203dff2b841
Comment 16 Sourceware Commits 2021-04-22 19:05:40 UTC
The gdb-10-branch branch has been updated by Simon Marchi <simark@sourceware.org>:

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

commit a2602365509739da6f611d1668eebdb8ea1bffec
Author: Simon Marchi <simon.marchi@polymtl.ca>
Date:   Thu Apr 22 15:05:18 2021 -0400

    gdb: fix getting range of flexible array member in Python
    
    As reported in bug 27757, we get an internal error when doing:
    
        $ cat test.c
        struct foo {
            int len;
            int items[];
        };
    
        struct foo *p;
    
        int main() {
            return 0;
        }
        $ gcc test.c -g -O0 -o test
        $ ./gdb -q -nx --data-directory=data-directory ./test -ex 'python gdb.parse_and_eval("p").type.target()["items"].type.range()'
        Reading symbols from ./test...
        /home/simark/src/binutils-gdb/gdb/gdbtypes.h:435: internal-error: LONGEST dynamic_prop::const_val() const: Assertion `m_kind == PROP_CONST' failed.
        A problem internal to GDB has been detected,
        further debugging may prove unreliable.
        Quit this debugging session? (y or n)
    
    This is because the Python code (typy_range) blindly reads the high
    bound of the type of `items` as a constant value.  Since it is a
    flexible array member, it has no high bound, the property is undefined.
    Since commit 8c2e4e0689 ("gdb: add accessors to struct dynamic_prop"),
    the getters check that you are not getting a property value of the wrong
    kind, so this causes a failed assertion.
    
    Fix it by checking if the property is indeed a constant value before
    accessing it as such.  Otherwise, use 0.  This restores the previous GDB
    behavior: because the structure was zero-initialized, this is what was
    returned before.  But now this behavior is explicit and not accidental.
    
    Add a test, gdb.python/flexible-array-member.exp, that is derived from
    gdb.base/flexible-array-member.exp.  It tests the same things, but
    through the Python API.  It also specifically tests getting the range
    from the various kinds of flexible array member types (AFAIK it wasn't
    possible to do the equivalent through the CLI).
    
    gdb/ChangeLog:
    
            PR gdb/27757
            * python/py-type.c (typy_range): Check that bounds are constant
            before accessing them as such.
            * guile/scm-type.c (gdbscm_type_range): Likewise.
    
    gdb/testsuite/ChangeLog:
    
            PR gdb/27757
            * gdb.python/flexible-array-member.c: New test.
            * gdb.python/flexible-array-member.exp: New test.
            * gdb.guile/scm-type.exp (test_range): Add test for flexible
            array member.
            * gdb.guile/scm-type.c (struct flex_member): New.
            (main): Use it.
    
    Change-Id: Ibef92ee5fd871ecb7c791db2a788f203dff2b841
Comment 17 Simon Marchi 2021-04-22 19:08:43 UTC
Marking as fixed, but if you could give it a try to make sure your use case now works well, it would be appreciated.
Comment 18 Elmot 2021-04-23 06:11:32 UTC
That was fast:)
Thanks, we'll try to test
Comment 19 Tom Tromey 2021-04-23 15:22:33 UTC
See bug #27770 for the interpreter-exec crasher.
Comment 20 Ahmed Sayeed 2021-06-27 17:44:00 UTC Comment hidden (spam)
Comment 21 Madison Wilson 2021-08-09 09:38:52 UTC Comment hidden (spam)
Comment 22 Joe Anderson 2021-08-17 02:04:31 UTC Comment hidden (spam)
Comment 23 Joe Anderson 2021-08-17 02:05:17 UTC Comment hidden (spam)
Comment 24 john 2021-08-24 19:51:41 UTC Comment hidden (spam)
Comment 25 james rohan 2021-09-02 11:06:18 UTC Comment hidden (spam)
Comment 26 Kim Olsun 2021-09-05 07:35:50 UTC Comment hidden (spam)
Comment 27 james robin 2021-09-06 09:08:30 UTC Comment hidden (spam)
Comment 29 Mehmet gelisin 2021-09-10 19:37:26 UTC Comment hidden (spam)
Comment 30 Gulsen Engin 2021-10-09 11:00:46 UTC Comment hidden (spam)
Comment 31 svitvitraga 2021-10-09 17:45:00 UTC Comment hidden (spam)
Comment 32 progonsaytu 2021-10-19 07:13:32 UTC Comment hidden (spam)
Comment 33 jaj058080 2021-10-20 09:21:57 UTC Comment hidden (spam)
Comment 34 glassmtech 2021-10-24 10:01:31 UTC Comment hidden (spam)
Comment 35 tesaso8237@funboxcn.com 2021-11-13 19:34:32 UTC Comment hidden (spam)
Comment 36 gexed96894 2021-11-22 06:48:17 UTC Comment hidden (spam)
Comment 37 Scorpia 2021-11-25 11:39:40 UTC Comment hidden (spam)