diff options
author | Pedro Alves <palves@redhat.com> | 2014-03-18 17:50:28 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2014-03-18 17:50:28 +0000 |
commit | 0c7e1a4602a41a1caf637823f67948be31d27732 (patch) | |
tree | decd909f1ca080aec0ad5dbc0d77a717cfb50aba | |
parent | a52e6fd34add3dbf267ac78e4d7912a0a3f65ece (diff) | |
download | gdb-0c7e1a4602a41a1caf637823f67948be31d27732.zip gdb-0c7e1a4602a41a1caf637823f67948be31d27732.tar.gz gdb-0c7e1a4602a41a1caf637823f67948be31d27732.tar.bz2 |
PR gdb/13860: make "-exec-foo"'s MI output equal to "foo"'s MI output.
Part of PR gdb/13860 is about the mi-solib.exp test's output being
different in sync vs async modes.
sync:
>./gdb -nx -q ./testsuite/gdb.mi/solib-main -ex "set stop-on-solib-events 1" -ex "set target-async off" -i=mi
=thread-group-added,id="i1"
~"Reading symbols from /home/pedro/gdb/mygit/build/gdb/testsuite/gdb.mi/solib-main..."
~"done.\n"
(gdb)
&"start\n"
~"Temporary breakpoint 1 at 0x400608: file ../../../src/gdb/testsuite/gdb.mi/solib-main.c, line 21.\n"
=breakpoint-created,bkpt={number="1",type="breakpoint",disp="del",enabled="y",addr="0x0000000000400608",func="main",file="../../../src/gdb/testsuite/gdb.mi/solib-main.c",fullname="/home/pedro/gdb/mygit/src/gdb/testsuite/gdb.mi/solib-main.c",line="21",times="0",original-location="main"}
~"Starting program: /home/pedro/gdb/mygit/build/gdb/testsuite/gdb.mi/solib-main \n"
=thread-group-started,id="i1",pid="17724"
=thread-created,id="1",group-id="i1"
^running
*running,thread-id="all"
(gdb)
=library-loaded,id="/lib64/ld-linux-x86-64.so.2",target-name="/lib64/ld-linux-x86-64.so.2",host-name="/lib64/ld-linux-x86-64.so.2",symbols-loaded="0",thread-group="i1"
~"Stopped due to shared library event (no libraries added or removed)\n"
*stopped,reason="solib-event",frame={addr="0x000000379180f990",func="_dl_debug_state",args=[],from="/lib64/ld-linux-x86-64.so.2"},thread-id="1",stopped-threads="all",core="3"
(gdb)
async:
>./gdb -nx -q ./testsuite/gdb.mi/solib-main -ex "set stop-on-solib-events 1" -ex "set target-async on" -i=mi
=thread-group-added,id="i1"
~"Reading symbols from /home/pedro/gdb/mygit/build/gdb/testsuite/gdb.mi/solib-main..."
~"done.\n"
(gdb)
start
&"start\n"
~"Temporary breakpoint 1 at 0x400608: file ../../../src/gdb/testsuite/gdb.mi/solib-main.c, line 21.\n"
=breakpoint-created,bkpt={number="1",type="breakpoint",disp="del",enabled="y",addr="0x0000000000400608",func="main",file="../../../src/gdb/testsuite/gdb.mi/solib-main.c",fullname="/home/pedro/gdb/mygit/src/gdb/testsuite/gdb.mi/solib-main.c",line="21",times="0",original-location="main"}
~"Starting program: /home/pedro/gdb/mygit/build/gdb/testsuite/gdb.mi/solib-main \n"
=thread-group-started,id="i1",pid="17729"
=thread-created,id="1",group-id="i1"
^running
*running,thread-id="all"
=library-loaded,id="/lib64/ld-linux-x86-64.so.2",target-name="/lib64/ld-linux-x86-64.so.2",host-name="/lib64/ld-linux-x86-64.so.2",symbols-loaded="0",thread-group="i1"
(gdb)
*stopped,reason="solib-event",thread-id="1",stopped-threads="all",core="1"
For now, let's focus only on the *stopped event. We see that the
async output is missing frame info. And this causes a test failure in
async mode, as "mi_expect_stop solib-event" wants to see the frame
info.
However, if we compare the event output when a real MI execution
command is used, compared to a CLI command (e.g., run vs -exec-run,
next vs -exec-next, etc.), we see:
>./gdb -nx -q ./testsuite/gdb.mi/solib-main -ex "set stop-on-solib-events 1" -ex "set target-async off" -i=mi
=thread-group-added,id="i1"
~"Reading symbols from /home/pedro/gdb/mygit/build/gdb/testsuite/gdb.mi/solib-main..."
~"done.\n"
(gdb)
r
&"r\n"
~"Starting program: /home/pedro/gdb/mygit/build/gdb/testsuite/gdb.mi/solib-main \n"
=thread-group-started,id="i1",pid="17751"
=thread-created,id="1",group-id="i1"
^running
*running,thread-id="all"
(gdb)
=library-loaded,id="/lib64/ld-linux-x86-64.so.2",target-name="/lib64/ld-linux-x86-64.so.2",host-name="/lib64/ld-linux-x86-64.so.2",symbols-loaded="0",thread-group="i1"
~"Stopped due to shared library event (no libraries added or removed)\n"
*stopped,reason="solib-event",frame={addr="0x000000379180f990",func="_dl_debug_state",args=[],from="/lib64/ld-linux-x86-64.so.2"},thread-id="1",stopped-threads="all",core="3"
(gdb)
-exec-run
=thread-exited,id="1",group-id="i1"
=thread-group-exited,id="i1"
=library-unloaded,id="/lib64/ld-linux-x86-64.so.2",target-name="/lib64/ld-linux-x86-64.so.2",host-name="/lib64/ld-linux-x86-64.so.2",thread-group="i1"
=thread-group-started,id="i1",pid="17754"
=thread-created,id="1",group-id="i1"
^running
*running,thread-id="all"
(gdb)
=library-loaded,id="/lib64/ld-linux-x86-64.so.2",target-name="/lib64/ld-linux-x86-64.so.2",host-name="/lib64/ld-linux-x86-64.so.2",symbols-loaded="0",thread-group="i1"
*stopped,reason="solib-event",thread-id="1",stopped-threads="all",core="1"
=thread-selected,id="1"
(gdb)
As seen above, with MI commands, the *stopped event _doesn't_ have
frame info. This is because normal_stop, as commanded by the result
of bpstat_print, skips printing frame info in this case (it's an
"event", not a "breakpoint"), and when the interpreter is MI,
mi_on_normal_stop skips calling print_stack_frame, as the normal_stop
call was already done with the MI uiout. This explains why the async
output is different even with a CLI command. Its because in async
mode, the mi_on_normal_stop path is always taken; it is always reached
with the MI uiout, because the stop is handled from the event loop,
instead of from within `proceed -> wait_for_inferior -> normal_stop'
with the interpreter overridden, as in sync mode.
This patch fixes the issue by making all cases output the same
*stopped event, by factoring out the print code from normal_stop, and
using it from mi_on_normal_stop as well. I chose the *stopped output
without a frame, mainly because that is what you already get if you
use MI execution commands, the commands frontends are supposed to use
(except when implementing a console). This patch makes it simpler to
tweak the MI output differently if desired, as we only have to change
the centralized print_stop_event (taking into account whether the
uiout is MI-like), and all different modes will change accordingly.
Tested on x86_64 Fedora 17, no regressions. The mi-solib.exp test no
longer fails in async mode with this patch, so the patch removes the
kfail.
2014-03-18 Pedro Alves <palves@redhat.com>
PR gdb/13860
* inferior.h (print_stop_event): Declare.
* infrun.c (print_stop_event): New, factored out from ...
(normal_stop): ... this.
* mi/mi-interp.c (mi_on_normal_stop): Use print_stop_event instead
of bpstat_print/print_stack_frame.
2014-03-18 Pedro Alves <palves@redhat.com>
PR gdb/13860
* gdb.mi/mi-solib.exp: Remove gdb/13860 kfail.
* lib/mi-support.exp (mi_expect_stop): Add special handling for
solib-event.
-rw-r--r-- | gdb/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/inferior.h | 2 | ||||
-rw-r--r-- | gdb/infrun.c | 118 | ||||
-rw-r--r-- | gdb/mi/mi-interp.c | 3 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/testsuite/gdb.mi/mi-solib.exp | 4 | ||||
-rw-r--r-- | gdb/testsuite/lib/mi-support.exp | 18 |
7 files changed, 98 insertions, 63 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8b54b59..1c68937 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2014-03-18 Pedro Alves <palves@redhat.com> + + PR gdb/13860 + * inferior.h (print_stop_event): Declare. + * infrun.c (print_stop_event): New, factored out from ... + (normal_stop): ... this. + * mi/mi-interp.c (mi_on_normal_stop): Use print_stop_event instead + of bpstat_print/print_stack_frame. + 2014-03-17 Tom Tromey <tromey@redhat.com> * ui-out.c (clear_table, ui_out_new): Clear uiout->table.id. diff --git a/gdb/inferior.h b/gdb/inferior.h index 6c0730a..b15f692 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -195,6 +195,8 @@ extern void start_remote (int from_tty); extern void normal_stop (void); +extern void print_stop_event (struct target_waitstatus *ws); + extern int signal_stop_state (int); extern int signal_print_state (int); diff --git a/gdb/infrun.c b/gdb/infrun.c index b7c0969..fe5d88b 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -5996,6 +5996,68 @@ print_no_history_reason (void) ui_out_text (current_uiout, "\nNo more reverse-execution history.\n"); } +/* Print current location without a level number, if we have changed + functions or hit a breakpoint. Print source line if we have one. + bpstat_print contains the logic deciding in detail what to print, + based on the event(s) that just occurred. */ + +void +print_stop_event (struct target_waitstatus *ws) +{ + int bpstat_ret; + int source_flag; + int do_frame_printing = 1; + struct thread_info *tp = inferior_thread (); + + bpstat_ret = bpstat_print (tp->control.stop_bpstat, ws->kind); + switch (bpstat_ret) + { + case PRINT_UNKNOWN: + /* FIXME: cagney/2002-12-01: Given that a frame ID does (or + should) carry around the function and does (or should) use + that when doing a frame comparison. */ + if (tp->control.stop_step + && frame_id_eq (tp->control.step_frame_id, + get_frame_id (get_current_frame ())) + && step_start_function == find_pc_function (stop_pc)) + { + /* Finished step, just print source line. */ + source_flag = SRC_LINE; + } + else + { + /* Print location and source line. */ + source_flag = SRC_AND_LOC; + } + break; + case PRINT_SRC_AND_LOC: + /* Print location and source line. */ + source_flag = SRC_AND_LOC; + break; + case PRINT_SRC_ONLY: + source_flag = SRC_LINE; + break; + case PRINT_NOTHING: + /* Something bogus. */ + source_flag = SRC_LINE; + do_frame_printing = 0; + break; + default: + internal_error (__FILE__, __LINE__, _("Unknown value.")); + } + + /* The behavior of this routine with respect to the source + flag is: + SRC_LINE: Print only source line + LOCATION: Print only location + SRC_AND_LOC: Print location and source line. */ + if (do_frame_printing) + print_stack_frame (get_selected_frame (NULL), 0, source_flag, 1); + + /* Display the auto-display expressions. */ + do_displays (); +} + /* Here to return control to GDB when the inferior stops for real. Print appropriate messages, remove breakpoints, give terminal our modes. @@ -6118,65 +6180,11 @@ normal_stop (void) { select_frame (get_current_frame ()); - /* Print current location without a level number, if - we have changed functions or hit a breakpoint. - Print source line if we have one. - bpstat_print() contains the logic deciding in detail - what to print, based on the event(s) that just occurred. */ - /* If --batch-silent is enabled then there's no need to print the current source location, and to try risks causing an error message about missing source files. */ if (stop_print_frame && !batch_silent) - { - int bpstat_ret; - int source_flag; - int do_frame_printing = 1; - struct thread_info *tp = inferior_thread (); - - bpstat_ret = bpstat_print (tp->control.stop_bpstat, last.kind); - switch (bpstat_ret) - { - case PRINT_UNKNOWN: - /* FIXME: cagney/2002-12-01: Given that a frame ID does - (or should) carry around the function and does (or - should) use that when doing a frame comparison. */ - if (tp->control.stop_step - && frame_id_eq (tp->control.step_frame_id, - get_frame_id (get_current_frame ())) - && step_start_function == find_pc_function (stop_pc)) - source_flag = SRC_LINE; /* Finished step, just - print source line. */ - else - source_flag = SRC_AND_LOC; /* Print location and - source line. */ - break; - case PRINT_SRC_AND_LOC: - source_flag = SRC_AND_LOC; /* Print location and - source line. */ - break; - case PRINT_SRC_ONLY: - source_flag = SRC_LINE; - break; - case PRINT_NOTHING: - source_flag = SRC_LINE; /* something bogus */ - do_frame_printing = 0; - break; - default: - internal_error (__FILE__, __LINE__, _("Unknown value.")); - } - - /* The behavior of this routine with respect to the source - flag is: - SRC_LINE: Print only source line - LOCATION: Print only location - SRC_AND_LOC: Print location and source line. */ - if (do_frame_printing) - print_stack_frame (get_selected_frame (NULL), 0, source_flag, 1); - - /* Display the auto-display expressions. */ - do_displays (); - } + print_stop_event (&last); } /* Save the function value return registers, if we care. diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c index 25bf0a1..862beaf 100644 --- a/gdb/mi/mi-interp.c +++ b/gdb/mi/mi-interp.c @@ -441,9 +441,8 @@ mi_on_normal_stop (struct bpstats *bs, int print_frame) current_uiout = mi_uiout; get_last_target_status (&last_ptid, &last); - bpstat_print (bs, last.kind); + print_stop_event (&last); - print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1); current_uiout = saved_uiout; } diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 4e6e248..458e795 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2014-03-18 Pedro Alves <palves@redhat.com> + + PR gdb/13860 + * gdb.mi/mi-solib.exp: Remove gdb/13860 kfail. + * lib/mi-support.exp (mi_expect_stop): Add special handling for + solib-event. + 2014-03-17 Joel Brobecker <brobecker@adacore.com> * gdb.ada/pckd_arr_ren: New testcase. diff --git a/gdb/testsuite/gdb.mi/mi-solib.exp b/gdb/testsuite/gdb.mi/mi-solib.exp index 06fa26b..608d2b7 100644 --- a/gdb/testsuite/gdb.mi/mi-solib.exp +++ b/gdb/testsuite/gdb.mi/mi-solib.exp @@ -60,8 +60,4 @@ mi_gdb_test "777-gdb-set stop-on-solib-events 1" "777\\^done" \ # commands still cause the correct MI output to be generated. mi_run_with_cli -global async -if { $async } { - setup_kfail gdb/13860 *-*-* -} mi_expect_stop solib-event .* .* .* .* .* "check for solib event" diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp index 1e8fee6..213073a 100644 --- a/gdb/testsuite/lib/mi-support.exp +++ b/gdb/testsuite/lib/mi-support.exp @@ -1028,6 +1028,8 @@ proc mi_expect_stop { reason func args file line extra test } { global thread_selected_re global breakpoint_re + set any "\[^\n\]*" + set after_stopped "" set after_reason "" if { [llength $extra] == 2 } { @@ -1070,6 +1072,20 @@ proc mi_expect_stop { reason func args file line extra test } { return } + if { $reason == "solib-event" } { + set pattern "\\*stopped,reason=\"solib-event\",thread-id=\"$decimal\",stopped-threads=$any\r\n($thread_selected_re|$breakpoint_re)*$prompt_re" + verbose -log "mi_expect_stop: expecting: $pattern" + gdb_expect { + -re "$pattern" { + pass "$test" + } + timeout { + fail "$test (unknown output after running)" + } + } + return + } + set args "\\\[$args\\\]" set bn "" @@ -1087,8 +1103,6 @@ proc mi_expect_stop { reason func args file line extra test } { set a $after_reason - set any "\[^\n\]*" - verbose -log "mi_expect_stop: expecting: \\*stopped,${r}${a}${bn}frame=\{addr=\"$hex\",func=\"$func\",args=$args,(?:file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"$line\"|from=\"$file\")\}$after_stopped,thread-id=\"$decimal\",stopped-threads=$any\r\n($thread_selected_re|$breakpoint_re)*$prompt_re" gdb_expect { -re "\\*stopped,${r}${a}${bn}frame=\{addr=\"$hex\",func=\"$func\",args=$args,(?:file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"($line)\"|from=\"$file\")\}$after_stopped,thread-id=\"$decimal\",stopped-threads=$any\r\n($thread_selected_re|$breakpoint_re)*$prompt_re" { |