From patchwork Tue Mar 29 15:49:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 1610713 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=TZVdfCxQ; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org (client-ip=112.213.38.117; helo=lists.ozlabs.org; envelope-from=pdbg-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org; receiver=) Received: from lists.ozlabs.org (lists.ozlabs.org [112.213.38.117]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KSYtx09P5z9sFk for ; Wed, 30 Mar 2022 02:50:49 +1100 (AEDT) Received: from boromir.ozlabs.org (localhost [IPv6:::1]) by lists.ozlabs.org (Postfix) with ESMTP id 4KSYtw684Sz2xYG for ; Wed, 30 Mar 2022 02:50:48 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=TZVdfCxQ; dkim-atps=neutral X-Original-To: pdbg@lists.ozlabs.org Delivered-To: pdbg@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::52b; helo=mail-pg1-x52b.google.com; envelope-from=npiggin@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=TZVdfCxQ; dkim-atps=neutral Received: from mail-pg1-x52b.google.com (mail-pg1-x52b.google.com [IPv6:2607:f8b0:4864:20::52b]) (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 lists.ozlabs.org (Postfix) with ESMTPS id 4KSYtt20z7z2xtQ for ; Wed, 30 Mar 2022 02:50:46 +1100 (AEDT) Received: by mail-pg1-x52b.google.com with SMTP id s72so15178325pgc.5 for ; Tue, 29 Mar 2022 08:50:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=WkQDCZr0hQ7FvYlKGJb/dzUOSXDXmSxeADLgh10rnFg=; b=TZVdfCxQB9wPDDVUBN0btwsRZxBgif6LL56MvcnpvjWWA7EHwHsWsrC/LSvtv4Pb0Q uyU4Y+mnz4a3A5ugKycUYxVTYjQxatBPcOkT5H6RfjRISM8C9cvoeGm+WrZB6/hCk6i8 CLEuDgY0t5V4vIDMoPBrHev0rr6emWK4S9NeJ394azToob2VYfVVW7wBxOzsfl2f+aLH qsdVvikY55VJcHyE5vYLlgDo/kI090svgbrV4zT6uRtD7rgu7OxVoMVEiiEnbb5A+QfH VDsyedJ0Yn77qJJC73jVNrLn8xmcfDRdCYY64Osvi6Kj1pOIe/46YaSOp3GSeZFcn1pB wlvw== 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=WkQDCZr0hQ7FvYlKGJb/dzUOSXDXmSxeADLgh10rnFg=; b=0ytPtNOTtGAllfM2V274wVNWo4ezbwDH0UKoaFn6pWmVP3FDopjZp0uV8C9HSE0/BD s6k23P8BXBwION1X02dxTws6MZnhFcHRbnzmUsMKoOj/MyVeWd44wL7pccDgTjY/c5mH DoyWLfucj2NZfDHEL/HPeW+20H9vs8/pqU/8a+447dfAdiUyNdKa7H8Jxr0vO0NO1UKC KamWwoZTc+Isc3VGCK34RFiCQdMVKRDqnzP1yvvRExHRFHA0dgLjZ5yTrfbXyd0xzN5e 7KpTSq+K438To7WNAqnlwzTGmZZ3Rg/V/Cvjku/E01OCC/zZQ6gCp9Xbaq7aSe9z/brJ 99DQ== X-Gm-Message-State: AOAM531xF0FBcCTs0QdoFgvZ/y2SiBnCruPfmNQTPN7v2cToobuoyhMa DdqhGrixqdN7LlI3wMado4mMaqdbdU4= X-Google-Smtp-Source: ABdhPJxOj1im9mwz0ih0zdJZ5UMrK0Kok89hlQpnzyThUytUOoP/e8FTG673KdjiZcRqRXyFR77peg== X-Received: by 2002:a63:3d4b:0:b0:386:322:ff8c with SMTP id k72-20020a633d4b000000b003860322ff8cmr2460503pga.385.1648569044253; Tue, 29 Mar 2022 08:50:44 -0700 (PDT) Received: from bobo.ibm.com (58-6-255-110.tpgi.com.au. [58.6.255.110]) by smtp.gmail.com with ESMTPSA id s35-20020a056a001c6300b004fb20b5d6c1sm14163564pfw.40.2022.03.29.08.50.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Mar 2022 08:50:44 -0700 (PDT) From: Nicholas Piggin To: pdbg@lists.ozlabs.org Date: Wed, 30 Mar 2022 01:49:24 +1000 Message-Id: <20220329154931.493851-32-npiggin@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20220329154931.493851-1-npiggin@gmail.com> References: <20220329154931.493851-1-npiggin@gmail.com> MIME-Version: 1.0 Subject: [Pdbg] [PATCH v2 31/38] gdbserver: track stop reason per thread X-BeenThere: pdbg@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "mailing list for https://github.com/open-power/pdbg development" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Nicholas Piggin Errors-To: pdbg-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Pdbg" Maintain the reason why each thread has stopped, which allows in particular distinguishing between threads that encountered a trap, one that took an interrupt, from those that were stopped afterwards due to all-stop semantics. This allows sending TRAP/INT/other stop reasons as appropriate rather than always sending TRAP. While here, switch to the more capable T packet rather than S packet, which can includes the thread-id. Switch target to the thread that hit a breakpoint when stopping. Signed-off-by: Nicholas Piggin --- src/pdbgproxy.c | 85 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 79 insertions(+), 6 deletions(-) diff --git a/src/pdbgproxy.c b/src/pdbgproxy.c index db80b6a..fca728f 100644 --- a/src/pdbgproxy.c +++ b/src/pdbgproxy.c @@ -30,7 +30,16 @@ #ifndef DISABLE_GDBSERVER -/* Maximum packet size */ +/* + * If the client sents qSupported then it can handle unlimited length response. + * Shouldn't need more than 8k for now. If we had to handle old clients, 512 + * should be a lower limit. + */ +#define MAX_RESP_LEN 8192 + +/* + * Maximum packet size. We don't advertise this to the client (TODO). + */ #define BUFFER_SIZE 8192 /* GDB packets */ @@ -38,7 +47,6 @@ #define ACK "+" #define NACK "-" #define OK "OK" -#define TRAP "S05" #define ERROR(e) "E"STR(e) #define TEST_SKIBOOT_ADDR 0x40000000 @@ -56,6 +64,8 @@ static enum client_state state = IDLE; struct gdb_thread { uint64_t pir; bool attn_set; + bool stop_attn; + bool stop_ctrlc; }; static void destroy_client(int dead_fd); @@ -132,9 +142,32 @@ static void set_thread(uint64_t *stack, void *priv) send_response(fd, ERROR(EEXIST)); } +static void send_stop_for_thread(struct pdbg_target *target) +{ + struct thread *thread = target_to_thread(target); + struct gdb_thread *gdb_thread = thread->gdbserver_priv; + uint64_t pir = gdb_thread->pir; + char data[MAX_RESP_LEN]; + size_t s = 0; + int sig; + + if (gdb_thread->stop_attn) + sig = 5; /* TRAP */ + else if (gdb_thread->stop_ctrlc) + sig = 2; /* INT */ + else + sig = 0; /* default / initial stop reason */ + + s += snprintf(data + s, sizeof(data) - s, "T%02uthread:%04" PRIx64 ";%s", sig, pir, sig == 5 ? "swbreak:;" : ""); + + send_response(fd, data); +} + static void stop_reason(uint64_t *stack, void *priv) { - send_response(fd, TRAP); + PR_INFO("stop_reason\n"); + + send_stop_for_thread(thread_target); } static void detach(uint64_t *stack, void *priv) @@ -539,8 +572,17 @@ out: static void v_conts(uint64_t *stack, void *priv) { + struct thread *thread = target_to_thread(thread_target); + struct gdb_thread *gdb_thread = thread->gdbserver_priv; + + PR_INFO("thread_step\n"); + thread_step(thread_target, 1); - send_response(fd, TRAP); + + gdb_thread->stop_ctrlc = false; + gdb_thread->stop_attn = false; + + send_stop_for_thread(thread_target); } static void __start_all(void) @@ -568,6 +610,8 @@ static void start_all(void) struct pdbg_target *target; for_each_path_target_class("thread", target) { + struct thread *thread = target_to_thread(target); + struct gdb_thread *gdb_thread; struct thread_state status; if (pdbg_target_status(target) != PDBG_TARGET_ENABLED) @@ -577,6 +621,11 @@ static void start_all(void) status = thread_status(target); if (!status.quiesced) PR_ERROR("starting thread not quiesced\n"); + + gdb_thread = thread->gdbserver_priv; + + gdb_thread->stop_attn = false; + gdb_thread->stop_ctrlc = false; } __start_all(); @@ -691,6 +740,8 @@ static void stop_all(void) PR_INFO("thread pir=%llx hit attn\n", gdb_thread->pir); + gdb_thread->stop_attn = true; + if (!(status.active)) PR_ERROR("Error thread inactive after trap\n"); /* Restore NIA to before break */ @@ -706,13 +757,18 @@ static void interrupt(uint64_t *stack, void *priv) { PR_INFO("Interrupt from gdb client\n"); if (state != IDLE) { + struct thread *thread = target_to_thread(thread_target); + struct gdb_thread *gdb_thread = thread->gdbserver_priv; + stop_all(); + if (!gdb_thread->stop_attn) + gdb_thread->stop_ctrlc = true; state = IDLE; poll_interval = VCONT_POLL_DELAY; } - send_response(fd, TRAP); + send_stop_for_thread(thread_target); } static bool poll_threads(void) @@ -735,6 +791,8 @@ static bool poll_threads(void) static void poll(void) { + struct pdbg_target *target; + if (state != SIGNAL_WAIT) return; @@ -745,12 +803,27 @@ static void poll(void) stop_all(); + for_each_path_target_class("thread", target) { + struct thread *thread = target_to_thread(target); + struct gdb_thread *gdb_thread; + + if (pdbg_target_status(target) != PDBG_TARGET_ENABLED) + continue; + + gdb_thread = thread->gdbserver_priv; + + if (gdb_thread->stop_attn) { + thread_target = target; + break; + } + } + set_attn(false); state = IDLE; poll_interval = VCONT_POLL_DELAY; - send_response(fd, TRAP); + send_stop_for_thread(thread_target); } static void cmd_default(uint64_t *stack, void *priv)