mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-24 20:28:28 +08:00
[gdb/testsuite] test a function call by hand from pretty printer
The test case added here is testing the bug gdb/28856, where calling a function by hand from a pretty printer makes GDB crash. There are 6 mechanisms to trigger this crash in the current test, using the commands backtrace, up, down, finish, step and continue. Since the failure happens because of use-after-free (more details below) the tests will always have a chance of passing through sheer luck, but anecdotally they seem to fail all of the time. The reason GDB is crashing is a use-after-free problem. The above mentioned functions save a pointer to the current frame's information, then calls the pretty printer, and uses the saved pointer for different reasons, depending on the function. The issue happens because call_function_by_hand needs to reset the obstack to get the current frame, invalidating the saved pointer.
This commit is contained in:
53
gdb/testsuite/gdb.python/pretty-print-call-by-hand.c
Normal file
53
gdb/testsuite/gdb.python/pretty-print-call-by-hand.c
Normal file
@ -0,0 +1,53 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2022 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
struct mytype
|
||||
{
|
||||
char *x;
|
||||
};
|
||||
|
||||
void
|
||||
rec (int i)
|
||||
{
|
||||
if (i <= 0)
|
||||
return;
|
||||
rec (i-1);
|
||||
}
|
||||
|
||||
int
|
||||
f ()
|
||||
{
|
||||
rec (100);
|
||||
return 2;
|
||||
}
|
||||
|
||||
void
|
||||
g (struct mytype mt, int depth)
|
||||
{
|
||||
if (depth <= 0)
|
||||
return; /* TAG: final frame */
|
||||
g (mt, depth - 1); /* TAG: first frame */
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
struct mytype mt;
|
||||
mt.x = "hello world";
|
||||
g (mt, 10); /* TAG: outside the frame */
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user