Fix gdb.FinishBreakpoint when returning to an inlined function
Currently, when creating a gdb.FinishBreakpoint in a function called from an inline frame, it will never be hit: ``` (gdb) py fb=gdb.FinishBreakpoint() Temporary breakpoint 1 at 0x13f1917b4: file C:/src/repos/binutils-gdb.git/gdb/testsuite/gdb.python/py-finish-breakpoint.c, line 47. (gdb) c Continuing. Thread-specific breakpoint 1 deleted - thread 1 no longer in the thread list. [Inferior 1 (process 1208) exited normally] ``` The reason is that the frame_id of a breakpoint has to be the ID of a real frame, ignoring any inline frames. With this fixed, it's working correctly: ``` (gdb) py fb=gdb.FinishBreakpoint() Temporary breakpoint 1 at 0x13f5617b4: file C:/src/repos/binutils-gdb.git/gdb/testsuite/gdb.python/py-finish-breakpoint.c, line 47. (gdb) c Continuing. Breakpoint 1, increase_inlined (a=0x40fa5c) at C:/src/repos/binutils-gdb.git/gdb/testsuite/gdb.python/py-finish-breakpoint.c:47 (gdb) py print(fb.return_value) -8 ``` Approved-By: Tom Tromey <tom@tromey.com>
This commit is contained in:
parent
52e0b52e6f
commit
80ffe72264
@ -212,7 +212,8 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs)
|
||||
"be set on a dummy frame."));
|
||||
}
|
||||
else
|
||||
frame_id = get_frame_id (prev_frame);
|
||||
/* Get the real calling frame ID, ignoring inline frames. */
|
||||
frame_id = frame_unwind_caller_id (frame);
|
||||
}
|
||||
}
|
||||
catch (const gdb_exception &except)
|
||||
|
@ -34,6 +34,19 @@ void increase (int *a)
|
||||
increase_1 (a);
|
||||
}
|
||||
|
||||
int increase_2 (int *a)
|
||||
{
|
||||
*a += 10;
|
||||
return -8;
|
||||
}
|
||||
|
||||
inline void __attribute__((always_inline))
|
||||
increase_inlined (int *a)
|
||||
{
|
||||
increase_2 (a);
|
||||
*a += 5;
|
||||
}
|
||||
|
||||
int
|
||||
test_1 (int i, int j)
|
||||
{
|
||||
@ -85,6 +98,7 @@ int main (int argc, char *argv[])
|
||||
increase (&i);
|
||||
increase (&i);
|
||||
increase (&i);
|
||||
increase_inlined (&i);
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
|
@ -85,6 +85,31 @@ with_test_prefix "normal conditions" {
|
||||
"check FinishBP not allowed in main"
|
||||
}
|
||||
|
||||
#
|
||||
# Test FinishBreakpoint returning to an inlined function
|
||||
#
|
||||
|
||||
with_test_prefix "return to inlined function" {
|
||||
clean_restart ${testfile}
|
||||
gdb_load_shlib ${lib_sl}
|
||||
|
||||
gdb_test "source $python_file" "Python script imported.*" \
|
||||
"import python scripts"
|
||||
|
||||
if {![runto_main]} {
|
||||
return 0
|
||||
}
|
||||
|
||||
gdb_breakpoint "increase_2"
|
||||
gdb_test "continue" "Breakpoint .*at.*" "continue to the function to finish"
|
||||
|
||||
gdb_test "python finishbp_inline = MyFinishBreakpoint (gdb.parse_and_eval ('a'), gdb.newest_frame ())" \
|
||||
"Temporary breakpoint.*" "set FinishBreakpoint returning to inlined frame"
|
||||
gdb_test "continue" "MyFinishBreakpoint stop with.*return_value is: -8.*#0.*increase_inlined.*" \
|
||||
"check MyFinishBreakpoint hit"
|
||||
gdb_test "python print (finishbp_inline.return_value)" "-8.*" "check return_value"
|
||||
}
|
||||
|
||||
#
|
||||
# Test FinishBreakpoint with no debug symbol
|
||||
#
|
||||
|
Loading…
x
Reference in New Issue
Block a user