From: Pedro Alves <pedro@palves.net>
To: Kevin Buettner <kevinb@redhat.com>, gdb-patches@sourceware.org
Subject: Re: [PATCH v2 3/6] Catch and (re)throw gdb_exception_quit
Date: Mon, 27 Sep 2021 19:05:26 +0100 [thread overview]
Message-ID: <f70f62bc-5e53-a03d-e3a0-5f39a5da79ba@palves.net> (raw)
In-Reply-To: <20210822231959.184061-4-kevinb@redhat.com>
On 2021-08-23 12:20 a.m., Kevin Buettner wrote:
> There is one case that I examined which I could not figure out how to
> handle. It is the scoped_switch_fork_info destructor in
> gdb/linux-fork.c. It looks looks like this:
>
> ~scoped_switch_fork_info ()
> {
> if (m_oldfp != nullptr)
> {
> /* Switch back to inferior_ptid. */
> try
> {
> remove_breakpoints ();
> fork_load_infrun_state (m_oldfp);
> insert_breakpoints ();
> }
> catch (const gdb_exception &ex)
> {
> warning (_("Couldn't restore checkpoint state in %s: %s"),
> target_pid_to_str (m_oldfp->ptid).c_str (),
> ex.what ());
> }
> }
> }
>
> The static analysis tool determined that there is a call path
> to maybe_quit():
>
> "_ZN23scoped_switch_fork_infoD2Ev"
> -> "_Z18remove_breakpointsv"
> -> "_ZL17remove_breakpointP11bp_location"
> -> "_ZL19remove_breakpoint_1P11bp_location16remove_bp_reason"
> -> "_Z26memory_validate_breakpointP7gdbarchP14bp_target_info"
> -> "_Z18target_read_memorymPhl"
> -> "_Z11target_readP10target_ops13target_objectPKcPhml"
> -> "_Z10maybe_quitv";
>
> The catch block simply prints a warning, thus (potentially) swallowing
> a QUIT exception. It's not clear to me whether rethrowing the
> exception is safe here.
No, it's not safe -- you'd crash gdb. Destructors by default are noexcept, so if you let
an exception escape a destructor the C++ runtime calls std::terminate().
I'm thinking we could instead do:
~foo::foo ()
{
try
{
... destruction code here ...
}
catch (const gdb_exception_quit &ex)
{
/* Can't let this escape the dtor, but we also don't want to lose it.
Set the global quit flag so that we handle it later once we
get to a QUIT. */
set_quit_flag ();
}
catch (const gdb_exception &ex)
{
warning (....);
}
}
we could even wrap this in a function that take gdb::function_view to avoid
duplicating the try/catch all over the place. Like:
void
wrap_dtor (gdb::function_view<void ()> body)
{
try
{
body ();
}
catch (const gdb_exception_quit &ex)
{
/* Can't handle now. Set the global flag so that we handle it
later once we get to a QUIT. */
set_quit_flag ();
}
catch (const gdb_exception &ex)
{
warning (....);
}
}
~foo::foo ()
{
wrap_dtor ([] ()
{
... destruction code here ...
});
}
> ---
> gdb/ada-lang.c | 4 ++++
> gdb/breakpoint.c | 15 +++++++++++++++
> gdb/i386-linux-tdep.c | 4 ++++
> gdb/infrun.c | 4 ++++
> gdb/jit.c | 4 ++++
> gdb/objc-lang.c | 4 ++++
> gdb/parse.c | 4 ++++
> gdb/printcmd.c | 4 ++++
> gdb/record-btrace.c | 4 ++++
> gdb/solib.c | 4 ++++
> gdb/sparc64-linux-tdep.c | 4 ++++
> 11 files changed, 55 insertions(+)
>
> diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
> index b098991612d..f2f6acf0bfe 100644
> --- a/gdb/ada-lang.c
> +++ b/gdb/ada-lang.c
> @@ -11679,6 +11679,10 @@ should_stop_exception (const struct bp_location *bl)
> stop = value_true (evaluate_expression (ada_loc->excep_cond_expr.get ()));
> value_free_to_mark (mark);
> }
> + catch (const gdb_exception_quit &ex)
> + {
> + throw;
> + }
> catch (const gdb_exception &ex)
Why not just replace the existing:
catch (const gdb_exception &ex)
with:
catch (const gdb_exception_error &ex)
?
> {
> exception_fprintf (gdb_stderr, ex,
> diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
> index 5cc37430e36..6271545073b 100644
> --- a/gdb/breakpoint.c
> +++ b/gdb/breakpoint.c
> @@ -2699,6 +2699,9 @@ insert_bp_location (struct bp_location *bl,
> {
> /* Can't set the breakpoint. */
>
> + if (bp_excpt.reason == RETURN_QUIT)
> + throw bp_excpt;
> +
> /* If the target has closed then it will have deleted any
> breakpoints inserted within the target inferior, as a result
> any further attempts to interact with the breakpoint objects
> @@ -5082,6 +5085,10 @@ bpstat_check_watchpoint (bpstat bs)
> {
> e = watchpoint_check (bs);
> }
> + catch (const gdb_exception_quit &ex)
> + {
> + throw;
> + }
> catch (const gdb_exception &ex)
Same question here.
> {
> exception_fprintf (gdb_stderr, ex,
> @@ -5317,6 +5324,10 @@ bpstat_check_breakpoint_conditions (bpstat bs, thread_info *thread)
> {
> condition_result = breakpoint_cond_eval (cond);
> }
> + catch (const gdb_exception_quit &ex)
> + {
> + throw;
> + }
> catch (const gdb_exception &ex)
Ditto.
> {
> exception_fprintf (gdb_stderr, ex,
> @@ -14385,6 +14396,10 @@ enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition,
> bpt->enable_state = bp_enabled;
> update_watchpoint (w, 1 /* reparse */);
> }
> + catch (const gdb_exception_quit &ex)
> + {
> + throw;
> + }
> catch (const gdb_exception &e)
Ditto. Same for the remainder of the patch.
next prev parent reply other threads:[~2021-09-27 18:05 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-22 23:19 [PATCH v2 0/6] glibc-2.34: Fix gdb.base/gdb-sigterm.exp failure/error Kevin Buettner via Gdb-patches
2021-08-22 23:19 ` [PATCH v2 1/6] Handle recursive internal problem in gdb_internal_error_resync Kevin Buettner via Gdb-patches
2021-09-27 17:38 ` Pedro Alves
2022-02-26 20:40 ` Kevin Buettner via Gdb-patches
2021-08-22 23:19 ` [PATCH v2 2/6] Handle gdb SIGTERM via normal QUIT processing Kevin Buettner via Gdb-patches
2021-09-27 17:39 ` Pedro Alves
2021-08-22 23:20 ` [PATCH v2 3/6] Catch and (re)throw gdb_exception_quit Kevin Buettner via Gdb-patches
2021-09-27 18:05 ` Pedro Alves [this message]
2021-08-22 23:20 ` [PATCH v2 4/6] Python QUIT processing updates Kevin Buettner via Gdb-patches
2021-09-27 18:24 ` Pedro Alves
2021-08-22 23:20 ` [PATCH v2 5/6] Guile " Kevin Buettner via Gdb-patches
2021-09-27 18:26 ` Pedro Alves
2021-08-22 23:20 ` [PATCH v2 6/6] QUIT processing w/ explicit sync_quit_force_run check Kevin Buettner via Gdb-patches
2021-09-27 18:34 ` Pedro Alves
2021-09-27 17:20 ` [PATCH v2 0/6] glibc-2.34: Fix gdb.base/gdb-sigterm.exp failure/error Kevin Buettner via Gdb-patches
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=f70f62bc-5e53-a03d-e3a0-5f39a5da79ba@palves.net \
--to=pedro@palves.net \
--cc=gdb-patches@sourceware.org \
--cc=kevinb@redhat.com \
/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