From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id Km/qDK/kt2d5ITgAWB0awg (envelope-from ) for ; Thu, 20 Feb 2025 21:27:59 -0500 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=BbcabhUU; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 1E8B21E105; Thu, 20 Feb 2025 21:27:59 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-6.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=4.0.0 Received: from server2.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 ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id A92451E08E for ; Thu, 20 Feb 2025 21:27:57 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5E089385841C for ; Fri, 21 Feb 2025 02:27:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5E089385841C Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=BbcabhUU Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id E15A63858404 for ; Fri, 21 Feb 2025 02:27:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E15A63858404 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org E15A63858404 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1740104822; cv=none; b=PA+AunaovwYAAUaSd7Qtwfh6yYZIgcyzJkroTO51WVblUUuIHehzAYNYzJSyrL7qmEEpv3XWvZ/IXabngicBnsEYS1QwuvhOsVvG9nmIQf0o7pstfEK3c9zzxQ4hPrPcCLsj73h/oqaDmlQNe4f/ojFKs9KPxZnMenSlZnj3Sp8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1740104822; c=relaxed/simple; bh=5VgeOci1gwL1qF5+VGp7RaMngF8ihr89TRaMI55Icd8=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=g21oHrHfjo2NGPmc16SPDM3nJKenlrWb0F6SDvvAnuqZGf1DIi1YKJdcbks8BYdaxKbH01BU0XtePGHDV6npZw+tMKGGFbT8WtnveOS5iBmf34uLrAEA7K8qWF/34c2Q3SJaJlTgS5WfBzvul2W4YOInpAb3mNl0HwfS9vi1IU4= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E15A63858404 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1740104821; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=5iyqy4b/8Vkj/G4iF+9wdyg8YbyvycQ4ZSYlIAzM+s4=; b=BbcabhUUX+pKG/cc3nW/LRSQGI2DgCRxmd4vNjBInqFKqNInlDxeXid6hcZ59tl8y1Qdtj TKQqrstJ7w38I3fu5LIs4KdVlmoFOqMyYGKRJ2qs3ZFYC8+/YHI3rv/htSy24Lvj4lhY18 iuIwRoGV01h1a8XtzNvw9u93BFhq6wc= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-52-Rk1Wk6DuNfinAZKjnt9obQ-1; Thu, 20 Feb 2025 21:27:00 -0500 X-MC-Unique: Rk1Wk6DuNfinAZKjnt9obQ-1 X-Mimecast-MFC-AGG-ID: Rk1Wk6DuNfinAZKjnt9obQ_1740104819 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 50C361800373 for ; Fri, 21 Feb 2025 02:26:59 +0000 (UTC) Received: from f41-1.lan (unknown [10.22.81.226]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 3E4B119560A3; Fri, 21 Feb 2025 02:26:58 +0000 (UTC) From: Kevin Buettner To: gdb-patches@sourceware.org Cc: Kevin Buettner Subject: [PATCH] Use ui_out for "info checkpoints" Date: Thu, 20 Feb 2025 19:25:16 -0700 Message-ID: <20250221022515.1861799-2-kevinb@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: jwOoBx8PVlj91gkBpoTYCCWqPi8gWIBJxny_PkztHRI_1740104819 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org In his review of my recent checkpoint work (commit e5501dd4321), Andrew Burgess suggested that I use GDB's structured table generation mechanism for the "info checkpoints" command. This patch does that. Andrew also recommended using print_stack_frame() for the "Frame" column. I tried this, but ran into some problems, which are described in a comment in the code. I got it to mostly work, except for the case when the current/active fork is running. Switching context away from and then back to a running fork doesn't work. It could, perhaps, be made to work, but I'm not convinced that the checkpoint facility is important enough to expend the effort for this case. So, instead, I simply adapted the existing checkpoint frame printing code to use the ui_out machinery instead of gdb_printf. --- gdb/linux-fork.c | 125 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 92 insertions(+), 33 deletions(-) diff --git a/gdb/linux-fork.c b/gdb/linux-fork.c index f31c777edff..52fd7d9ab8f 100644 --- a/gdb/linux-fork.c +++ b/gdb/linux-fork.c @@ -30,6 +30,7 @@ #include "gdbthread.h" #include "source.h" #include "progspace-and-thread.h" +#include "cli/cli-style.h" #include "nat/gdb_ptrace.h" #include "gdbsupport/gdb_wait.h" @@ -759,20 +760,14 @@ Please switch to another checkpoint before detaching the current one")); delete_fork (ptid, current_inferior ()); } -/* Print information about currently known checkpoints. */ +/* Helper for info_checkpoints_command. */ static void -info_checkpoints_command (const char *arg, int from_tty) +print_checkpoints (struct ui_out *uiout, inferior *req_inf, fork_info *req_fi) { - struct gdbarch *gdbarch = get_current_arch (); struct inferior *cur_inf = current_inferior (); - inferior *req_inf = nullptr; - fork_info *req_fi = nullptr; bool will_print_something = false; - if (arg && *arg) - std::tie (req_fi, req_inf) = parse_checkpoint_id (arg); - /* Figure out whether to print the inferior number in the checkpoint list. */ bool print_inf = (number_of_inferiors () > 1); @@ -821,18 +816,21 @@ info_checkpoints_command (const char *arg, int from_tty) if (!print_inf && num_width < 2) num_width = 2; - /* Print column headers... */ - gdb_printf (" "); - gdb_printf ("%-*s", (print_inf ? (int) inf_width : 0) - + (int) num_width + 1, "Id"); - gdb_printf ("Active "); - gdb_printf ("%-*s", (int) targid_width + 1, "Target Id"); - gdb_printf ("Frame\n"); + ui_out_emit_table table_emitter (uiout, 5, -1, "checkpoints"); + + /* Define the columns / headers... */ + uiout->table_header (1, ui_left, "current", ""); + uiout->table_header ((print_inf ? (int) inf_width : 0) + (int) num_width, + ui_right, "id", "Id"); + uiout->table_header (6, ui_left, "active", "Active"); + uiout->table_header (targid_width, ui_left, "target-id", "Target Id"); + uiout->table_header (1, ui_left, "frame", "Frame"); + uiout->table_body (); - /* Print each checkpoint padded, as needed, with spaces so that everything - lines up. */ for (inferior *inf : all_inferiors (linux_target)) { + /* If asked to print a partciular inferior, skip all of + those which don't match. */ if (req_inf != nullptr && req_inf != inf) continue; @@ -841,59 +839,120 @@ info_checkpoints_command (const char *arg, int from_tty) for (const fork_info &fi : fork_list (inf)) { + /* If asked to print a particular checkpoint, skip all + which don't match. */ if (req_fi != nullptr && req_fi != &fi) continue; thread_info *t = any_thread_of_inferior (inf); bool is_current = fi.ptid.pid () == inf->pid; + + ui_out_emit_tuple tuple_emitter (uiout, nullptr); + if (is_current && cur_inf == inf) - gdb_printf ("* "); + uiout->field_string ("current", "*"); else - gdb_printf (" "); + uiout->field_skip ("current"); if (print_inf) - gdb_printf ("%*d.%-*d", (int) inf_width, inf->num, - (int) num_width, fi.num); + uiout->field_fmt ("id", "%d.%d", inf->num, fi.num); else - gdb_printf ("%*d ", (int) num_width, fi.num); + uiout->field_fmt ("id", "%d", fi.num); /* Print out 'y' or 'n' for whether the checkpoint is current. */ - gdb_printf ("%-7s", is_current ? "y" : "n"); + uiout->field_string ("active", is_current ? "y" : "n"); /* Print target id. */ - gdb_printf ("%-*s", (int) targid_width, - target_pid_to_str (proc_ptid (fi.ptid)).c_str ()); + uiout->field_string + ("target-id", target_pid_to_str (proc_ptid (fi.ptid)).c_str ()); if (t->state == THREAD_RUNNING && is_current) - gdb_printf (_(" (running)")); + uiout->text ("(running)"); else { - gdb_printf (_(" at ")); + /* Print frame info for the checkpoint under + consideration. + + Ideally, we'd call print_stack_frame() here in order + to have consistency (with regard to how frames are + printed) with other parts of GDB as well as to reduce + the amount of code required here. + + However, we can't simply print the frame without + switching checkpoint contexts. To do that, we could + first call scoped_switch_fork_info() - that mostly + works - except when the active fork/checkpoint is + running, i.e. when t->state == THREAD_RUNNING. + Switching context away from a running fork has certain + problems associated with it. Certainly, the + fork_info struct would need some new fields, but + work would also need to be done to do something + reasonable should the state of the running fork + have changed when switching back to it. + + Note: If scoped_switch_fork_info() is someday + changed to allow switching from a running + fork/checkpoint, then it might also be possible to + allow a restart from a running checkpoint to some + other checkpoint. */ + + ui_out_emit_tuple frame_tuple_emitter (uiout, "frame"); + uiout->text ("at "); + ULONGEST pc = (is_current ? regcache_read_pc (get_thread_regcache (t)) : fi.pc); - gdb_puts (paddress (gdbarch, pc)); + uiout->field_core_addr ("addr", get_current_arch (), pc); symtab_and_line sal = find_pc_line (pc, 0); if (sal.symtab) - gdb_printf (_(", file %s"), - symtab_to_filename_for_display (sal.symtab)); + { + uiout->text (", file "); + uiout->field_string ("file", + symtab_to_filename_for_display (sal.symtab), + file_name_style.style ()); + } if (sal.line) - gdb_printf (_(", line %d"), sal.line); + { + uiout->text (", line "); + uiout->field_signed ("line", sal.line, + line_number_style.style ()); + } if (!sal.symtab && !sal.line) { bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (pc); if (msym.minsym) - gdb_printf (", <%s>", msym.minsym->linkage_name ()); + { + uiout->text (", <"); + uiout->field_string ("linkage-name", + msym.minsym->linkage_name (), + function_name_style.style ()); + uiout->text (">"); + } } } - gdb_putc ('\n'); + uiout->text ("\n"); } } } +/* Print information about currently known checkpoints. */ + +static void +info_checkpoints_command (const char *arg, int from_tty) +{ + inferior *req_inf = nullptr; + fork_info *req_fi = nullptr; + + if (arg && *arg) + std::tie (req_fi, req_inf) = parse_checkpoint_id (arg); + + print_checkpoints (current_uiout, req_inf, req_fi); + +} + /* The PID of the process we're checkpointing. */ static int checkpointing_pid = 0; -- 2.48.0