diff options
author | Pedro Alves <palves@redhat.com> | 2016-06-21 01:11:53 +0100 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2016-06-21 01:11:53 +0100 |
commit | 8980e177bb62ec64875b335cf8733b41f3aae2fd (patch) | |
tree | d524b3094ae34d1a5c6d5302f988f7da3ded1ccb /gdb/testsuite | |
parent | 26cde2cc30c25ba4d5666ea502db51ee6cb5b069 (diff) | |
download | gdb-8980e177bb62ec64875b335cf8733b41f3aae2fd.zip gdb-8980e177bb62ec64875b335cf8733b41f3aae2fd.tar.gz gdb-8980e177bb62ec64875b335cf8733b41f3aae2fd.tar.bz2 |
Push thread->control.command_interp to the struct thread_fsm
I noticed that if we step into an inline function, step_1 never
reaches proceed, and thus nevers sets the thread's
tp->control.command_interp. Because of that,
should_print_stop_to_console fails to determine that is should print
stop output to the console.
The fix is to set the thread's command_interp earlier. However, I
realized that we can move that field to the thread_fsm, given that its
lifetime is exactly the same as thread_fsm. So the patch plumbs all
fsms constructors to take the command interp and store it in the
thread_fsm.
We can see the fix in action, with e.g., the gdb.opt/inline-cmds.exp
test, and issuing a step when stopped at line 67:
&"s\n"
^running
*running,thread-id="all"
(gdb)
~"67\t result = func2 ();\n"
*stopped,reason="end-stepping-range",frame={addr="0x00000000004004d0",func="main",args=[],file="/home/pedro/gdb/mygit/src/gdb/testsuite/gdb.opt/inline-cmds.c",fullname="/home/pedro/gdb/mygit/src/gdb/testsuite/gdb.opt/inline-cmds.c",line="67"},thread-id="1",stopped-threads="all",core="0"
(gdb)
s
&"s\n"
^running
*running,thread-id="all"
(gdb)
+ ~"func2 () at /home/pedro/gdb/mygit/src/gdb/testsuite/gdb.opt/inline-cmds.c:67\n"
+ ~"67\t result = func2 ();\n"
*stopped,reason="end-stepping-range",frame={addr="0x00000000004004d0",func="func2",args=[],file="/home/pedro/gdb/mygit/src/gdb/testsuite/gdb.opt/inline-cmds.c",fullname="/home/pedro/gdb/mygit/src/gdb/testsuite/gdb.opt/inline-cmds.c",line="67"},thread-id="1",stopped-threads="all",core="0"
(gdb)
(The inline-cmds.exp command is adjusted to exercise this.)
(Due to the follow_fork change, this also fixes "next N" across a fork
with "set follow-fork child" with "set detach-on-fork on". Commands
that rely on internal breakpoints, like "finish" will still require
more work to migrate breakpoints etc. to the child thread.)
gdb/ChangeLog:
2016-06-21 Pedro Alves <palves@redhat.com>
* breakpoint.c (new_until_break_fsm): Add 'cmd_interp' parameter.
(until_break_fsm_should_stop, until_break_fsm_clean_up): Add
thread parameter.
(until_break_command): Pass command interpreter to thread fsm
ctor.
* cli/cli-interp.c (should_print_stop_to_console): Adjust.
* gdbthread.h (struct thread_control_state) <command_interp>:
Delete field.
* infcall.c (new_call_thread_fsm): Add 'cmd_interp' parameter.
Pass it down.
(call_thread_fsm_should_stop): Add thread parameter.
(call_function_by_hand_dummy): Pass command interpreter to thread
fsm ctor. Pass thread pointer to fsm clean up method.
* infcmd.c: Include interps.h.
(struct step_command_fsm) <thread>: Delete field.
(new_step_command_fsm): Add 'cmd_interp' parameter. Pass it down.
(step_command_fsm_prepare): Remove references to fsm's thread
field.
(step_1): Pass command interpreter to thread
fsm ctor. Pass thread pointer to fsm clean up method.
(step_command_fsm_should_stop, step_command_fsm_clean_up): Add
thread parameter and use it.
(new_until_next_fsm): Add 'cmd_interp' parameter. Pass it down.
(until_next_fsm_should_stop, until_next_fsm_clean_up): Add thread
parameter and use it.
(until_next_command): Pass command interpreter to thread fsm ctor.
(struct finish_command_fsm) <thread>: Delete field.
(finish_command_fsm_ops): Add NULL slot for should_notify_stop.
(new_finish_command_fsm): Add 'cmd_interp' parameter and pass it
down. Remove thread parameter and adjust.
(finish_command_fsm_should_stop, finish_command_fsm_clean_up): Add
thread parameter and use it.
(finish_command): Pass command interpreter to thread fsm ctor.
Don't pass thread.
* infrun.c (follow_fork): Move thread fsm to child fork instead of
command interpreter, only.
(clear_proceed_status_thread): Remove reference to command_interp.
(proceed): Don't record the thread's command interpreter.
(clean_up_just_stopped_threads_fsms): Pass thread to fsm clean_up
method.
(fetch_inferior_event): Pass thread to fsm should_stop method.
* thread-fsm.c (thread_fsm_ctor): Add 'cmd_interp' parameter.
Store it.
(thread_fsm_clean_up, thread_fsm_should_stop): Add thread
parameter and pass it down.
* thread-fsm.h (struct thread_fsm) <command_interp>: New field.
(struct thread_fsm_ops) <clean_up, should_stop>: Add thread
parameter.
(thread_fsm_ctor): Add 'cmd_interp' parameter.
(thread_fsm_clean_up, thread_fsm_should_stop): Add thread
parameter.
* thread.c (thread_cancel_execution_command): Pass thread to
thread fsm clean_up method.
gdb/testsuite/ChangeLog:
2016-06-21 Pedro Alves <palves@redhat.com>
* gdb.opt/inline-cmds.c: Add "set mi break here" marker.
* gdb.opt/inline-cmds.exp: Add MI tests.
Diffstat (limited to 'gdb/testsuite')
-rw-r--r-- | gdb/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/testsuite/gdb.opt/inline-cmds.c | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.opt/inline-cmds.exp | 62 |
3 files changed, 68 insertions, 1 deletions
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 3bd499a..9ad93eb 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2016-06-21 Pedro Alves <palves@redhat.com> + * gdb.opt/inline-cmds.c: Add "set mi break here" marker. + * gdb.opt/inline-cmds.exp: Add MI tests. + +2016-06-21 Pedro Alves <palves@redhat.com> + * gdb.gdb/selftest.exp (do_steps_and_nexts): Add new regexp. 2016-06-21 Pedro Alves <palves@redhat.com> diff --git a/gdb/testsuite/gdb.opt/inline-cmds.c b/gdb/testsuite/gdb.opt/inline-cmds.c index 20e1d0b..59631d7 100644 --- a/gdb/testsuite/gdb.opt/inline-cmds.c +++ b/gdb/testsuite/gdb.opt/inline-cmds.c @@ -61,7 +61,7 @@ int main (void) int val; x = 7; - y = 8; + y = 8; /* set mi break here */ result = func1 (); result = func2 (); diff --git a/gdb/testsuite/gdb.opt/inline-cmds.exp b/gdb/testsuite/gdb.opt/inline-cmds.exp index d57a333..684f4dd 100644 --- a/gdb/testsuite/gdb.opt/inline-cmds.exp +++ b/gdb/testsuite/gdb.opt/inline-cmds.exp @@ -13,6 +13,9 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +load_lib mi-support.exp +set MIFLAGS "-i=mi" + standard_testfile .c inline-markers.c if {[prepare_for_testing $testfile.exp $testfile \ @@ -315,3 +318,62 @@ gdb_test "up" "#3 .*outer_inline2.*" "up to outer_inline2" gdb_test "info frame" ".*inlined into frame.*" "outer_inline2 inlined" gdb_test "up" "#4 main.*" "up from outer_inline2" gdb_test "info frame" ".*\n caller of frame.*" "main not inlined" + +gdb_exit + +# Send a CLI "step" command over MI. CLI_OUTPUT_RE is a regexp that +# matches the expected CLI output. MESSAGE is used as test message. + +proc mi_cli_step {cli_output_re message} { + global mi_gdb_prompt + global srcfile + global decimal + + send_gdb "interpreter-exec console \"step\"\n" + gdb_expect { + -re "\\^running\r\n\\*running,thread-id=\"all\"\r\n${mi_gdb_prompt}${cli_output_re}" { + pass $message + } + timeout { + fail "$message (timeout)" + } + eof { + fail "$message (eof)" + } + } + + # mi_expect_stop handles "set mi-async on/off" differences. + mi_expect_stop "end-stepping-range" "\[^\r\n\]*" "" ".*$srcfile" "$decimal" \ + "" "got *stopped for $message" +} + +# Test that stepping into an inlined function with the CLI "step" +# command run while the top interpreter is MI results in the expected +# CLI output sent to MI's console. +with_test_prefix "mi" { + if [mi_gdb_start] { + continue + } + mi_gdb_load ${binfile} + mi_runto main + + set line_number [gdb_get_line_number "set mi break here"] + mi_gdb_test "-break-insert ${srcfile}:${line_number}" \ + {\^done,bkpt=.number="2",type="breakpoint".*\}} \ + "set breakpoint" + + mi_execute_to "exec-continue" "breakpoint-hit" "main" "" ".*" ".*" \ + { "" "disp=\"keep\"" } "breakpoint hit" + + incr line_number 2 + + # Step to the line that does an inline call. + set re "~\"$line_number\\\\t result = func1 \\(\\);\\\\n\"\r\n" + mi_cli_step "${re}" "step to inline call" + + # Step into the inlined function. + set re [multi_line \ + "~\"func1 \\(\\) at .*$srcfile:$decimal\\\\n\"" \ + "~\"$decimal\\\\t bar \\(\\);\\\\n\"\r\n"] + mi_cli_step "${re}" "step into inline call" +} |