From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 1413C3858D33; Tue, 24 Jan 2023 18:59:11 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1413C3858D33 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1674586751; bh=rWRzYWJ8HiaUza54ZiwzcnNahYJ9OhLBOZqbSAfkooc=; h=From:To:Subject:Date:From; b=aA/5ar6yH08qNyLkwhXfHRsnLFWXeGjk3isV5NLDnQqz1lsmcRN8p32hI7jGZzZSx nZ+pjd3GOExisfpfJlN/xZr4hIB2zVAItaD99pA5yJclgSZSUXgBWGcVko5lV6FQ39 TdYfflLWv9KflQpv5mhQM4O38RXUxyLaM6GOddvc= From: "ssbssa at sourceware dot 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 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gdb X-Bugzilla-Component: python X-Bugzilla-Version: HEAD X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: ssbssa at sourceware dot org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: unassigned at sourceware dot org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://sourceware.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://sourceware.org/bugzilla/show_bug.cgi?id=3D30044 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 pyt= hon 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 destru= ctor 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 af= ter 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/testsuit= e/gdb.python/py-pp-cast.c, line 22. > (gdb) r > Starting program: C:\gdb\build64\gdb-git-python3\gdb\testsuite\outputs\gd= b.python\py-pp-cast\py-pp-cast.exe >=20 > Breakpoint 1, break_function () at C:/src/repos/binutils-gdb.git/gdb/test= suite/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(), s= o 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 e= xp_opcode op) > res_val =3D value_cast (type, val); > } >=20 > + if (res_val =3D=3D val) > + res_val =3D value_copy (val); > + > result =3D 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 ma= rk 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 pyt= hon 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 no= rmal printing, which then crashed. The question for me is why are values released from all_values at all, is t= his done to reduce the used memory? --=20 You are receiving this mail because: You are on the CC list for the bug.=