From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id 3r8rKLtp9F85PwAAWB0awg (envelope-from ) for ; Tue, 05 Jan 2021 08:29:31 -0500 Received: by simark.ca (Postfix, from userid 112) id 950E81F0AA; Tue, 5 Jan 2021 08:29:31 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=MAILING_LIST_MULTI, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from sourceware.org (server2.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 4B1351E965 for ; Tue, 5 Jan 2021 08:29:30 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0676E39450E1; Tue, 5 Jan 2021 13:29:30 +0000 (GMT) Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by sourceware.org (Postfix) with ESMTPS id 5348E39450DE for ; Tue, 5 Jan 2021 13:29:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 5348E39450DE Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=tdevries@suse.de X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 6C8E1AD19 for ; Tue, 5 Jan 2021 13:29:26 +0000 (UTC) Date: Tue, 5 Jan 2021 14:29:24 +0100 From: Tom de Vries To: gdb-patches@sourceware.org Subject: [PATCH][gdb] Fix internal-error in process_event_stop_test Message-ID: <20210105132923.GA15843@delia> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.10.1 (2018-07-13) 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: , Errors-To: gdb-patches-bounces@sourceware.org Sender: "Gdb-patches" Hi, The function create_exception_master_breakpoint in gdb/breakpoint.c attempts to set a master exception breakpoint in each objfile. It tries this using a libgcc/unwind probe, and if that fails then using the _Unwind_DebugHook symbol: ... for (objfile *objfile : current_program_space->objfiles ()) { /* Try using probes. */ if (/* successful */) continue; /* Try using _Unwind_DebugHook */ } ... The preference scheme works ok both if the objfile has debug info, and if it's stripped. But it doesn't work when the objfile has a .gnu_debuglink to a .debug file (and the .debug file is present). What happens is that: - we first encounter objfile libgcc.debug - we try using probes, and this fails - so we try _Unwind_DebugHook, which succeeds - next we encounter objfile libgcc - we try using probes, and this succeeds. So, we end up with a master exception breakpoint in both libgcc (using probes) and libgcc.debug (using _Unwind_DebugHook). This eventually causes: ... (gdb) PASS: gdb.cp/nextoverthrow.exp: post-check - next over a throw 3 next^M src/gdb/infrun.c:6384: internal-error: \ void process_event_stop_test(execution_control_state*): \ Assertion `ecs->event_thread->control.exception_resume_breakpoint != NULL' \ failed.^M A problem internal to GDB has been detected,^M further debugging may prove unreliable.^M Quit this debugging session? (y or n) FAIL: gdb.cp/nextoverthrow.exp: next past catch (GDB internal error) ... To trigger this internal-error, we need to use gcc-10 or later to compile the test-case, such that it contains the fix for gcc PR97774 - "Incorrect line info for try/catch". Fix this by only trying to install the master exception breakpoint in libgcc.debug using the _Unwind_DebugHook method, if the install using probes in libgcc failed. Tested on x86_64-linux. Any comments? Thanks, - Tom [gdb] Fix internal-error in process_event_stop_test gdb/ChangeLog: 2021-01-05 Tom de Vries PR gdb/26881 * breakpoint.c (create_exception_master_breakpoint_1): Factor out of ... (create_exception_master_breakpoint): ... here. Only try to install the master exception breakpoint in objfile.debug using the _Unwind_DebugHook method, if the install using probes in objfile failed. --- gdb/breakpoint.c | 155 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 93 insertions(+), 62 deletions(-) diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 69e452993f1..6171e9ca396 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -3477,92 +3477,123 @@ create_std_terminate_master_breakpoint (void) } } -/* Install a master breakpoint on the unwinder's debug hook. */ +/* Install a master breakpoint on the unwinder's debug hook for OBJFILE. + Return true if a breakpoint was installed. */ -static void -create_exception_master_breakpoint (void) +static bool +create_exception_master_breakpoint_1 (objfile *objfile) { const char *const func_name = "_Unwind_DebugHook"; + struct breakpoint *b; + struct gdbarch *gdbarch; + struct breakpoint_objfile_data *bp_objfile_data; + CORE_ADDR addr; + struct explicit_location explicit_loc; - for (objfile *objfile : current_program_space->objfiles ()) - { - struct breakpoint *b; - struct gdbarch *gdbarch; - struct breakpoint_objfile_data *bp_objfile_data; - CORE_ADDR addr; - struct explicit_location explicit_loc; + bp_objfile_data = get_breakpoint_objfile_data (objfile); - bp_objfile_data = get_breakpoint_objfile_data (objfile); + /* We prefer the SystemTap probe point if it exists. */ + if (!bp_objfile_data->exception_searched) + { + std::vector ret + = find_probes_in_objfile (objfile, "libgcc", "unwind"); - /* We prefer the SystemTap probe point if it exists. */ - if (!bp_objfile_data->exception_searched) + if (!ret.empty ()) { - std::vector ret - = find_probes_in_objfile (objfile, "libgcc", "unwind"); + /* We are only interested in checking one element. */ + probe *p = ret[0]; - if (!ret.empty ()) + if (!p->can_evaluate_arguments ()) { - /* We are only interested in checking one element. */ - probe *p = ret[0]; - - if (!p->can_evaluate_arguments ()) - { - /* We cannot use the probe interface here, because it does - not know how to evaluate arguments. */ - ret.clear (); - } + /* We cannot use the probe interface here, because it does + not know how to evaluate arguments. */ + ret.clear (); } - bp_objfile_data->exception_probes = ret; - bp_objfile_data->exception_searched = 1; } + bp_objfile_data->exception_probes = ret; + bp_objfile_data->exception_searched = 1; + } - if (!bp_objfile_data->exception_probes.empty ()) + if (!bp_objfile_data->exception_probes.empty ()) + { + gdbarch = objfile->arch (); + + for (probe *p : bp_objfile_data->exception_probes) { - gdbarch = objfile->arch (); + b = create_internal_breakpoint (gdbarch, + p->get_relocated_address (objfile), + bp_exception_master, + &internal_breakpoint_ops); + b->location = new_probe_location ("-probe-stap libgcc:unwind"); + b->enable_state = bp_disabled; + } - for (probe *p : bp_objfile_data->exception_probes) - { - b = create_internal_breakpoint (gdbarch, - p->get_relocated_address (objfile), - bp_exception_master, - &internal_breakpoint_ops); - b->location = new_probe_location ("-probe-stap libgcc:unwind"); - b->enable_state = bp_disabled; - } + return true; + } - continue; - } + /* Otherwise, try the hook function. */ - /* Otherwise, try the hook function. */ + if (msym_not_found_p (bp_objfile_data->exception_msym.minsym)) + return false; - if (msym_not_found_p (bp_objfile_data->exception_msym.minsym)) - continue; + gdbarch = objfile->arch (); - gdbarch = objfile->arch (); + if (bp_objfile_data->exception_msym.minsym == NULL) + { + struct bound_minimal_symbol debug_hook; - if (bp_objfile_data->exception_msym.minsym == NULL) + debug_hook = lookup_minimal_symbol (func_name, NULL, objfile); + if (debug_hook.minsym == NULL) { - struct bound_minimal_symbol debug_hook; + bp_objfile_data->exception_msym.minsym = &msym_not_found; + return false; + } - debug_hook = lookup_minimal_symbol (func_name, NULL, objfile); - if (debug_hook.minsym == NULL) - { - bp_objfile_data->exception_msym.minsym = &msym_not_found; - continue; - } + bp_objfile_data->exception_msym = debug_hook; + } + + addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->exception_msym); + addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr, + current_top_target ()); + b = create_internal_breakpoint (gdbarch, addr, bp_exception_master, + &internal_breakpoint_ops); + initialize_explicit_location (&explicit_loc); + explicit_loc.function_name = ASTRDUP (func_name); + b->location = new_explicit_location (&explicit_loc); + b->enable_state = bp_disabled; + + return true; +} + +/* Install a master breakpoint on the unwinder's debug hook. */ - bp_objfile_data->exception_msym = debug_hook; +static void +create_exception_master_breakpoint (void) +{ + objfile *skip = nullptr; + for (objfile *obj : current_program_space->objfiles ()) + { + if (skip) + { + gdb_assert (skip == obj); + skip = nullptr; + continue; } - addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->exception_msym); - addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr, - current_top_target ()); - b = create_internal_breakpoint (gdbarch, addr, bp_exception_master, - &internal_breakpoint_ops); - initialize_explicit_location (&explicit_loc); - explicit_loc.function_name = ASTRDUP (func_name); - b->location = new_explicit_location (&explicit_loc); - b->enable_state = bp_disabled; + if (obj->separate_debug_objfile_backlink) + { + objfile *exec = obj->separate_debug_objfile_backlink; + + /* Try a probe kind breakpoint in the exec objfile. */ + if (!create_exception_master_breakpoint_1 (exec)) + /* Try an _Unwind_DebugHook kind breakpoint in the .debug + objfile. */ + create_exception_master_breakpoint_1 (obj); + + skip = exec; + } + else + create_exception_master_breakpoint_1 (obj); } }