From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id eMlVBJQXRmJQHAAAWB0awg (envelope-from ) for ; Thu, 31 Mar 2022 17:05:24 -0400 Received: by simark.ca (Postfix, from userid 112) id 0FB651F163; Thu, 31 Mar 2022 17:05:24 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,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 29E0B1E150 for ; Thu, 31 Mar 2022 17:05:23 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D7A4B388CC39 for ; Thu, 31 Mar 2022 21:05:22 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D7A4B388CC39 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1648760722; bh=v/iORD0zIAx3eJ/Vk8QfrhKvP9mCByc4NJC2ipIUz9Q=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=D2kILm2NbJ5uDZKmdVUTf8Q5yhJoy38LG2CO9b/m1u3jBzJ3wlwwRSeVyn9jOc5sS lZjzMf+CL/oXYoii3VZUbeBROXyVImUOoSbojHpUkcIGqS0dTDpY0F6zuOqP23ul5T e9JKOa0/mR7Zl/IDAYv50uo9u/Q1EqCcqi+IoyHs= Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id E9BCB385843E for ; Thu, 31 Mar 2022 21:04:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E9BCB385843E Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-209-jVRzGd1vNj61YTRvrsBNdQ-1; Thu, 31 Mar 2022 17:04:32 -0400 X-MC-Unique: jVRzGd1vNj61YTRvrsBNdQ-1 Received: by mail-wm1-f72.google.com with SMTP id o19-20020a05600c379300b0038c7117460dso243223wmr.6 for ; Thu, 31 Mar 2022 14:04:31 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=v/iORD0zIAx3eJ/Vk8QfrhKvP9mCByc4NJC2ipIUz9Q=; b=1pY8MrnSmjYweJTHeDcsbvYm4cie0TmDoxSjOyWPdMXKX010sdqXpRtEsypAZGDrN3 jzcmEU0JqHfkiiDyRDe/KS8WXn4E76w2N1aH0E8FpaHFwTbIR9WradtJ+A8Ap3WwJteI 7m50P7lzf3M2qF7FpDLD6PtLONUlWJSD3kSJF1056FbmSrjZ4/vHahFf7YmEF10r6dAn Weg4FY5A3w2i7kK7eIR8hEfi1gbPOrLOIjHhToqjB8hDzjCsPZvovpI4WhGhXWUkQAia dEGFWjsUlawqTNrSdM8ulVXzdwaInUncAv72hWAJwCUrp7ZN9d1csdKiWc6aQhF9e7BL IB5A== X-Gm-Message-State: AOAM530++UsISTUM7WyNGTstE9HbHKwO8J8E9BBGC+ChDSpcD5Jc54Kp eOrvafMAc+WFcUjYCu1l/LakLwqfbli1/UyKnvfmTo2uJqjtr34xZqHGEiu3x1FGGzIptl1jmc6 qIw6JG1aOzE6oJOHs6nr3fLvWMzD7+HI7kPuKg2aJWT7CQQO8vAMxHg2lv+O0rg1sanqpFZG05Q == X-Received: by 2002:adf:e987:0:b0:203:d6f6:71f3 with SMTP id h7-20020adfe987000000b00203d6f671f3mr5661455wrm.82.1648760670261; Thu, 31 Mar 2022 14:04:30 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwj/qqwnpkzbeAfyTHO+SAhSpnGyM5NjHDeehL2EQpdVBqD0esk47W/cOJA636KYtUd4QfqXA== X-Received: by 2002:adf:e987:0:b0:203:d6f6:71f3 with SMTP id h7-20020adfe987000000b00203d6f671f3mr5661438wrm.82.1648760669800; Thu, 31 Mar 2022 14:04:29 -0700 (PDT) Received: from localhost (host86-169-131-113.range86-169.btcentralplus.com. [86.169.131.113]) by smtp.gmail.com with ESMTPSA id e9-20020a5d6d09000000b00203ecdca5b7sm435698wrq.33.2022.03.31.14.04.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 31 Mar 2022 14:04:29 -0700 (PDT) To: gdb-patches@sourceware.org Subject: [PATCH 01/16] gdb: don't try to use readline before it's initialized Date: Thu, 31 Mar 2022 22:04:07 +0100 Message-Id: <3bf20187338c926508290a85209f502e55800199.1648760270.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true 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: Andrew Burgess via Gdb-patches Reply-To: Andrew Burgess Cc: Andrew Burgess Errors-To: gdb-patches-bounces+public-inbox=simark.ca@sourceware.org Sender: "Gdb-patches" While working on a different patch, I triggered an assertion from the initialize_current_architecture code, specifically from one of the *_gdbarch_init functions in a *-tdep.c file. This exposes a couple of issues with GDB. This is easy enough to reproduce by adding 'gdb_assert (false)' into a suitable function. For example, I added a line into i386_gdbarch_init and can see the following issue. I start GDB and immediately hit the assert, the output is as you'd expect, except for the very last line: $ ./gdb/gdb --data-directory ./gdb/data-directory/ ../../src.dev-1/gdb/i386-tdep.c:8455: internal-error: i386_gdbarch_init: Assertion `false' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. ----- Backtrace ----- ... snip ... --------------------- ../../src.dev-1/gdb/i386-tdep.c:8455: internal-error: i386_gdbarch_init: Assertion `false' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. Quit this debugging session? (y or n) ../../src.dev-1/gdb/ser-event.c:212:16: runtime error: member access within null pointer of type 'struct serial' Something goes wrong when we try to query the user. Note, I configured GDB with --enable-ubsan, I suspect that without this the above "error" would actually just be a crash. The backtrace from ser-event.c:212 looks like this: (gdb) bt 10 #0 serial_event_clear (event=0x675c020) at ../../src/gdb/ser-event.c:212 #1 0x0000000000769456 in invoke_async_signal_handlers () at ../../src/gdb/async-event.c:211 #2 0x000000000295049b in gdb_do_one_event () at ../../src/gdbsupport/event-loop.cc:194 #3 0x0000000001f015f8 in gdb_readline_wrapper ( prompt=0x67135c0 "../../src/gdb/i386-tdep.c:8455: internal-error: i386_gdbarch_init: Assertion `false' failed.\nA problem internal to GDB has been detected,\nfurther debugging may prove unreliable.\nQuit this debugg"...) at ../../src/gdb/top.c:1141 #4 0x0000000002118b64 in defaulted_query(const char *, char, typedef __va_list_tag __va_list_tag *) ( ctlstr=0x2e4eb68 "%s\nQuit this debugging session? ", defchar=0 '\000', args=0x7fffffffa6e0) at ../../src/gdb/utils.c:934 #5 0x0000000002118f72 in query (ctlstr=0x2e4eb68 "%s\nQuit this debugging session? ") at ../../src/gdb/utils.c:1026 #6 0x00000000021170f6 in internal_vproblem(internal_problem *, const char *, int, const char *, typedef __va_list_tag __va_list_tag *) (problem=0x6107bc0 , file=0x2b976c8 "../../src/gdb/i386-tdep.c", line=8455, fmt=0x2b96d7f "%s: Assertion `%s' failed.", ap=0x7fffffffa8e8) at ../../src/gdb/utils.c:417 #7 0x00000000021175a0 in internal_verror (file=0x2b976c8 "../../src/gdb/i386-tdep.c", line=8455, fmt=0x2b96d7f "%s: Assertion `%s' failed.", ap=0x7fffffffa8e8) at ../../src/gdb/utils.c:485 #8 0x00000000029503b3 in internal_error (file=0x2b976c8 "../../src/gdb/i386-tdep.c", line=8455, fmt=0x2b96d7f "%s: Assertion `%s' failed.") at ../../src/gdbsupport/errors.cc:55 #9 0x000000000122d5b6 in i386_gdbarch_init (info=..., arches=0x0) at ../../src/gdb/i386-tdep.c:8455 (More stack frames follow...) It turns out that the problem is that the async event handler mechanism has been invoked, but this has not yet been initialized. If we look at gdb_init (in gdb/top.c) we can indeed see the call to gdb_init_signals is after the call to initialize_current_architecture. If I reorder the calls, moving gdb_init_signals earlier, then the initial error is resolved, however, things are still broken. I now see the same "Quit this debugging session? (y or n)" prompt, but when I provide an answer and press return GDB immediately crashes. So what's going on now? The next problem is that the call_readline field within the current_ui structure is not initialized, and this callback is invoked to process the reply I entered. The problem is that call_readline is setup as a result of calling set_top_level_interpreter, which is called from captured_main_1. Unfortunately, set_top_level_interpreter is called after gdb_init is called. I wondered how to solve this problem for a while, however, I don't know if there's an easy "just reorder some lines" solution here. Looking through captured_main_1 there seems to be a bunch of dependencies between printing various things, parsing config files, and setting up the interpreter. I'm sure there is a solution hiding in there somewhere.... I'm just not sure I want to spend any longer looking for it. So. I propose a simpler solution, more of a hack/work-around. In utils.c we already have a function filtered_printing_initialized, this is checked in a few places within internal_vproblem. In some of these cases the call gates whether or not GDB will query the user. My proposal is to add a new readline_initialized function, which checks if the current_ui has had readline initialized yet. If this is not the case then we should not attempt to query the user. After this change GDB prints the error message, the backtrace, and then aborts (including dumping core). This actually seems pretty sane as, if GDB has not yet made it through the initialization then it doesn't make much sense to allow the user to say "no, I don't want to quit the debug session" (I think). --- gdb/utils.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/gdb/utils.c b/gdb/utils.c index 9ca268ad07f..375614d685d 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -306,6 +306,16 @@ struct internal_problem bool should_print_backtrace; }; +/* Return true if the readline callbacks have been initialized for UI. + This is always true once GDB is fully initialized, but during the early + startup phase this is initially false. */ + +static bool +readline_initialized (struct ui *ui) +{ + return ui->call_readline != nullptr; +} + /* Report a problem, internal to GDB, to the user. Once the problem has been reported, and assuming GDB didn't quit, the caller can either allow execution to resume or throw an error. */ @@ -378,6 +388,7 @@ internal_vproblem (struct internal_problem *problem, if (problem->should_quit != internal_problem_ask || !confirm || !filtered_printing_initialized () + || !readline_initialized (current_ui) || problem->should_print_backtrace) gdb_printf (gdb_stderr, "%s\n", reason.c_str ()); @@ -389,7 +400,8 @@ internal_vproblem (struct internal_problem *problem, /* Default (yes/batch case) is to quit GDB. When in batch mode this lessens the likelihood of GDB going into an infinite loop. */ - if (!confirm || !filtered_printing_initialized ()) + if (!confirm || !filtered_printing_initialized () + || !readline_initialized (current_ui)) quit_p = 1; else quit_p = query (_("%s\nQuit this debugging session? "), @@ -412,7 +424,8 @@ internal_vproblem (struct internal_problem *problem, { if (!can_dump_core_warn (LIMIT_MAX, reason.c_str ())) dump_core_p = 0; - else if (!filtered_printing_initialized ()) + else if (!filtered_printing_initialized () + || !readline_initialized (current_ui)) dump_core_p = 1; else { -- 2.25.4