From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id 9Wh3LE0GX2FnbAAAWB0awg (envelope-from ) for ; Thu, 07 Oct 2021 10:38:05 -0400 Received: by simark.ca (Postfix, from userid 112) id AD8B11EE20; Thu, 7 Oct 2021 10:38:05 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-0.7 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,RDNS_DYNAMIC,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 960C91EDDB for ; Thu, 7 Oct 2021 10:38:04 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 372243858018 for ; Thu, 7 Oct 2021 14:38:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 372243858018 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1633617484; bh=jb4MSsljR+D3JduDcLsGsgtzVz3/x8caNGZ05MLlkE8=; h=Subject:To:References:Date:In-Reply-To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=kYyhn762/VFtc65geyzgfmB9IxoFjjoQFw6KhpZbF878h2RDxhtOiOXusLPzecSoN VPFXmjkKQakX9oWX71lLejY6CSAhVZih/tZw/h8ia9FEdYJEvbXfX/PzH9R3VMQqki SYNLzcnvxYC1NJlVEGkC90bdvZOmSGpSFumhy6RM= Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by sourceware.org (Postfix) with ESMTPS id DDD70385840B for ; Thu, 7 Oct 2021 14:37:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org DDD70385840B Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id E03CC200C9 for ; Thu, 7 Oct 2021 14:37:43 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id CE28813CE5 for ; Thu, 7 Oct 2021 14:37:43 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id FVk+MTcGX2F/XwAAMHmgww (envelope-from ) for ; Thu, 07 Oct 2021 14:37:43 +0000 Subject: [PING][PATCH][gdb] Make execute_command_to_string return string on throw To: gdb-patches@sourceware.org References: <20210911120202.GA16898@delia.home> Message-ID: <2dd30093-2e5a-828e-bcef-7cb37c9221ad@suse.de> Date: Thu, 7 Oct 2021 16:37:43 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.12.0 MIME-Version: 1.0 In-Reply-To: <20210911120202.GA16898@delia.home> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Tom de Vries via Gdb-patches Reply-To: Tom de Vries Errors-To: gdb-patches-bounces+public-inbox=simark.ca@sourceware.org Sender: "Gdb-patches" On 9/11/21 2:02 PM, Tom de Vries wrote: > Hi, > > The pattern for using execute_command_to_string is: > ... > std::string output; > output = execute_fn_to_string (fn, term_out); > ... > > This results in a problem when using it in a try/catch: > ... > try > { > output = execute_fn_to_string (fn, term_out) > } > catch (const gdb_exception &e) > { > /* Use output. */ > } > ... > > If an expection was thrown during execute_fn_to_string, then the output > remains unassigned, while it could be worthwhile to known what output was > generated by gdb before the expection was thrown. > > Fix this by returning the string using a parameter instead: > ... > execute_fn_to_string (output, fn, term_out) > ... > > Also add a variant without string parameter, to support places where the > function is used while ignoring the result: > ... > execute_fn_to_string (fn, term_out) > ... > > Tested on x86_64-linux. > > Any comments? > Ping. Thanks, - Tom > [gdb] Make execute_command_to_string return string on throw > > --- > gdb/complaints.c | 4 ++-- > gdb/gdbcmd.h | 12 +++++++++--- > gdb/guile/guile.c | 2 +- > gdb/python/python.c | 6 +++--- > gdb/stack.c | 4 ++-- > gdb/thread.c | 5 +++-- > gdb/top.c | 34 +++++++++++++++++++++++++++------- > 7 files changed, 47 insertions(+), 20 deletions(-) > > diff --git a/gdb/complaints.c b/gdb/complaints.c > index 525a3a7eacf..a823fcb0020 100644 > --- a/gdb/complaints.c > +++ b/gdb/complaints.c > @@ -91,7 +91,7 @@ test_complaints () > do \ > { \ > std::string output; \ > - output = execute_fn_to_string ([]() { complaint (STR); }, false); \ > + execute_fn_to_string (output, []() { complaint (STR); }, false); \ > std::string expected \ > = _("During symbol reading: ") + std::string (STR "\n"); \ > SELF_CHECK (output == expected); \ > @@ -102,7 +102,7 @@ test_complaints () > do \ > { \ > std::string output; \ > - output = execute_fn_to_string ([]() { complaint (STR); }, false); \ > + execute_fn_to_string (output, []() { complaint (STR); }, false); \ > SELF_CHECK (output.empty ()); \ > SELF_CHECK (counters[STR] == CNT); \ > } while (0) > diff --git a/gdb/gdbcmd.h b/gdb/gdbcmd.h > index 27550c1faee..05ffd7fd0ee 100644 > --- a/gdb/gdbcmd.h > +++ b/gdb/gdbcmd.h > @@ -145,7 +145,8 @@ extern void execute_fn_to_ui_file (struct ui_file *file, std::function (e.g. with styling). When TERM_OUT is false raw output will be collected > (e.g. no styling). */ > > -extern std::string execute_fn_to_string (std::function fn, bool term_out); > +extern void execute_fn_to_string (std::string &res, > + std::function fn, bool term_out); > > /* As execute_fn_to_ui_file, but run execute_command for P and FROM_TTY. */ > > @@ -154,8 +155,13 @@ extern void execute_command_to_ui_file (struct ui_file *file, > > /* As execute_fn_to_string, but run execute_command for P and FROM_TTY. */ > > -extern std::string execute_command_to_string (const char *p, int from_tty, > - bool term_out); > +extern void execute_command_to_string (std::string &res, const char *p, > + int from_tty, bool term_out); > + > +/* As execute_command_to_string, but ignore resulting string. */ > + > +extern void execute_command_to_string (const char *p, > + int from_tty, bool term_out); > > extern void print_command_line (struct command_line *, unsigned int, > struct ui_file *); > diff --git a/gdb/guile/guile.c b/gdb/guile/guile.c > index a28dee37ed8..8ba840cba6a 100644 > --- a/gdb/guile/guile.c > +++ b/gdb/guile/guile.c > @@ -302,7 +302,7 @@ gdbscm_execute_gdb_command (SCM command_scm, SCM rest) > > scoped_restore preventer = prevent_dont_repeat (); > if (to_string) > - to_string_res = execute_command_to_string (command, from_tty, false); > + execute_command_to_string (to_string_res, command, from_tty, false); > else > execute_command (command, from_tty); > > diff --git a/gdb/python/python.c b/gdb/python/python.c > index 5918bb414a3..34c1be76a16 100644 > --- a/gdb/python/python.c > +++ b/gdb/python/python.c > @@ -1888,11 +1888,11 @@ namespace selftests { > static void > test_python () > { > -#define CMD execute_command_to_string ("python print(5)", 0, true); > +#define CMD(S) execute_command_to_string (S, "python print(5)", 0, true) > > std::string output; > > - output = CMD; > + CMD (output); > SELF_CHECK (output == "5\n"); > output.clear (); > > @@ -1901,7 +1901,7 @@ test_python () > = make_scoped_restore (&gdb_python_initialized, 0); > try > { > - output = CMD; > + CMD (output); > } > catch (const gdb_exception &e) > { > diff --git a/gdb/stack.c b/gdb/stack.c > index 516e4d45696..edfda3a4e55 100644 > --- a/gdb/stack.c > +++ b/gdb/stack.c > @@ -3026,8 +3026,8 @@ frame_apply_command_count (const char *which_command, > set to the selected frame. */ > scoped_restore_current_thread restore_fi_current_frame; > > - cmd_result = execute_command_to_string > - (cmd, from_tty, gdb_stdout->term_out ()); > + execute_command_to_string > + (cmd_result, cmd, from_tty, gdb_stdout->term_out ()); > } > fi = get_selected_frame (_("frame apply " > "unable to get selected frame.")); > diff --git a/gdb/thread.c b/gdb/thread.c > index 10c3dcd6991..019c658bc47 100644 > --- a/gdb/thread.c > +++ b/gdb/thread.c > @@ -1457,8 +1457,9 @@ thr_try_catch_cmd (thread_info *thr, const char *cmd, int from_tty, > > try > { > - std::string cmd_result = execute_command_to_string > - (cmd, from_tty, gdb_stdout->term_out ()); > + std::string cmd_result; > + execute_command_to_string > + (cmd_result, cmd, from_tty, gdb_stdout->term_out ()); > if (!flags.silent || cmd_result.length () > 0) > { > if (!flags.quiet) > diff --git a/gdb/top.c b/gdb/top.c > index 7e95ed3969c..ff240eed657 100644 > --- a/gdb/top.c > +++ b/gdb/top.c > @@ -728,13 +728,22 @@ execute_fn_to_ui_file (struct ui_file *file, std::function fn) > > /* See gdbcmd.h. */ > > -std::string > -execute_fn_to_string (std::function fn, bool term_out) > +void > +execute_fn_to_string (std::string &res, std::function fn, > + bool term_out) > { > string_file str_file (term_out); > > - execute_fn_to_ui_file (&str_file, fn); > - return std::move (str_file.string ()); > + try { > + execute_fn_to_ui_file (&str_file, fn); > + } catch (...) { > + /* Finally. */ > + res = std::move (str_file.string ()); > + throw; > + } > + > + /* And finally. */ > + res = std::move (str_file.string ()); > } > > /* See gdbcmd.h. */ > @@ -748,12 +757,23 @@ execute_command_to_ui_file (struct ui_file *file, > > /* See gdbcmd.h. */ > > -std::string > +void > +execute_command_to_string (std::string &res, const char *p, int from_tty, > + bool term_out) > +{ > + execute_fn_to_string (res, [=]() { execute_command (p, from_tty); }, > + term_out); > +} > + > +/* See gdbcmd.h. */ > + > +void > execute_command_to_string (const char *p, int from_tty, > bool term_out) > { > - return > - execute_fn_to_string ([=]() { execute_command (p, from_tty); }, term_out); > + std::string dummy; > + execute_fn_to_string (dummy, [=]() { execute_command (p, from_tty); }, > + term_out); > } > > /* When nonzero, cause dont_repeat to do nothing. This should only be >