public inbox for gdb-prs@sourceware.org
help / color / mirror / Atom feed
From: "ssbssa at sourceware dot org" <sourceware-bugzilla@sourceware.org>
To: gdb-prs@sourceware.org
Subject: [Bug python/30044] New: Flawed logic when releasing values from all_values buffer
Date: Tue, 24 Jan 2023 18:59:10 +0000	[thread overview]
Message-ID: <bug-30044-4717@http.sourceware.org/bugzilla/> (raw)

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

            Bug ID: 30044
           Summary: Flawed logic when releasing values from all_values
                    buffer
           Product: gdb
           Version: HEAD
            Status: NEW
          Severity: normal
          Priority: P2
         Component: python
          Assignee: unassigned at sourceware dot org
          Reporter: ssbssa at sourceware dot org
  Target Milestone: ---

The root problem I encountered was because in a to_string function of a python
pretty printer some value was cast to the type it already had, which meant
value_cast() inside valpy_do_cast() simply returned the input value.

This value was also the mark point of scoped_value_mark free_values, and was
released from all_values by value_to_value_object(), which meant the destructor
of free_values cleared all of all_values (since the mark point was missing).

Any or all of the values that were before the mark point were still used after
the pretty printer finished, which lead to my original crash.

I've reduced this to the attached py-pp-cast.c and py-pp-cast-1.py, in gdb I
just did this:

> >\gdb\build64\gdb-git-python3\gdb\gdb.exe -q py-pp-cast.exe
> Reading symbols from py-pp-cast.exe...
> (gdb) source py-pp-cast-1.py
> (gdb) b break_function
> Breakpoint 1 at 0x401603: file C:/src/repos/binutils-gdb.git/gdb/testsuite/gdb.python/py-pp-cast.c, line 22.
> (gdb) r
> Starting program: C:\gdb\build64\gdb-git-python3\gdb\testsuite\outputs\gdb.python\py-pp-cast\py-pp-cast.exe
> 
> Breakpoint 1, break_function () at C:/src/repos/binutils-gdb.git/gdb/testsuite/gdb.python/py-pp-cast.c:22
> 22        return 0;
> (gdb) up
> #1  0x0134162d in main () at C:/src/repos/binutils-gdb.git/gdb/testsuite/gdb.python/py-pp-cast.c:34
> 34        return break_function();
> (gdb) info locals

Then it crashed, detailed crash info is in crash-1.html.

My idea was to simply make sure a new value is create in valpy_do_cast(), so it
will be after the mark point, preventing this problem:

> --- a/gdb/python/py-value.c
> +++ b/gdb/python/py-value.c
> @@ -820,6 +820,9 @@ valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op)
>           res_val = value_cast (type, val);
>         }
> 
> +      if (res_val == val)
> +        res_val = value_copy (val);
> +
>        result = value_to_value_object (res_val);
>      }
>    catch (const gdb_exception &except)

But this is really just a local workaround for a global problem.

My next idea was to change value_mark() that it always creates a new dummy
value entry for the mark point, making sure that no one can release this mark
point.
This fixed the original crash, but I came up with even simpler python code that
still crashed, see py-pp-cast-2.py and crash-2.html.
To reproduce in gdb, it's the same commands as before, but sourcing
py-pp-cast-2.py in the beginng instead.

The reason it crashed now was that the value returned by valpy_do_cast() was
before the mark point, released from all_values as before, and once the python
code was finished (when gdbpy_apply_val_pretty_printer() returned), it was
destroyed (since the python object had the last reference).
But since no pretty printing was done, gdb itself tried to access it for normal
printing, which then crashed.

The question for me is why are values released from all_values at all, is this
done to reduce the used memory?

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

             reply	other threads:[~2023-01-24 18:59 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-24 18:59 ssbssa at sourceware dot org [this message]
2023-01-24 19:00 ` [Bug python/30044] " ssbssa at sourceware dot org
2023-01-24 19:01 ` ssbssa at sourceware dot org
2023-01-24 19:01 ` ssbssa at sourceware dot org
2023-01-24 19:02 ` ssbssa at sourceware dot org
2023-01-24 19:02 ` ssbssa at sourceware dot org
2023-01-24 19:03 ` ssbssa at sourceware dot org
2023-01-24 19:04 ` ssbssa at sourceware dot org
2023-01-24 19:07 ` tromey at sourceware dot org
2023-01-30 22:16 ` tromey at sourceware dot org
2023-01-30 23:22 ` tromey at sourceware dot org
2023-01-31  1:46 ` tromey at sourceware dot org
2023-01-31  2:04 ` tromey at sourceware dot org
2023-01-31 18:29 ` ssbssa at sourceware dot org
2023-02-11  1:13 ` tromey at sourceware dot org
2023-02-27 22:56 ` cvs-commit at gcc dot gnu.org
2023-02-27 22:57 ` tromey at sourceware dot org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-30044-4717@http.sourceware.org/bugzilla/ \
    --to=sourceware-bugzilla@sourceware.org \
    --cc=gdb-prs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).