From: Tom de Vries via Gdb-patches <gdb-patches@sourceware.org>
To: gdb-patches@sourceware.org
Subject: [PATCH][gdb] Make execute_command_to_string return string on throw
Date: Sat, 11 Sep 2021 14:02:04 +0200 [thread overview]
Message-ID: <20210911120202.GA16898@delia.home> (raw)
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?
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<void(void
(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<void(void)> fn, bool term_out);
+extern void execute_fn_to_string (std::string &res,
+ std::function<void(void)> 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<void(void)> fn)
/* See gdbcmd.h. */
-std::string
-execute_fn_to_string (std::function<void(void)> fn, bool term_out)
+void
+execute_fn_to_string (std::string &res, std::function<void(void)> 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);
}
\f
/* When nonzero, cause dont_repeat to do nothing. This should only be
next reply other threads:[~2021-09-11 12:03 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-11 12:02 Tom de Vries via Gdb-patches [this message]
2021-10-07 14:37 ` [PING][PATCH][gdb] " Tom de Vries via Gdb-patches
2021-10-07 15:33 ` [PATCH][gdb] " Simon Marchi
2021-10-07 16:15 ` Tom de Vries via Gdb-patches
2021-10-07 16:16 ` Simon Marchi
2021-10-20 18:53 ` Tom Tromey
2021-10-20 20:43 ` Tom de Vries via Gdb-patches
2021-10-20 22:14 ` Tom Tromey
2021-10-21 18:28 ` Tom Tromey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210911120202.GA16898@delia.home \
--to=gdb-patches@sourceware.org \
--cc=tdevries@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox