From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 32657 invoked by alias); 28 Aug 2014 11:33:35 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 32593 invoked by uid 89); 28 Aug 2014 11:33:30 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.5 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_NONE,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.2 X-HELO: na01-bn1-obe.outbound.protection.outlook.com Received: from mail-bn1blp0187.outbound.protection.outlook.com (HELO na01-bn1-obe.outbound.protection.outlook.com) (207.46.163.187) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Thu, 28 Aug 2014 11:33:25 +0000 Received: from BN3PR0301CA0058.namprd03.prod.outlook.com (25.160.152.154) by BLUPR03MB134.namprd03.prod.outlook.com (10.255.212.14) with Microsoft SMTP Server (TLS) id 15.0.1015.19; Thu, 28 Aug 2014 11:33:22 +0000 Received: from BN1AFFO11FD025.protection.gbl (2a01:111:f400:7c10::125) by BN3PR0301CA0058.outlook.office365.com (2a01:111:e400:401e::26) with Microsoft SMTP Server (TLS) id 15.0.1015.19 via Frontend Transport; Thu, 28 Aug 2014 11:33:22 +0000 Received: from az84smr01.freescale.net (192.88.158.2) by BN1AFFO11FD025.mail.protection.outlook.com (10.58.52.85) with Microsoft SMTP Server (TLS) id 15.0.1010.11 via Frontend Transport; Thu, 28 Aug 2014 11:33:21 +0000 Received: from [10.0.2.15] (b46904-02.ea.freescale.net [10.171.74.24]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id s7SBXASb022278; Thu, 28 Aug 2014 04:33:19 -0700 Message-ID: <53FF1377.8060805@freescale.com> Date: Thu, 28 Aug 2014 11:33:00 -0000 From: Adrian Sendroiu User-Agent: Mozilla/5.0 (X11; Linux i686; rv:24.0) Gecko/20100101 Thunderbird/24.2.0 MIME-Version: 1.0 To: Pedro Alves , , CC: Subject: Re: [PATCH v2 2/2] mi-out: Implement mi redirection using a stack. References: <53D8DA80.8010603@redhat.com> <1406819332-24242-1-git-send-email-adrian.sendroiu@freescale.com> <53DA6D73.5050906@redhat.com> <53E0E251.7040803@freescale.com> In-Reply-To: <53E0E251.7040803@freescale.com> Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: 7bit X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:192.88.158.2;CTRY:US;IPV:CAL;IPV:NLI;EFV:NLI;SFV:NSPM;SFS:(6009001)(377424004)(479174003)(377454003)(189002)(199003)(51704005)(51444003)(24454002)(90102001)(81542001)(65956001)(47776003)(81156004)(50466002)(64126003)(23756003)(106466001)(74662001)(74502001)(31966008)(46102001)(107046002)(104016003)(93886004)(81342001)(4396001)(85306004)(36756003)(65816999)(20776003)(80022001)(59896002)(65806001)(64706001)(87266999)(99396002)(26826002)(102836001)(83072002)(86362001)(85852003)(54356999)(21056001)(50986999)(68736004)(69596002)(19580405001)(83322001)(19580395003)(80316001)(6806004)(44976005)(87936001)(95666004)(105606002)(77982001)(76482001)(79102001)(76176999)(83506001)(97736001)(2201001)(33656002)(92566001)(92726001)(84676001);DIR:OUT;SFP:;SCL:1;SRVR:BLUPR03MB134;H:az84smr01.freescale.net;FPR:;MLV:ovrnspm;PTR:InfoDomainNonexistent;MX:1;A:1;LANG:en; X-Microsoft-Antispam: BCL:0;PCL:0;RULEID:;UriScan:; X-Forefront-PRVS: 031763BCAF Received-SPF: Fail (protection.outlook.com: domain of freescale.com does not designate 192.88.158.2 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.158.2; helo=az84smr01.freescale.net; Authentication-Results: spf=fail (sender IP is 192.88.158.2) smtp.mailfrom=adrian.sendroiu@freescale.com; X-OriginatorOrg: freescale.com X-SW-Source: 2014-08/txt/msg00600.txt.bz2 ping On 08/05/2014 04:55 PM, Adrian Sendroiu wrote: >> It's better to use $bpnum instead of hardcoding 2, as otherwise if someone adds a >> test that adds another breakpoint before this, this test stops being >> effective, silently. > > done > >>> + mi_gdb_test "-exec-continue" ".*" >> >> This should use mi_send_resuming_command/mi_expect_stop >> or mi_execute_to, so that the test works when the whole MI >> testsuite is run in async mode. > > done. Although I ran into another problem here, because mi_expect_stop expects a > message that looks like *stopped + prompt, while in my case it was something like > *stopped + =breakpoint-modified + prompt. I solved this by doing an even simpler > test case: just executing two python commands nested inside one another, like > "python gdb.execute('python gdb.execute(...". > > >> I think that we can avoid this duplication by renaming >> skip_python_tests, adding it a prompt_re parameter, and >> using that instead of $gdb_prompt. Something like: >> >> proc skip_python_tests {} { >> skip_python_tests_prompt "$gdb_prompt $" >> } >> >> proc mi_skip_python_tests { >> skip_python_tests_prompt "$mi_gdb_prompt$" >> } >> >> Did you try that? > > done > > --- 8< --- > Subject: [PATCH] mi-out: Implement mi redirection using a stack. > > The current implementation doesn't support nested redirections because it only > has an "original_buffer" where it saves the current stream when a redirection is > done. To overcome this limitation, this patch reimplements it using a stack of > streams. > > gdb/ > 2014-07-23 Adrian Sendroiu > > * mi/mi-out.c (ui_filep): New typedef. > (DEF_VEC_P (ui_filep)): New type. > (struct ui_out_data): Remove field. > Remove field. > : New field. > (mi_field_string): Get the output stream from the top of the > stack of streams. > (mi_field_fmt): Likewise. > (mi_flush): Likewise. > (field_separator): Likewise. > (mi_open): Likewise. > (mi_close): Likewise. > (mi_out_buffered): Likewise. > (mi_out_rewind): Likewise. > (mi_out_put): Likewise. > (mi_out_new): Initialize the stack of streams. Push a newly > created stream on the stack. Remove obsolete comment. > (mi_redirect): Reimplement using push and pop operations. > > gdb/testsuite/ > 2014-08-05 Adrian Sendroiu > > * gdb.mi/mi-logging.exp: Add test for nested mi redirection. > * lib/gdb.exp: (skip_python_tests_prompt): New function. > (skip_python_tests): Use skip_python_tests_prompt. > * lib/mi-support.exp: (mi_skip_python_tests): New function. > --- > gdb/mi/mi-out.c | 77 ++++++++++++++++++++--------------- > gdb/testsuite/gdb.mi/mi-logging.exp | 14 +++++++ > gdb/testsuite/lib/gdb.exp | 20 +++++---- > gdb/testsuite/lib/mi-support.exp | 7 ++++ > 4 files changed, 77 insertions(+), 41 deletions(-) > > diff --git a/gdb/mi/mi-out.c b/gdb/mi/mi-out.c > index 6ec41e6..6731509 100644 > --- a/gdb/mi/mi-out.c > +++ b/gdb/mi/mi-out.c > @@ -22,14 +22,17 @@ > #include "defs.h" > #include "ui-out.h" > #include "mi-out.h" > +#include "vec.h" > + > +typedef struct ui_file *ui_filep; > +DEF_VEC_P (ui_filep); > > struct ui_out_data > { > int suppress_field_separator; > int suppress_output; > int mi_version; > - struct ui_file *buffer; > - struct ui_file *original_buffer; > + VEC (ui_filep) *streams; > }; > typedef struct ui_out_data mi_out_data; > > @@ -215,17 +218,20 @@ mi_field_string (struct ui_out *uiout, int fldno, int width, > enum ui_align align, const char *fldname, const char *string) > { > mi_out_data *data = ui_out_data (uiout); > + struct ui_file *stream; > > if (data->suppress_output) > return; > > + stream = VEC_last (ui_filep, data->streams); > + > field_separator (uiout); > if (fldname) > - fprintf_unfiltered (data->buffer, "%s=", fldname); > - fprintf_unfiltered (data->buffer, "\""); > + fprintf_unfiltered (stream, "%s=", fldname); > + fprintf_unfiltered (stream, "\""); > if (string) > - fputstr_unfiltered (string, '"', data->buffer); > - fprintf_unfiltered (data->buffer, "\""); > + fputstr_unfiltered (string, '"', stream); > + fprintf_unfiltered (stream, "\""); > } > > /* This is the only field function that does not align. */ > @@ -236,17 +242,20 @@ mi_field_fmt (struct ui_out *uiout, int fldno, int width, > const char *format, va_list args) > { > mi_out_data *data = ui_out_data (uiout); > + struct ui_file *stream; > > if (data->suppress_output) > return; > > + stream = VEC_last (ui_filep, data->streams); > + > field_separator (uiout); > if (fldname) > - fprintf_unfiltered (data->buffer, "%s=\"", fldname); > + fprintf_unfiltered (stream, "%s=\"", fldname); > else > - fputs_unfiltered ("\"", data->buffer); > - vfprintf_unfiltered (data->buffer, format, args); > - fputs_unfiltered ("\"", data->buffer); > + fputs_unfiltered ("\"", stream); > + vfprintf_unfiltered (stream, format, args); > + fputs_unfiltered ("\"", stream); > } > > void > @@ -275,8 +284,9 @@ void > mi_flush (struct ui_out *uiout) > { > mi_out_data *data = ui_out_data (uiout); > + struct ui_file *stream = VEC_last (ui_filep, data->streams); > > - gdb_flush (data->buffer); > + gdb_flush (stream); > } > > int > @@ -285,15 +295,9 @@ mi_redirect (struct ui_out *uiout, struct ui_file *outstream) > mi_out_data *data = ui_out_data (uiout); > > if (outstream != NULL) > - { > - data->original_buffer = data->buffer; > - data->buffer = outstream; > - } > - else if (data->original_buffer != NULL) > - { > - data->buffer = data->original_buffer; > - data->original_buffer = NULL; > - } > + VEC_safe_push (ui_filep, data->streams, outstream); > + else > + VEC_pop (ui_filep, data->streams); > > return 0; > } > @@ -306,29 +310,31 @@ static void > field_separator (struct ui_out *uiout) > { > mi_out_data *data = ui_out_data (uiout); > + struct ui_file *stream = VEC_last (ui_filep, data->streams); > > if (data->suppress_field_separator) > data->suppress_field_separator = 0; > else > - fputc_unfiltered (',', data->buffer); > + fputc_unfiltered (',', stream); > } > > static void > mi_open (struct ui_out *uiout, const char *name, enum ui_out_type type) > { > mi_out_data *data = ui_out_data (uiout); > + struct ui_file *stream = VEC_last (ui_filep, data->streams); > > field_separator (uiout); > data->suppress_field_separator = 1; > if (name) > - fprintf_unfiltered (data->buffer, "%s=", name); > + fprintf_unfiltered (stream, "%s=", name); > switch (type) > { > case ui_out_type_tuple: > - fputc_unfiltered ('{', data->buffer); > + fputc_unfiltered ('{', stream); > break; > case ui_out_type_list: > - fputc_unfiltered ('[', data->buffer); > + fputc_unfiltered ('[', stream); > break; > default: > internal_error (__FILE__, __LINE__, _("bad switch")); > @@ -339,14 +345,15 @@ static void > mi_close (struct ui_out *uiout, enum ui_out_type type) > { > mi_out_data *data = ui_out_data (uiout); > + struct ui_file *stream = VEC_last (ui_filep, data->streams); > > switch (type) > { > case ui_out_type_tuple: > - fputc_unfiltered ('}', data->buffer); > + fputc_unfiltered ('}', stream); > break; > case ui_out_type_list: > - fputc_unfiltered (']', data->buffer); > + fputc_unfiltered (']', stream); > break; > default: > internal_error (__FILE__, __LINE__, _("bad switch")); > @@ -360,8 +367,9 @@ void > mi_out_buffered (struct ui_out *uiout, char *string) > { > mi_out_data *data = ui_out_data (uiout); > + struct ui_file *stream = VEC_last (ui_filep, data->streams); > > - fprintf_unfiltered (data->buffer, "%s", string); > + fprintf_unfiltered (stream, "%s", string); > } > > /* Clear the buffer. */ > @@ -370,8 +378,9 @@ void > mi_out_rewind (struct ui_out *uiout) > { > mi_out_data *data = ui_out_data (uiout); > + struct ui_file *stream = VEC_last (ui_filep, data->streams); > > - ui_file_rewind (data->buffer); > + ui_file_rewind (stream); > } > > /* Dump the buffer onto the specified stream. */ > @@ -386,9 +395,10 @@ void > mi_out_put (struct ui_out *uiout, struct ui_file *stream) > { > mi_out_data *data = ui_out_data (uiout); > + struct ui_file *current_stream = VEC_last (ui_filep, data->streams); > > - ui_file_put (data->buffer, do_write, stream); > - ui_file_rewind (data->buffer); > + ui_file_put (current_stream, do_write, stream); > + ui_file_rewind (current_stream); > } > > /* Return the current MI version. */ > @@ -407,13 +417,14 @@ struct ui_out * > mi_out_new (int mi_version) > { > int flags = 0; > + struct ui_file *new_stream; > > mi_out_data *data = XNEW (mi_out_data); > data->suppress_field_separator = 0; > data->suppress_output = 0; > data->mi_version = mi_version; > - /* FIXME: This code should be using a ``string_file'' and not the > - TUI buffer hack. */ > - data->buffer = mem_fileopen (); > + data->streams = NULL; > + new_stream = mem_fileopen (); > + VEC_safe_push (ui_filep, data->streams, new_stream); > return ui_out_new (&mi_ui_out_impl, data, flags); > } > diff --git a/gdb/testsuite/gdb.mi/mi-logging.exp b/gdb/testsuite/gdb.mi/mi-logging.exp > index d5e4193..bd884d3 100644 > --- a/gdb/testsuite/gdb.mi/mi-logging.exp > +++ b/gdb/testsuite/gdb.mi/mi-logging.exp > @@ -82,6 +82,20 @@ if [regexp "1001\\^done\[\r\n\]+$mi_log_prompt.*1002\\^running\[\r\n\]+\\*runnin > fail "Redirect log file contents" > } > > +# This triggers a nested mi_ui_out redirection, by executing a python command > +# inside another python command, both of which are run with to_string = True. > +if ![mi_skip_python_tests] { > + mi_gdb_test "-break-insert do_nothing" ".*" > + mi_gdb_test "commands \$bpnum\npython gdb.execute('python gdb.execute(\"help\", True, True)', True, True)\nend" ".*" > + > + mi_send_resuming_command "exec-continue" "continue" > + > + mi_expect_stop "breakpoint-hit" "do_nothing" ".*" ".*" ".*" {".*" ".*"} "Continue to breakpoint" > + > + # This will crash gdb if redirection is not done properly. > + mi_gdb_test "help" ".*" "nested redirect" > +} > + > mi_gdb_exit > > remote_file host delete $milogfile > diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp > index 8cb98ae..8bb2d23 100644 > --- a/gdb/testsuite/lib/gdb.exp > +++ b/gdb/testsuite/lib/gdb.exp > @@ -1603,34 +1603,33 @@ proc skip_d_tests {} { > > # Return a 1 for configurations that do not support Python scripting. > > -proc skip_python_tests {} { > - global gdb_prompt > +proc skip_python_tests_prompt { prompt_re } { > global gdb_py_is_py3k > global gdb_py_is_py24 > > gdb_test_multiple "python print ('test')" "verify python support" { > - -re "not supported.*$gdb_prompt $" { > + -re "not supported.*$prompt_re" { > unsupported "Python support is disabled." > return 1 > } > - -re "$gdb_prompt $" {} > + -re "$prompt_re" {} > } > > set gdb_py_is_py24 0 > gdb_test_multiple "python print (sys.version_info\[0\])" "check if python 3" { > - -re "3.*$gdb_prompt $" { > + -re "3.*$prompt_re" { > set gdb_py_is_py3k 1 > } > - -re ".*$gdb_prompt $" { > + -re ".*$prompt_re" { > set gdb_py_is_py3k 0 > } > } > if { $gdb_py_is_py3k == 0 } { > gdb_test_multiple "python print (sys.version_info\[1\])" "check if python 2.4" { > - -re "\[45\].*$gdb_prompt $" { > + -re "\[45\].*$prompt_re" { > set gdb_py_is_py24 1 > } > - -re ".*$gdb_prompt $" { > + -re ".*$prompt_re" { > set gdb_py_is_py24 0 > } > } > @@ -1639,6 +1638,11 @@ proc skip_python_tests {} { > return 0 > } > > +proc skip_python_tests { } { > + global gdb_prompt > + skip_python_tests_prompt "$gdb_prompt $" > +} > + > # Return a 1 if we should skip shared library tests. > > proc skip_shlib_tests {} { > diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp > index 204f1e8..80a3627 100644 > --- a/gdb/testsuite/lib/mi-support.exp > +++ b/gdb/testsuite/lib/mi-support.exp > @@ -2491,3 +2491,10 @@ proc mi_make_breakpoint_table {bp_list} { > # Assemble the final regexp. > return "BreakpointTable={nr_rows=\"$nr\",nr_cols=\"$nc\",$header,$body}" > } > + > +# Return a 1 for configurations that do not support Python scripting. > + > +proc mi_skip_python_tests {} { > + global mi_gdb_prompt > + skip_python_tests_prompt "$mi_gdb_prompt$" > +} >